From 8fb4efae6f5fabbe889bebbda60e9f7dce930f1f Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Thu, 9 Jun 2011 22:04:24 +0200 Subject: build-sys: use top-level directory for libblkid rather than shlibs/blkid Signed-off-by: Karel Zak --- Makefile.am | 2 +- config/include-Makefile.am | 6 +- configure.ac | 20 +- libblkid/.gitignore | 5 + libblkid/COPYING.libblkid | 510 +++++++++ libblkid/Makefile.am | 16 + libblkid/README.blkid | 78 ++ libblkid/blkid.pc.in | 11 + libblkid/docs/.gitignore | 17 + libblkid/docs/Makefile.am | 101 ++ libblkid/docs/libblkid-config.xml | 57 + libblkid/docs/libblkid-docs.xml | 69 ++ libblkid/docs/libblkid-sections.txt | 145 +++ libblkid/docs/libblkid.types | 0 libblkid/docs/version.xml.in | 1 + libblkid/libblkid.3 | 110 ++ libblkid/samples/.gitignore | 4 + libblkid/samples/Makefile.am | 7 + libblkid/samples/mkfs.c | 78 ++ libblkid/samples/partitions.c | 95 ++ libblkid/samples/superblocks.c | 67 ++ libblkid/samples/topology.c | 86 ++ libblkid/src/Makefile.am | 72 ++ libblkid/src/blkid.h.in | 336 ++++++ libblkid/src/blkid.sym | 141 +++ libblkid/src/blkidP.h | 466 ++++++++ libblkid/src/cache.c | 264 +++++ libblkid/src/config.c | 201 ++++ libblkid/src/dev.c | 272 +++++ libblkid/src/devname.c | 680 +++++++++++ libblkid/src/devno.c | 527 +++++++++ libblkid/src/encode.c | 338 ++++++ libblkid/src/evaluate.c | 315 ++++++ libblkid/src/getsize.c | 34 + libblkid/src/llseek.c | 142 +++ libblkid/src/partitions/Makefile.am | 22 + libblkid/src/partitions/aix.c | 58 + libblkid/src/partitions/aix.h | 7 + libblkid/src/partitions/blkid_parttypes.h | 121 ++ libblkid/src/partitions/bsd.c | 243 ++++ libblkid/src/partitions/dos.c | 287 +++++ libblkid/src/partitions/dos.h | 36 + libblkid/src/partitions/gpt.c | 401 +++++++ libblkid/src/partitions/mac.c | 181 +++ libblkid/src/partitions/minix.c | 103 ++ libblkid/src/partitions/partitions.c | 1336 ++++++++++++++++++++++ libblkid/src/partitions/partitions.h | 62 + libblkid/src/partitions/sgi.c | 158 +++ libblkid/src/partitions/solaris_x86.c | 150 +++ libblkid/src/partitions/sun.c | 187 +++ libblkid/src/partitions/ultrix.c | 88 ++ libblkid/src/partitions/unixware.c | 193 ++++ libblkid/src/probe.c | 1509 +++++++++++++++++++++++++ libblkid/src/read.c | 498 ++++++++ libblkid/src/resolve.c | 139 +++ libblkid/src/save.c | 196 ++++ libblkid/src/superblocks/Makefile.am | 51 + libblkid/src/superblocks/adaptec_raid.c | 113 ++ libblkid/src/superblocks/befs.c | 470 ++++++++ libblkid/src/superblocks/bfs.c | 23 + libblkid/src/superblocks/btrfs.c | 93 ++ libblkid/src/superblocks/cramfs.c | 62 + libblkid/src/superblocks/ddf_raid.c | 138 +++ libblkid/src/superblocks/drbd.c | 114 ++ libblkid/src/superblocks/exfat.c | 146 +++ libblkid/src/superblocks/ext.c | 526 +++++++++ libblkid/src/superblocks/gfs.c | 131 +++ libblkid/src/superblocks/hfs.c | 321 ++++++ libblkid/src/superblocks/highpoint_raid.c | 85 ++ libblkid/src/superblocks/hpfs.c | 122 ++ libblkid/src/superblocks/iso9660.c | 153 +++ libblkid/src/superblocks/isw_raid.c | 64 ++ libblkid/src/superblocks/jfs.c | 71 ++ libblkid/src/superblocks/jmicron_raid.c | 63 ++ libblkid/src/superblocks/linux_raid.c | 257 +++++ libblkid/src/superblocks/lsi_raid.c | 59 + libblkid/src/superblocks/luks.c | 66 ++ libblkid/src/superblocks/lvm.c | 182 +++ libblkid/src/superblocks/minix.c | 125 ++ libblkid/src/superblocks/netware.c | 97 ++ libblkid/src/superblocks/nilfs.c | 120 ++ libblkid/src/superblocks/ntfs.c | 172 +++ libblkid/src/superblocks/nvidia_raid.c | 63 ++ libblkid/src/superblocks/ocfs.c | 213 ++++ libblkid/src/superblocks/promise_raid.c | 70 ++ libblkid/src/superblocks/reiserfs.c | 128 +++ libblkid/src/superblocks/romfs.c | 51 + libblkid/src/superblocks/silicon_raid.c | 84 ++ libblkid/src/superblocks/squashfs.c | 68 ++ libblkid/src/superblocks/superblocks.c | 754 ++++++++++++ libblkid/src/superblocks/superblocks.h | 92 ++ libblkid/src/superblocks/swap.c | 171 +++ libblkid/src/superblocks/sysv.c | 153 +++ libblkid/src/superblocks/ubifs.c | 121 ++ libblkid/src/superblocks/udf.c | 168 +++ libblkid/src/superblocks/ufs.c | 238 ++++ libblkid/src/superblocks/vfat.c | 427 +++++++ libblkid/src/superblocks/via_raid.c | 88 ++ libblkid/src/superblocks/vmfs.c | 101 ++ libblkid/src/superblocks/vxfs.c | 41 + libblkid/src/superblocks/xfs.c | 63 ++ libblkid/src/superblocks/zfs.c | 222 ++++ libblkid/src/tag.c | 474 ++++++++ libblkid/src/topology/Makefile.am | 17 + libblkid/src/topology/dm.c | 137 +++ libblkid/src/topology/evms.c | 76 ++ libblkid/src/topology/ioctl.c | 73 ++ libblkid/src/topology/lvm.c | 148 +++ libblkid/src/topology/md.c | 151 +++ libblkid/src/topology/sysfs.c | 116 ++ libblkid/src/topology/topology.c | 369 ++++++ libblkid/src/topology/topology.h | 24 + libblkid/src/tst_types.c | 63 ++ libblkid/src/verify.c | 231 ++++ libblkid/src/version.c | 62 + shlibs/blkid/.gitignore | 5 - shlibs/blkid/COPYING.libblkid | 510 --------- shlibs/blkid/Makefile.am | 16 - shlibs/blkid/README.blkid | 78 -- shlibs/blkid/blkid.pc.in | 11 - shlibs/blkid/docs/.gitignore | 17 - shlibs/blkid/docs/Makefile.am | 101 -- shlibs/blkid/docs/libblkid-config.xml | 57 - shlibs/blkid/docs/libblkid-docs.xml | 69 -- shlibs/blkid/docs/libblkid-sections.txt | 145 --- shlibs/blkid/docs/libblkid.types | 0 shlibs/blkid/docs/version.xml.in | 1 - shlibs/blkid/libblkid.3 | 110 -- shlibs/blkid/samples/.gitignore | 4 - shlibs/blkid/samples/Makefile.am | 7 - shlibs/blkid/samples/mkfs.c | 78 -- shlibs/blkid/samples/partitions.c | 95 -- shlibs/blkid/samples/superblocks.c | 67 -- shlibs/blkid/samples/topology.c | 86 -- shlibs/blkid/src/Makefile.am | 72 -- shlibs/blkid/src/blkid.h.in | 336 ------ shlibs/blkid/src/blkid.sym | 141 --- shlibs/blkid/src/blkidP.h | 466 -------- shlibs/blkid/src/cache.c | 264 ----- shlibs/blkid/src/config.c | 201 ---- shlibs/blkid/src/dev.c | 272 ----- shlibs/blkid/src/devname.c | 680 ----------- shlibs/blkid/src/devno.c | 527 --------- shlibs/blkid/src/encode.c | 338 ------ shlibs/blkid/src/evaluate.c | 315 ------ shlibs/blkid/src/getsize.c | 34 - shlibs/blkid/src/llseek.c | 142 --- shlibs/blkid/src/partitions/Makefile.am | 22 - shlibs/blkid/src/partitions/aix.c | 58 - shlibs/blkid/src/partitions/aix.h | 7 - shlibs/blkid/src/partitions/blkid_parttypes.h | 121 -- shlibs/blkid/src/partitions/bsd.c | 243 ---- shlibs/blkid/src/partitions/dos.c | 287 ----- shlibs/blkid/src/partitions/dos.h | 36 - shlibs/blkid/src/partitions/gpt.c | 401 ------- shlibs/blkid/src/partitions/mac.c | 181 --- shlibs/blkid/src/partitions/minix.c | 103 -- shlibs/blkid/src/partitions/partitions.c | 1336 ---------------------- shlibs/blkid/src/partitions/partitions.h | 62 - shlibs/blkid/src/partitions/sgi.c | 158 --- shlibs/blkid/src/partitions/solaris_x86.c | 150 --- shlibs/blkid/src/partitions/sun.c | 187 --- shlibs/blkid/src/partitions/ultrix.c | 88 -- shlibs/blkid/src/partitions/unixware.c | 193 ---- shlibs/blkid/src/probe.c | 1509 ------------------------- shlibs/blkid/src/read.c | 498 -------- shlibs/blkid/src/resolve.c | 139 --- shlibs/blkid/src/save.c | 196 ---- shlibs/blkid/src/superblocks/Makefile.am | 51 - shlibs/blkid/src/superblocks/adaptec_raid.c | 113 -- shlibs/blkid/src/superblocks/befs.c | 470 -------- shlibs/blkid/src/superblocks/bfs.c | 23 - shlibs/blkid/src/superblocks/btrfs.c | 93 -- shlibs/blkid/src/superblocks/cramfs.c | 62 - shlibs/blkid/src/superblocks/ddf_raid.c | 138 --- shlibs/blkid/src/superblocks/drbd.c | 114 -- shlibs/blkid/src/superblocks/exfat.c | 146 --- shlibs/blkid/src/superblocks/ext.c | 526 --------- shlibs/blkid/src/superblocks/gfs.c | 131 --- shlibs/blkid/src/superblocks/hfs.c | 321 ------ shlibs/blkid/src/superblocks/highpoint_raid.c | 85 -- shlibs/blkid/src/superblocks/hpfs.c | 122 -- shlibs/blkid/src/superblocks/iso9660.c | 153 --- shlibs/blkid/src/superblocks/isw_raid.c | 64 -- shlibs/blkid/src/superblocks/jfs.c | 71 -- shlibs/blkid/src/superblocks/jmicron_raid.c | 63 -- shlibs/blkid/src/superblocks/linux_raid.c | 257 ----- shlibs/blkid/src/superblocks/lsi_raid.c | 59 - shlibs/blkid/src/superblocks/luks.c | 66 -- shlibs/blkid/src/superblocks/lvm.c | 182 --- shlibs/blkid/src/superblocks/minix.c | 125 -- shlibs/blkid/src/superblocks/netware.c | 97 -- shlibs/blkid/src/superblocks/nilfs.c | 120 -- shlibs/blkid/src/superblocks/ntfs.c | 172 --- shlibs/blkid/src/superblocks/nvidia_raid.c | 63 -- shlibs/blkid/src/superblocks/ocfs.c | 213 ---- shlibs/blkid/src/superblocks/promise_raid.c | 70 -- shlibs/blkid/src/superblocks/reiserfs.c | 128 --- shlibs/blkid/src/superblocks/romfs.c | 51 - shlibs/blkid/src/superblocks/silicon_raid.c | 84 -- shlibs/blkid/src/superblocks/squashfs.c | 68 -- shlibs/blkid/src/superblocks/superblocks.c | 754 ------------ shlibs/blkid/src/superblocks/superblocks.h | 92 -- shlibs/blkid/src/superblocks/swap.c | 171 --- shlibs/blkid/src/superblocks/sysv.c | 153 --- shlibs/blkid/src/superblocks/ubifs.c | 121 -- shlibs/blkid/src/superblocks/udf.c | 168 --- shlibs/blkid/src/superblocks/ufs.c | 238 ---- shlibs/blkid/src/superblocks/vfat.c | 427 ------- shlibs/blkid/src/superblocks/via_raid.c | 88 -- shlibs/blkid/src/superblocks/vmfs.c | 101 -- shlibs/blkid/src/superblocks/vxfs.c | 41 - shlibs/blkid/src/superblocks/xfs.c | 63 -- shlibs/blkid/src/superblocks/zfs.c | 222 ---- shlibs/blkid/src/tag.c | 474 -------- shlibs/blkid/src/topology/Makefile.am | 17 - shlibs/blkid/src/topology/dm.c | 137 --- shlibs/blkid/src/topology/evms.c | 76 -- shlibs/blkid/src/topology/ioctl.c | 73 -- shlibs/blkid/src/topology/lvm.c | 148 --- shlibs/blkid/src/topology/md.c | 151 --- shlibs/blkid/src/topology/sysfs.c | 116 -- shlibs/blkid/src/topology/topology.c | 369 ------ shlibs/blkid/src/topology/topology.h | 24 - shlibs/blkid/src/tst_types.c | 63 -- shlibs/blkid/src/verify.c | 231 ---- shlibs/blkid/src/version.c | 62 - tests/commands.sh.in | 4 +- 228 files changed, 20317 insertions(+), 20317 deletions(-) create mode 100644 libblkid/.gitignore create mode 100644 libblkid/COPYING.libblkid create mode 100644 libblkid/Makefile.am create mode 100644 libblkid/README.blkid create mode 100644 libblkid/blkid.pc.in create mode 100644 libblkid/docs/.gitignore create mode 100644 libblkid/docs/Makefile.am create mode 100644 libblkid/docs/libblkid-config.xml create mode 100644 libblkid/docs/libblkid-docs.xml create mode 100644 libblkid/docs/libblkid-sections.txt create mode 100644 libblkid/docs/libblkid.types create mode 100644 libblkid/docs/version.xml.in create mode 100644 libblkid/libblkid.3 create mode 100644 libblkid/samples/.gitignore create mode 100644 libblkid/samples/Makefile.am create mode 100644 libblkid/samples/mkfs.c create mode 100644 libblkid/samples/partitions.c create mode 100644 libblkid/samples/superblocks.c create mode 100644 libblkid/samples/topology.c create mode 100644 libblkid/src/Makefile.am create mode 100644 libblkid/src/blkid.h.in create mode 100644 libblkid/src/blkid.sym create mode 100644 libblkid/src/blkidP.h create mode 100644 libblkid/src/cache.c create mode 100644 libblkid/src/config.c create mode 100644 libblkid/src/dev.c create mode 100644 libblkid/src/devname.c create mode 100644 libblkid/src/devno.c create mode 100644 libblkid/src/encode.c create mode 100644 libblkid/src/evaluate.c create mode 100644 libblkid/src/getsize.c create mode 100644 libblkid/src/llseek.c create mode 100644 libblkid/src/partitions/Makefile.am create mode 100644 libblkid/src/partitions/aix.c create mode 100644 libblkid/src/partitions/aix.h create mode 100644 libblkid/src/partitions/blkid_parttypes.h create mode 100644 libblkid/src/partitions/bsd.c create mode 100644 libblkid/src/partitions/dos.c create mode 100644 libblkid/src/partitions/dos.h create mode 100644 libblkid/src/partitions/gpt.c create mode 100644 libblkid/src/partitions/mac.c create mode 100644 libblkid/src/partitions/minix.c create mode 100644 libblkid/src/partitions/partitions.c create mode 100644 libblkid/src/partitions/partitions.h create mode 100644 libblkid/src/partitions/sgi.c create mode 100644 libblkid/src/partitions/solaris_x86.c create mode 100644 libblkid/src/partitions/sun.c create mode 100644 libblkid/src/partitions/ultrix.c create mode 100644 libblkid/src/partitions/unixware.c create mode 100644 libblkid/src/probe.c create mode 100644 libblkid/src/read.c create mode 100644 libblkid/src/resolve.c create mode 100644 libblkid/src/save.c create mode 100644 libblkid/src/superblocks/Makefile.am create mode 100644 libblkid/src/superblocks/adaptec_raid.c create mode 100644 libblkid/src/superblocks/befs.c create mode 100644 libblkid/src/superblocks/bfs.c create mode 100644 libblkid/src/superblocks/btrfs.c create mode 100644 libblkid/src/superblocks/cramfs.c create mode 100644 libblkid/src/superblocks/ddf_raid.c create mode 100644 libblkid/src/superblocks/drbd.c create mode 100644 libblkid/src/superblocks/exfat.c create mode 100644 libblkid/src/superblocks/ext.c create mode 100644 libblkid/src/superblocks/gfs.c create mode 100644 libblkid/src/superblocks/hfs.c create mode 100644 libblkid/src/superblocks/highpoint_raid.c create mode 100644 libblkid/src/superblocks/hpfs.c create mode 100644 libblkid/src/superblocks/iso9660.c create mode 100644 libblkid/src/superblocks/isw_raid.c create mode 100644 libblkid/src/superblocks/jfs.c create mode 100644 libblkid/src/superblocks/jmicron_raid.c create mode 100644 libblkid/src/superblocks/linux_raid.c create mode 100644 libblkid/src/superblocks/lsi_raid.c create mode 100644 libblkid/src/superblocks/luks.c create mode 100644 libblkid/src/superblocks/lvm.c create mode 100644 libblkid/src/superblocks/minix.c create mode 100644 libblkid/src/superblocks/netware.c create mode 100644 libblkid/src/superblocks/nilfs.c create mode 100644 libblkid/src/superblocks/ntfs.c create mode 100644 libblkid/src/superblocks/nvidia_raid.c create mode 100644 libblkid/src/superblocks/ocfs.c create mode 100644 libblkid/src/superblocks/promise_raid.c create mode 100644 libblkid/src/superblocks/reiserfs.c create mode 100644 libblkid/src/superblocks/romfs.c create mode 100644 libblkid/src/superblocks/silicon_raid.c create mode 100644 libblkid/src/superblocks/squashfs.c create mode 100644 libblkid/src/superblocks/superblocks.c create mode 100644 libblkid/src/superblocks/superblocks.h create mode 100644 libblkid/src/superblocks/swap.c create mode 100644 libblkid/src/superblocks/sysv.c create mode 100644 libblkid/src/superblocks/ubifs.c create mode 100644 libblkid/src/superblocks/udf.c create mode 100644 libblkid/src/superblocks/ufs.c create mode 100644 libblkid/src/superblocks/vfat.c create mode 100644 libblkid/src/superblocks/via_raid.c create mode 100644 libblkid/src/superblocks/vmfs.c create mode 100644 libblkid/src/superblocks/vxfs.c create mode 100644 libblkid/src/superblocks/xfs.c create mode 100644 libblkid/src/superblocks/zfs.c create mode 100644 libblkid/src/tag.c create mode 100644 libblkid/src/topology/Makefile.am create mode 100644 libblkid/src/topology/dm.c create mode 100644 libblkid/src/topology/evms.c create mode 100644 libblkid/src/topology/ioctl.c create mode 100644 libblkid/src/topology/lvm.c create mode 100644 libblkid/src/topology/md.c create mode 100644 libblkid/src/topology/sysfs.c create mode 100644 libblkid/src/topology/topology.c create mode 100644 libblkid/src/topology/topology.h create mode 100644 libblkid/src/tst_types.c create mode 100644 libblkid/src/verify.c create mode 100644 libblkid/src/version.c delete mode 100644 shlibs/blkid/.gitignore delete mode 100644 shlibs/blkid/COPYING.libblkid delete mode 100644 shlibs/blkid/Makefile.am delete mode 100644 shlibs/blkid/README.blkid delete mode 100644 shlibs/blkid/blkid.pc.in delete mode 100644 shlibs/blkid/docs/.gitignore delete mode 100644 shlibs/blkid/docs/Makefile.am delete mode 100644 shlibs/blkid/docs/libblkid-config.xml delete mode 100644 shlibs/blkid/docs/libblkid-docs.xml delete mode 100644 shlibs/blkid/docs/libblkid-sections.txt delete mode 100644 shlibs/blkid/docs/libblkid.types delete mode 100644 shlibs/blkid/docs/version.xml.in delete mode 100644 shlibs/blkid/libblkid.3 delete mode 100644 shlibs/blkid/samples/.gitignore delete mode 100644 shlibs/blkid/samples/Makefile.am delete mode 100644 shlibs/blkid/samples/mkfs.c delete mode 100644 shlibs/blkid/samples/partitions.c delete mode 100644 shlibs/blkid/samples/superblocks.c delete mode 100644 shlibs/blkid/samples/topology.c delete mode 100644 shlibs/blkid/src/Makefile.am delete mode 100644 shlibs/blkid/src/blkid.h.in delete mode 100644 shlibs/blkid/src/blkid.sym delete mode 100644 shlibs/blkid/src/blkidP.h delete mode 100644 shlibs/blkid/src/cache.c delete mode 100644 shlibs/blkid/src/config.c delete mode 100644 shlibs/blkid/src/dev.c delete mode 100644 shlibs/blkid/src/devname.c delete mode 100644 shlibs/blkid/src/devno.c delete mode 100644 shlibs/blkid/src/encode.c delete mode 100644 shlibs/blkid/src/evaluate.c delete mode 100644 shlibs/blkid/src/getsize.c delete mode 100644 shlibs/blkid/src/llseek.c delete mode 100644 shlibs/blkid/src/partitions/Makefile.am delete mode 100644 shlibs/blkid/src/partitions/aix.c delete mode 100644 shlibs/blkid/src/partitions/aix.h delete mode 100644 shlibs/blkid/src/partitions/blkid_parttypes.h delete mode 100644 shlibs/blkid/src/partitions/bsd.c delete mode 100644 shlibs/blkid/src/partitions/dos.c delete mode 100644 shlibs/blkid/src/partitions/dos.h delete mode 100644 shlibs/blkid/src/partitions/gpt.c delete mode 100644 shlibs/blkid/src/partitions/mac.c delete mode 100644 shlibs/blkid/src/partitions/minix.c delete mode 100644 shlibs/blkid/src/partitions/partitions.c delete mode 100644 shlibs/blkid/src/partitions/partitions.h delete mode 100644 shlibs/blkid/src/partitions/sgi.c delete mode 100644 shlibs/blkid/src/partitions/solaris_x86.c delete mode 100644 shlibs/blkid/src/partitions/sun.c delete mode 100644 shlibs/blkid/src/partitions/ultrix.c delete mode 100644 shlibs/blkid/src/partitions/unixware.c delete mode 100644 shlibs/blkid/src/probe.c delete mode 100644 shlibs/blkid/src/read.c delete mode 100644 shlibs/blkid/src/resolve.c delete mode 100644 shlibs/blkid/src/save.c delete mode 100644 shlibs/blkid/src/superblocks/Makefile.am delete mode 100644 shlibs/blkid/src/superblocks/adaptec_raid.c delete mode 100644 shlibs/blkid/src/superblocks/befs.c delete mode 100644 shlibs/blkid/src/superblocks/bfs.c delete mode 100644 shlibs/blkid/src/superblocks/btrfs.c delete mode 100644 shlibs/blkid/src/superblocks/cramfs.c delete mode 100644 shlibs/blkid/src/superblocks/ddf_raid.c delete mode 100644 shlibs/blkid/src/superblocks/drbd.c delete mode 100644 shlibs/blkid/src/superblocks/exfat.c delete mode 100644 shlibs/blkid/src/superblocks/ext.c delete mode 100644 shlibs/blkid/src/superblocks/gfs.c delete mode 100644 shlibs/blkid/src/superblocks/hfs.c delete mode 100644 shlibs/blkid/src/superblocks/highpoint_raid.c delete mode 100644 shlibs/blkid/src/superblocks/hpfs.c delete mode 100644 shlibs/blkid/src/superblocks/iso9660.c delete mode 100644 shlibs/blkid/src/superblocks/isw_raid.c delete mode 100644 shlibs/blkid/src/superblocks/jfs.c delete mode 100644 shlibs/blkid/src/superblocks/jmicron_raid.c delete mode 100644 shlibs/blkid/src/superblocks/linux_raid.c delete mode 100644 shlibs/blkid/src/superblocks/lsi_raid.c delete mode 100644 shlibs/blkid/src/superblocks/luks.c delete mode 100644 shlibs/blkid/src/superblocks/lvm.c delete mode 100644 shlibs/blkid/src/superblocks/minix.c delete mode 100644 shlibs/blkid/src/superblocks/netware.c delete mode 100644 shlibs/blkid/src/superblocks/nilfs.c delete mode 100644 shlibs/blkid/src/superblocks/ntfs.c delete mode 100644 shlibs/blkid/src/superblocks/nvidia_raid.c delete mode 100644 shlibs/blkid/src/superblocks/ocfs.c delete mode 100644 shlibs/blkid/src/superblocks/promise_raid.c delete mode 100644 shlibs/blkid/src/superblocks/reiserfs.c delete mode 100644 shlibs/blkid/src/superblocks/romfs.c delete mode 100644 shlibs/blkid/src/superblocks/silicon_raid.c delete mode 100644 shlibs/blkid/src/superblocks/squashfs.c delete mode 100644 shlibs/blkid/src/superblocks/superblocks.c delete mode 100644 shlibs/blkid/src/superblocks/superblocks.h delete mode 100644 shlibs/blkid/src/superblocks/swap.c delete mode 100644 shlibs/blkid/src/superblocks/sysv.c delete mode 100644 shlibs/blkid/src/superblocks/ubifs.c delete mode 100644 shlibs/blkid/src/superblocks/udf.c delete mode 100644 shlibs/blkid/src/superblocks/ufs.c delete mode 100644 shlibs/blkid/src/superblocks/vfat.c delete mode 100644 shlibs/blkid/src/superblocks/via_raid.c delete mode 100644 shlibs/blkid/src/superblocks/vmfs.c delete mode 100644 shlibs/blkid/src/superblocks/vxfs.c delete mode 100644 shlibs/blkid/src/superblocks/xfs.c delete mode 100644 shlibs/blkid/src/superblocks/zfs.c delete mode 100644 shlibs/blkid/src/tag.c delete mode 100644 shlibs/blkid/src/topology/Makefile.am delete mode 100644 shlibs/blkid/src/topology/dm.c delete mode 100644 shlibs/blkid/src/topology/evms.c delete mode 100644 shlibs/blkid/src/topology/ioctl.c delete mode 100644 shlibs/blkid/src/topology/lvm.c delete mode 100644 shlibs/blkid/src/topology/md.c delete mode 100644 shlibs/blkid/src/topology/sysfs.c delete mode 100644 shlibs/blkid/src/topology/topology.c delete mode 100644 shlibs/blkid/src/topology/topology.h delete mode 100644 shlibs/blkid/src/tst_types.c delete mode 100644 shlibs/blkid/src/verify.c delete mode 100644 shlibs/blkid/src/version.c diff --git a/Makefile.am b/Makefile.am index b116483c..01a28bb7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -7,7 +7,7 @@ SHLIBS_DIRS += libuuid endif if BUILD_LIBBLKID -SHLIBS_DIRS += shlibs/blkid +SHLIBS_DIRS += libblkid endif if BUILD_LIBMOUNT diff --git a/config/include-Makefile.am b/config/include-Makefile.am index 49e45ccc..8c41ad19 100644 --- a/config/include-Makefile.am +++ b/config/include-Makefile.am @@ -12,9 +12,9 @@ dist_noinst_DATA = $(dist_man_MANS) # Paths to in-tree libraries (use ul_ prefix to avoid possible collisions) # # blkid -ul_libblkid_srcdir = $(top_srcdir)/shlibs/blkid/src -ul_libblkid_builddir = $(top_builddir)/shlibs/blkid/src -ul_libblkid_la = $(top_builddir)/shlibs/blkid/src/libblkid.la +ul_libblkid_srcdir = $(top_srcdir)/libblkid/src +ul_libblkid_builddir = $(top_builddir)/libblkid/src +ul_libblkid_la = $(top_builddir)/libblkid/src/libblkid.la # blkid.h is generated by ./configure script and stored in build directory ul_libblkid_incdir = $(ul_libblkid_builddir) diff --git a/configure.ac b/configure.ac index 984b41bb..3524623e 100644 --- a/configure.ac +++ b/configure.ac @@ -1225,16 +1225,16 @@ mount/Makefile partx/Makefile po/Makefile.in schedutils/Makefile -shlibs/blkid/blkid.pc -shlibs/blkid/Makefile -shlibs/blkid/docs/Makefile -shlibs/blkid/docs/version.xml -shlibs/blkid/src/Makefile -shlibs/blkid/src/blkid.h -shlibs/blkid/src/superblocks/Makefile -shlibs/blkid/src/topology/Makefile -shlibs/blkid/src/partitions/Makefile -shlibs/blkid/samples/Makefile +libblkid/blkid.pc +libblkid/Makefile +libblkid/docs/Makefile +libblkid/docs/version.xml +libblkid/src/Makefile +libblkid/src/blkid.h +libblkid/src/superblocks/Makefile +libblkid/src/topology/Makefile +libblkid/src/partitions/Makefile +libblkid/samples/Makefile libmount/mount.pc libmount/Makefile libmount/src/Makefile diff --git a/libblkid/.gitignore b/libblkid/.gitignore new file mode 100644 index 00000000..6ffe4a9e --- /dev/null +++ b/libblkid/.gitignore @@ -0,0 +1,5 @@ +*.sh +bin/blkid +bin/findfs +test_* +blkid.h diff --git a/libblkid/COPYING.libblkid b/libblkid/COPYING.libblkid new file mode 100644 index 00000000..cf9b6b99 --- /dev/null +++ b/libblkid/COPYING.libblkid @@ -0,0 +1,510 @@ + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations +below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. +^L + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it +becomes a de-facto standard. To achieve this, non-free programs must +be allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. +^L + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control +compilation and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. +^L + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. +^L + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at least + three years, to give the same user the materials specified in + Subsection 6a, above, for a charge no more than the cost of + performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. +^L + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. +^L + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply, and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License +may add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. +^L + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS +^L + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms +of the ordinary General Public License). + + To apply these terms, attach the following notices to the library. +It is safest to attach them to the start of each source file to most +effectively convey the exclusion of warranty; and each file should +have at least the "copyright" line and a pointer to where the full +notice is found. + + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or +your school, if any, to sign a "copyright disclaimer" for the library, +if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James + Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/libblkid/Makefile.am b/libblkid/Makefile.am new file mode 100644 index 00000000..59362cfe --- /dev/null +++ b/libblkid/Makefile.am @@ -0,0 +1,16 @@ +include $(top_srcdir)/config/include-Makefile.am + +SUBDIRS = src samples + +if ENABLE_GTK_DOC +SUBDIRS += docs +endif + +# pkg-config stuff +pkgconfigdir = $(usrlib_execdir)/pkgconfig +pkgconfig_DATA = blkid.pc + +dist_man_MANS = libblkid.3 + +EXTRA_DIST = COPYING.libblkid README.blkid blkid.pc.in libblkid.3 + diff --git a/libblkid/README.blkid b/libblkid/README.blkid new file mode 100644 index 00000000..4fa9be1f --- /dev/null +++ b/libblkid/README.blkid @@ -0,0 +1,78 @@ +libblkid - a library to handle device identification and token extraction + +Basic usage is as follows - there are two normal usage patterns: + +For cases where a program wants information about multiple devices, or +expects to be doing multiple token searches, the program should +directly initialize cache file via (second parameter is cache +filename, NULL = default): + + blkid_cache cache = NULL; + if (blkid_get_cache(&cache, NULL) < 0) + /* error reading the cache file, not really fatal */ + +Note that if no cache file exists, an empty cache struct is still +allocated. Usage of libblkid functions will use the cache to avoid +needless device scans. + +The model of the blkid cache is that each device has a number of +attributes that can be associated with it. Currently the attributes +which are supported (and set) by blkid are: + + TYPE filesystem type + UUID filesystem uuid + LABEL filesystem label + + +How to use libblkid? Normally, you either want to find a device with +a specific NAME=value token, or you want to output token(s) from a +device. To find a device that matches a following attribute, you +simply call the blkid_get_devname() function: + + if ((devname = blkid_get_devname(cache, attribute_name, value))) { + /* do something with devname */ + string_free(devname); + } + +The cache parameter is optional; if it is NULL, then the blkid library +will load the default blkid.tab cache file, and then release the cache +before function call returns. The return value is an allocated string +which holds the resulting device name (if it is found). If the value +is NULL, then attribute_name is parsed as if it were +"="; if it cannot be so parsed, then the +original attribute_name is returned in a copied allocated string. +This is a convenience to allow user programs to want to translate user +input, whether it is of the form: "/dev/hda1", "LABEL=root", +"UUID=082D-26E3", and get back a device name that it can use. + +Alternatively, of course, the programmer can pass an attribute name of +"LABEL", and value of "root", if that is more convenient. + +Another common usage is to retrieve the value of a specific attribute +for a particular device. This can be used to determine the filesystem +type, or label, or uuid for a particular device: + + if ((value = blkid_get_tag_value(cache, attribute_name, devname))) { + /* do something with value */ + string_free(value); + } + +If a program needs to call multiple blkid functions, then passing in a +cache value of NULL is not recommended, since the /etc/blkid.tab file +will be repeatedly parsed over and over again, with memory allocated +and deallocated. To initialize the blkid cache, blkid_get_cache() +function is used: + + if (blkid_get_cache(&cache, NULL) < 0) + goto errout; + +The second parameter of blkid_get_cache (if non-zero) is the alternate +filename of the blkid cache file (where the default is +/etc/blkid.tab). Normally, programs should just pass in NULL. + +If you have called blkid_get_cache(), you should call blkid_put_cache() +when you are done using the blkid library functions. This will save the +cache to the blkid.tab file, if you have write access to the file. It +will also free all associated devices and tags: + + blkid_put_cache(cache); diff --git a/libblkid/blkid.pc.in b/libblkid/blkid.pc.in new file mode 100644 index 00000000..40ec8a9d --- /dev/null +++ b/libblkid/blkid.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@usrlib_execdir@ +includedir=@includedir@ + +Name: blkid +Description: Block device id library +Version: @LIBBLKID_VERSION@ +Requires.private: uuid +Cflags: -I${includedir}/blkid +Libs: -L${libdir} -lblkid diff --git a/libblkid/docs/.gitignore b/libblkid/docs/.gitignore new file mode 100644 index 00000000..917c8481 --- /dev/null +++ b/libblkid/docs/.gitignore @@ -0,0 +1,17 @@ +*.args +*.bak +*-decl-list.txt +*-decl.txt +*.hierarchy +html/* +*.interfaces +*-overrides.txt +*.prerequisites +*.signals +*.stamp +tmpl/* +*-undeclared.txt +*-undocumented.txt +*-unused.txt +version.xml +xml/* diff --git a/libblkid/docs/Makefile.am b/libblkid/docs/Makefile.am new file mode 100644 index 00000000..8ef3b239 --- /dev/null +++ b/libblkid/docs/Makefile.am @@ -0,0 +1,101 @@ +include $(top_srcdir)/config/include-Makefile.am + +## Process this file with automake to produce Makefile.in + +# We require automake 1.10 at least. +AUTOMAKE_OPTIONS = 1.10 + +# This is a blank Makefile.am for using gtk-doc. +# Copy this to your project's API docs directory and modify the variables to +# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples +# of using the various options. + +# The name of the module, e.g. 'glib'. +DOC_MODULE=libblkid + +# Uncomment for versioned docs and specify the version of the module, e.g. '2'. +#DOC_MODULE_VERSION=2 + +# The top-level SGML file. You can change this if you want to. +DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml + +# The directory containing the source code. Relative to $(srcdir). +# gtk-doc will search all .c & .h files beneath here for inline comments +# documenting the functions and macros. +# e.g. DOC_SOURCE_DIR=../../../gtk +DOC_SOURCE_DIR=../src + +# Extra options to pass to gtkdoc-scangobj. Not normally needed. +SCANGOBJ_OPTIONS= + +# Extra options to supply to gtkdoc-scan. +# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" +SCAN_OPTIONS= + +# Extra options to supply to gtkdoc-mkdb. +# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml +MKDB_OPTIONS=--sgml-mode --output-format=xml --name-space blkid + +# Extra options to supply to gtkdoc-mktmpl +# e.g. MKTMPL_OPTIONS=--only-section-tmpl +MKTMPL_OPTIONS= + +# Extra options to supply to gtkdoc-mkhtml +MKHTML_OPTIONS= + +# Extra options to supply to gtkdoc-fixref. Not normally needed. +# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html +FIXXREF_OPTIONS= + +# Used for dependencies. The docs will be rebuilt if any of these change. +# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h +# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c +HFILE_GLOB=$(ul_libblkid_incdir)/blkid.h +CFILE_GLOB=$(ul_libblkid_srcdir)/*.c + +# Extra header to include when scanning, which are not under DOC_SOURCE_DIR +# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h +EXTRA_HFILES= + +# Header files to ignore when scanning. Use base file name, no paths +# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h +IGNORE_HFILES=blkidP.h list.h partitions.h superblocks.h topology.h aix.h dos.h + +# Images to copy into HTML directory. +# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png +HTML_IMAGES= + +# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). +# e.g. content_files=running.sgml building.sgml changes-2.0.sgml +content_files = $(builddir)/version.xml $(srcdir)/libblkid-config.xml + +# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded +# These files must be listed here *and* in content_files +# e.g. expand_content_files=running.sgml +expand_content_files= + +# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. +# Only needed if you are using gtkdoc-scangobj to dynamically query widget +# signals and properties. +# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) +# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) +GTKDOC_CFLAGS= +GTKDOC_LIBS= + +# This includes the standard gtk-doc make rules, copied by gtkdocize. +include $(top_srcdir)/config/gtk-doc.make + +# Other files to distribute +# e.g. EXTRA_DIST += version.xml.in +EXTRA_DIST += version.xml.in + +# Files not to distribute +# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types +# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt +#DISTCLEANFILES += + +# Comment this out if you want your docs-status tested during 'make check' +if ENABLE_GTK_DOC +#TESTS_ENVIRONMENT = cd $(srcsrc) +#TESTS = $(GTKDOC_CHECK) +endif diff --git a/libblkid/docs/libblkid-config.xml b/libblkid/docs/libblkid-config.xml new file mode 100644 index 00000000..89fbb7f1 --- /dev/null +++ b/libblkid/docs/libblkid-config.xml @@ -0,0 +1,57 @@ + + +]> + + +Config file +3 +LIBBLKID Library + + + +Config file +config file to control paths and basic library behavior + + + +Description + +The standard location of the +/etc/blkid.conf config file can be overridden by the environment variable +BLKID_CONF. The following options control the libblkid library: + + + + + SEND_UEVENT=yes|not + + Sends uevent when /dev/disk/by-{label,uuid}/ + symlink does not match with LABEL or UUID on the device. Default is "yes". + + + + CACHE_FILE=path + + Overrides the standard location of the cache file. This + setting can be overridden by the environment variable BLKID_FILE. Default is + /etc/blkid.tab. + + + + EVALUATE=method + + Defines LABEL and UUID evaluation method(s). Currently, + the libblkid library supports "udev" and "scan" methods. More than one methods + may be specified in a comma separated list. Default is "udev,scan". The "udev" + method uses udev /dev/disk/by-* symlinks and the "scan" method scans all + block devices from the /proc/partitions file. + + + + + + + diff --git a/libblkid/docs/libblkid-docs.xml b/libblkid/docs/libblkid-docs.xml new file mode 100644 index 00000000..c99192a9 --- /dev/null +++ b/libblkid/docs/libblkid-docs.xml @@ -0,0 +1,69 @@ + + +]> + + + libblkid Reference Manual + for libblkid version &version; + + 2009 + Karel Zak <kzak@redhat.com> + + + + + libblkid Overview + + +The libblkid library is used to identify block devices (disks) as to their +content (e.g. filesystem type, partitions) as well as extracting additional +information such as filesystem labels/volume names, partitions, unique +identifiers/serial numbers, etc. A common use is to allow use of LABEL= and +UUID= tags instead of hard-coding specific block device names into +configuration files. + + +The libblkid librray +was written by Andreas Dilger for the ext2 filesystem utilties, with input +from Ted Ts'o. The library was subsequently heavily modified by Ted Ts'o. + + +The low-level probing code, topology and partitions support was written +by Karel Zak. Currently, the library is mainatned by Karel Zak. + + +The library is part of the util-linux package since version 2.15 and is +available from ftp://ftp.kernel.org/pub/linux/utils/util-linux/. + + + + + + + High-level + + + + + + Low-level + + + + + + + + Common utils + + + + + + API Index + + + diff --git a/libblkid/docs/libblkid-sections.txt b/libblkid/docs/libblkid-sections.txt new file mode 100644 index 00000000..47675f4a --- /dev/null +++ b/libblkid/docs/libblkid-sections.txt @@ -0,0 +1,145 @@ +
+evaluate +blkid_evaluate_tag +
+ +
+cache +blkid_cache +blkid_gc_cache +blkid_get_cache +blkid_put_cache +blkid_probe_all +blkid_probe_all_new +blkid_verify +
+ +
+search +blkid_dev +blkid_dev_devname +blkid_dev_has_tag +blkid_dev_iterate +blkid_dev_iterate_begin +blkid_dev_iterate_end +blkid_dev_next +blkid_dev_set_search +blkid_find_dev_with_tag +blkid_get_dev +blkid_get_devname +blkid_get_tag_value +blkid_tag_iterate +blkid_tag_iterate_begin +blkid_tag_iterate_end +blkid_tag_next +
+ +
+lowprobe +blkid_probe +blkid_free_probe +blkid_new_probe +blkid_new_probe_from_filename +blkid_probe_get_devno +blkid_probe_get_sectorsize +blkid_probe_get_sectors +blkid_probe_get_size +blkid_probe_set_device +blkid_reset_probe +
+ +
+lowprobe-tags +blkid_do_fullprobe +blkid_do_probe +blkid_do_safeprobe + +blkid_probe_get_value +blkid_probe_has_value +blkid_probe_lookup_value +blkid_probe_numof_values +
+ +
+partitions +blkid_partlist +blkid_partition +blkid_parttable +blkid_probe_enable_partitions +blkid_probe_set_partitions_flags + +blkid_known_pttype + +blkid_partition_get_name +blkid_partition_get_partno +blkid_partition_get_size +blkid_partition_get_start +blkid_partition_get_table +blkid_partition_get_type +blkid_partition_get_type_string +blkid_partition_get_uuid +blkid_partition_is_extended +blkid_partition_is_logical +blkid_partition_is_primary + +blkid_partlist_get_partition +blkid_partlist_numof_partitions + +blkid_parttable_get_offset +blkid_parttable_get_parent +blkid_parttable_get_type + +blkid_probe_get_partitions +
+ +
+superblocks +blkid_probe_enable_superblocks + +blkid_known_fstype + +blkid_probe_filter_superblocks_type +blkid_probe_filter_superblocks_usage +blkid_probe_invert_superblocks_filter +blkid_probe_reset_superblocks_filter +blkid_probe_set_superblocks_flags + +blkid_probe_reset_filter +blkid_probe_filter_types +blkid_probe_filter_usage +blkid_probe_invert_filter +blkid_probe_set_request +
+ +
+topology +blkid_topology +blkid_probe_enable_topology + +blkid_probe_get_topology +blkid_topology_get_alignment_offset +blkid_topology_get_logical_sector_size +blkid_topology_get_minimum_io_size +blkid_topology_get_optimal_io_size +blkid_topology_get_physical_sector_size +
+ +
+encode +blkid_encode_string +blkid_safe_string +
+ +
+misc +blkid_loff_t +blkid_devno_to_devname +blkid_devno_to_wholedisk +blkid_get_dev_size +blkid_get_library_version +blkid_parse_tag_string +blkid_parse_version_string +blkid_send_uevent +
+ + diff --git a/libblkid/docs/libblkid.types b/libblkid/docs/libblkid.types new file mode 100644 index 00000000..e69de29b diff --git a/libblkid/docs/version.xml.in b/libblkid/docs/version.xml.in new file mode 100644 index 00000000..d78bda93 --- /dev/null +++ b/libblkid/docs/version.xml.in @@ -0,0 +1 @@ +@VERSION@ diff --git a/libblkid/libblkid.3 b/libblkid/libblkid.3 new file mode 100644 index 00000000..15412a51 --- /dev/null +++ b/libblkid/libblkid.3 @@ -0,0 +1,110 @@ +.\" Copyright 2001 Andreas Dilger (adilger@turbolinux.com) +.\" +.\" This man page was created for libblkid.so.1.0 from e2fsprogs-1.24. +.\" +.\" This file may be copied under the terms of the GNU Public License. +.\" +.\" Created Wed Sep 14 12:02:12 2001, Andreas Dilger +.TH LIBBLKID 3 "May 2009" "util-linux" +.SH NAME +libblkid \- block device identification library +.SH SYNOPSIS +.B #include +.sp +.B cc +.I file.c +.B \-lblkid +.SH DESCRIPTION +The +.B libblkid +library is used to identify block devices (disks) as to their content (e.g. +filesystem type) as well as extracting additional information such as +filesystem labels/volume names, unique identifiers/serial numbers, etc. +A common use is to allow use of LABEL= and UUID= tags instead of hard-coding +specific block device names into configuration files. +.P +Block device information is normally kept in a cache file +.I /etc/blkid.tab +and is verified to still be valid before being returned to the user +(if the user has read permission on the raw block device, otherwise not). +The cache file also allows unprivileged users (normally anyone other +than root, or those not in the "disk" group) to locate devices by label/id. +The standard location of the cache file can be overridden by the +environment variable BLKID_FILE. +.P +In situations where one is getting information about a single known device, +it does not impact performance whether the cache is used or not (unless you +are not able to read the block device directly). If you are dealing with +multiple devices, use of the cache is highly recommended (even if empty) as +devices will be scanned at most one time and the on-disk cache will be +updated if possible. There is rarely a reason not to use the cache. +.P +In some cases (modular kernels), block devices are not even visible until +after they are accessed the first time, so it is critical that there is +some way to locate these devices without enumerating only visible devices, +so the use of the cache file is +.B required +in this situation. +.SH CONFIGURATION FILE +The standard location of the +.I /etc/blkid.conf +config file can be overridden by the environment variable BLKID_CONF. +The following options control the libblkid library: +.TP +.I SEND_UEVENT= +Sends uevent when +.I /dev/disk/by-{label,uuid}/ +symlink does not match with LABEL or UUID on the device. Default is "yes". +.TP +.I CACHE_FILE= +Overrides the standard location of the cache file. This setting can be +overridden by the environment variable BLKID_FILE. Default is +.I /etc/blkid.tab. +.TP +.I EVALUATE= +Defines LABEL and UUID evaluation method(s). Currently, the libblkid library +supports "udev" and "scan" methods. More than one methods may be specified in +a comma separated list. Default is "udev,scan". The "udev" method uses udev +.I /dev/disk/by-* +symlinks and the "scan" method scans all block devices from the +.I /proc/partitions +file. +.SH AUTHOR +.B libblkid +was written by Andreas Dilger for the ext2 filesystem utilties, with input +from Ted Ts'o. The library was subsequently heavily modified by Ted Ts'o. + +The low-level probing code was rewritten by Karel Zak. +.SH FILES +.TP 18 +.I /etc/blkid.tab +caches data extracted from each recognized block device +.TP +.I /etc/blkid.conf +configuration file +.SH AVAILABILITY +.B libblkid +is part of the util-linux package since version 2.15 and is available from +ftp://ftp.kernel.org/pub/linux/utils/util-linux/. +.SH COPYING +.B libblkid +is available under the terms of the GNU Library General Public License (LGPL), +version 2 (or at your discretion any later version). A copy of the LGPL +should be included with this library in the file COPYING. If not, write to +.RS +Free Software Foundation, Inc. +.br +51 Franklin St +.br +Fifth Floor +.br +Boston, MA 02110-1301 USA +.RE +.PP +or visit +.UR http://www.gnu.org/licenses/licenses.html#LGPL +http://www.gnu.org/licenses/licenses.html#LGPL +.UE +.SH "SEE ALSO" +.BR blkid (8) +.BR findfs (8) diff --git a/libblkid/samples/.gitignore b/libblkid/samples/.gitignore new file mode 100644 index 00000000..409e5cff --- /dev/null +++ b/libblkid/samples/.gitignore @@ -0,0 +1,4 @@ +topology +partitions +mkfs +superblocks diff --git a/libblkid/samples/Makefile.am b/libblkid/samples/Makefile.am new file mode 100644 index 00000000..93588d57 --- /dev/null +++ b/libblkid/samples/Makefile.am @@ -0,0 +1,7 @@ +include $(top_srcdir)/config/include-Makefile.am + +AM_CPPFLAGS += -I$(ul_libblkid_incdir) +AM_LDFLAGS += $(ul_libblkid_la) + +noinst_PROGRAMS = topology partitions mkfs superblocks + diff --git a/libblkid/samples/mkfs.c b/libblkid/samples/mkfs.c new file mode 100644 index 00000000..5c3ebe79 --- /dev/null +++ b/libblkid/samples/mkfs.c @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "c.h" + +int main(int argc, char *argv[]) +{ + int rc; + char *devname; + blkid_probe pr; + blkid_topology tp; + + if (argc < 2) { + fprintf(stderr, "usage: %s " + "-- checks based on libblkid for mkfs-like programs.\n", + program_invocation_short_name); + return EXIT_FAILURE; + } + + devname = argv[1]; + pr = blkid_new_probe_from_filename(devname); + if (!pr) + err(EXIT_FAILURE, "%s: faild to create a new libblkid probe", + devname); + + /* + * check Filesystems / Partitions overwrite + */ + + /* enable partitions probing (superblocks are enabled by default) */ + blkid_probe_enable_partitions(pr, TRUE); + + rc = blkid_do_fullprobe(pr); + if (rc == -1) + errx(EXIT_FAILURE, "%s: blkid_do_fullprobe() failed", devname); + else if (rc == 0) { + const char *type; + + if (!blkid_probe_lookup_value(pr, "TYPE", &type, NULL)) + errx(EXIT_FAILURE, "%s: appears to contain an existing " + "%s superblock", devname, type); + + if (!blkid_probe_lookup_value(pr, "PTTYPE", &type, NULL)) + errx(EXIT_FAILURE, "%s: appears to contain an partition " + "table (%s)", devname, type); + } + + /* + * get topology details + */ + tp = blkid_probe_get_topology(pr); + if (!tp) + errx(EXIT_FAILURE, "%s: failed to read topology", devname); + + + /* ... your mkfs. code or so ... + + off = blkid_topology_get_alignment_offset(tp); + + */ + + blkid_free_probe(pr); + + return EXIT_SUCCESS; +} diff --git a/libblkid/samples/partitions.c b/libblkid/samples/partitions.c new file mode 100644 index 00000000..3b527364 --- /dev/null +++ b/libblkid/samples/partitions.c @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include "c.h" + +int main(int argc, char *argv[]) +{ + int i, nparts; + char *devname; + blkid_probe pr; + blkid_partlist ls; + blkid_parttable root_tab; + + if (argc < 2) { + fprintf(stderr, "usage: %s " + "-- prints partitions\n", + program_invocation_short_name); + return EXIT_FAILURE; + } + + devname = argv[1]; + pr = blkid_new_probe_from_filename(devname); + if (!pr) + err(EXIT_FAILURE, "%s: faild to create a new libblkid probe", + devname); + /* Binary interface */ + ls = blkid_probe_get_partitions(pr); + if (!ls) + errx(EXIT_FAILURE, "%s: failed to read partitions\n", devname); + + /* + * Print info about the primary (root) partition table + */ + root_tab = blkid_partlist_get_table(ls); + if (!root_tab) + errx(EXIT_FAILURE, "%s: does not contains any " + "known partition table\n", devname); + + printf("size: %jd, sector size: %u, PT: %s, offset: %jd\n---\n", + blkid_probe_get_size(pr), + blkid_probe_get_sectorsize(pr), + blkid_parttable_get_type(root_tab), + blkid_parttable_get_offset(root_tab)); + + /* + * List partitions + */ + nparts = blkid_partlist_numof_partitions(ls); + if (!nparts) + goto done; + + for (i = 0; i < nparts; i++) { + const char *p; + blkid_partition par = blkid_partlist_get_partition(ls, i); + blkid_parttable tab = blkid_partition_get_table(par); + + printf("#%d: %10llu %10llu 0x%x", + blkid_partition_get_partno(par), + (unsigned long long) blkid_partition_get_start(par), + (unsigned long long) blkid_partition_get_size(par), + blkid_partition_get_type(par)); + + if (root_tab != tab) + /* subpartition (BSD, Minix, ...) */ + printf(" (%s)", blkid_parttable_get_type(tab)); + + p = blkid_partition_get_name(par); + if (p) + printf(" name='%s'", p); + p = blkid_partition_get_uuid(par); + if (p) + printf(" uuid='%s'", p); + p = blkid_partition_get_type_string(par); + if (p) + printf(" type='%s'", p); + + putc('\n', stdout); + } + +done: + blkid_free_probe(pr); + return EXIT_SUCCESS; +} diff --git a/libblkid/samples/superblocks.c b/libblkid/samples/superblocks.c new file mode 100644 index 00000000..20e39c97 --- /dev/null +++ b/libblkid/samples/superblocks.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "c.h" + +int main(int argc, char *argv[]) +{ + int rc; + char *devname; + blkid_probe pr; + + if (argc < 2) { + fprintf(stderr, "usage: %s " + "-- prints superblocks details about the device\n", + program_invocation_short_name); + return EXIT_FAILURE; + } + + devname = argv[1]; + pr = blkid_new_probe_from_filename(devname); + if (!pr) + err(EXIT_FAILURE, "%s: faild to create a new libblkid probe", + devname); + + /* enable topology probing */ + blkid_probe_enable_superblocks(pr, TRUE); + + /* set all flags */ + blkid_probe_set_superblocks_flags(pr, + BLKID_SUBLKS_LABEL | BLKID_SUBLKS_LABELRAW | + BLKID_SUBLKS_UUID | BLKID_SUBLKS_UUIDRAW | + BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE | + BLKID_SUBLKS_USAGE | BLKID_SUBLKS_VERSION | + BLKID_SUBLKS_MAGIC); + + rc = blkid_do_safeprobe(pr); + if (rc == -1) + errx(EXIT_FAILURE, "%s: blkid_do_safeprobe() failed", devname); + else if (rc == 1) + warnx("%s: cannot gather information about superblocks", devname); + else { + int i, nvals = blkid_probe_numof_values(pr); + + for (i = 0; i < nvals; i++) { + const char *name, *data; + + blkid_probe_get_value(pr, i, &name, &data, NULL); + printf("\t%s = %s\n", name, data); + } + } + + blkid_free_probe(pr); + return EXIT_SUCCESS; +} diff --git a/libblkid/samples/topology.c b/libblkid/samples/topology.c new file mode 100644 index 00000000..de1c3a5e --- /dev/null +++ b/libblkid/samples/topology.c @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "c.h" + +int main(int argc, char *argv[]) +{ + int rc; + char *devname; + blkid_probe pr; + blkid_topology tp; + + if (argc < 2) { + fprintf(stderr, "usage: %s " + "-- prints topology details about the device\n", + program_invocation_short_name); + return EXIT_FAILURE; + } + + devname = argv[1]; + pr = blkid_new_probe_from_filename(devname); + if (!pr) + err(EXIT_FAILURE, "%s: faild to create a new libblkid probe", + devname); + /* + * Binary interface + */ + tp = blkid_probe_get_topology(pr); + if (tp) { + printf("----- binary interface:\n"); + printf("\talignment offset : %lu\n", + blkid_topology_get_alignment_offset(tp)); + printf("\tminimum io size : %lu\n", + blkid_topology_get_minimum_io_size(tp)); + printf("\toptimal io size : %lu\n", + blkid_topology_get_optimal_io_size(tp)); + printf("\tlogical sector size : %lu\n", + blkid_topology_get_logical_sector_size(tp)); + printf("\tphysical sector size : %lu\n", + blkid_topology_get_physical_sector_size(tp)); + } + + /* + * NAME=value interface + */ + + /* enable topology probing */ + blkid_probe_enable_topology(pr, TRUE); + + /* disable superblocks probing (enabled by default) */ + blkid_probe_enable_superblocks(pr, FALSE); + + rc = blkid_do_fullprobe(pr); + if (rc == -1) + errx(EXIT_FAILURE, "%s: blkid_do_fullprobe() failed", devname); + else if (rc == 1) + warnx("%s: missing topology information", devname); + else { + int i, nvals = blkid_probe_numof_values(pr); + + printf("----- NAME=value interface (values: %d):\n", nvals); + + for (i = 0; i < nvals; i++) { + const char *name, *data; + + blkid_probe_get_value(pr, i, &name, &data, NULL); + printf("\t%s = %s\n", name, data); + } + } + + blkid_free_probe(pr); + return EXIT_SUCCESS; +} diff --git a/libblkid/src/Makefile.am b/libblkid/src/Makefile.am new file mode 100644 index 00000000..543f2f62 --- /dev/null +++ b/libblkid/src/Makefile.am @@ -0,0 +1,72 @@ +include $(top_srcdir)/config/include-Makefile.am + +SUBDIRS = superblocks topology partitions . + +common_ldadd = +common_cflags = + +if BUILD_LIBUUID +common_ldadd += $(ul_libuuid_la) +common_cflags += -I$(ul_libuuid_srcdir) +endif + +AM_CPPFLAGS += -I$(ul_libblkid_incdir) -I$(ul_libblkid_srcdir) $(common_cflags) + +# includes +blkidincdir = $(includedir)/blkid +nodist_blkidinc_HEADERS = blkid.h + +usrlib_exec_LTLIBRARIES = libblkid.la +libblkid_la_SOURCES = cache.c dev.c devname.c devno.c getsize.c llseek.c \ + probe.c read.c resolve.c save.c tag.c version.c verify.c \ + encode.c blkidP.h superblocks/superblocks.h \ + config.c evaluate.c \ + $(blkidinc_HEADERS) \ + $(top_srcdir)/lib/blkdev.c \ + $(top_srcdir)/lib/linux_version.c \ + $(top_srcdir)/lib/canonicalize.c \ + $(top_srcdir)/lib/md5.c \ + $(top_srcdir)/lib/crc32.c \ + $(top_srcdir)/include/list.h \ + $(top_srcdir)/lib/env.c \ + $(top_srcdir)/lib/strutils.c \ + $(top_srcdir)/lib/at.c \ + $(top_srcdir)/lib/sysfs.c + +nodist_libblkid_la_SOURCES = blkid.h + +libblkid_la_LIBADD = superblocks/libblkid_superblocks.la \ + topology/libblkid_topology.la \ + partitions/libblkid_partitions.la \ + $(common_ldadd) + +libblkid_la_DEPENDENCIES = $(libblkid_la_LIBADD) blkid.sym blkid.h.in + +libblkid_la_LDFLAGS = -Wl,--version-script=$(ul_libblkid_srcdir)/blkid.sym \ + -version-info $(LIBBLKID_VERSION_INFO) + +tests = test_cache test_config test_dev test_devname test_devno \ + test_read test_resolve test_save test_tag test_verify test_evaluate + +EXTRA_DIST = blkid.sym tst_types.c blkid.h.in +CLEANFILES = $(tests) + +tests: all $(tests) +test_%: %.c + $(AM_V_CC)$(COMPILE) -DTEST_PROGRAM $< .libs/libblkid.a -o $@ -luuid + + +# move lib from $(usrlib_execdir) to $(libdir) if needed +install-exec-hook: + if test "$(usrlib_execdir)" != "$(libdir)"; then \ + mkdir -p $(DESTDIR)$(libdir); \ + mv $(DESTDIR)$(usrlib_execdir)/libblkid.so.* $(DESTDIR)$(libdir); \ + so_img_name=$$(readlink $(DESTDIR)$(usrlib_execdir)/libblkid.so); \ + so_img_rel_target=$$(echo $(usrlib_execdir) | sed 's,\(^/\|\)[^/][^/]*,..,g'); \ + (cd $(DESTDIR)$(usrlib_execdir) && \ + rm -f libblkid.so && \ + $(LN_S) $$so_img_rel_target$(libdir)/$$so_img_name libblkid.so); \ + fi + +uninstall-hook: + rm -f $(DESTDIR)$(libdir)/libblkid.so* diff --git a/libblkid/src/blkid.h.in b/libblkid/src/blkid.h.in new file mode 100644 index 00000000..05527bed --- /dev/null +++ b/libblkid/src/blkid.h.in @@ -0,0 +1,336 @@ +/* + * blkid.h - Interface for libblkid, a library to identify block devices + * + * Copyright (C) 2001 Andreas Dilger + * Copyright (C) 2003 Theodore Ts'o + * Copyright (C) 2008 Karel Zak + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _BLKID_BLKID_H +#define _BLKID_BLKID_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLKID_VERSION "@LIBBLKID_VERSION@" +#define BLKID_DATE "@LIBBLKID_DATE@" + +/** + * blkid_dev: + * + * The device object keeps information about one device + */ +typedef struct blkid_struct_dev *blkid_dev; + +/** + * blkid_cache: + * + * information about all system devices + */ +typedef struct blkid_struct_cache *blkid_cache; + +/** + * blkid_probe: + * + * low-level probing setting + */ +typedef struct blkid_struct_probe *blkid_probe; + +/** + * blkid_topology: + * + * device topology information + */ +typedef struct blkid_struct_topology *blkid_topology; + +/** + * blkid_partlist + * + * list of all detected partitions and partitions tables + */ +typedef struct blkid_struct_partlist *blkid_partlist; + +/** + * blkid_partition: + * + * information about a partition + */ +typedef struct blkid_struct_partition *blkid_partition; + +/** + * blkid_parttable: + * + * information about a partition table + */ +typedef struct blkid_struct_parttable *blkid_parttable; + +/** + * blkid_loff_t: + * + * 64-bit signed number for offsets and sizes + */ +typedef int64_t blkid_loff_t; + +/** + * blkid_tag_iterate: + * + * tags iterator for high-level (blkid_cache) API + */ +typedef struct blkid_struct_tag_iterate *blkid_tag_iterate; + +/** + * blkid_dev_iterate: + * + * devices iterator for high-level (blkid_cache) API + */ +typedef struct blkid_struct_dev_iterate *blkid_dev_iterate; + +/* + * Flags for blkid_get_dev + * + * BLKID_DEV_CREATE Create an empty device structure if not found + * in the cache. + * BLKID_DEV_VERIFY Make sure the device structure corresponds + * with reality. + * BLKID_DEV_FIND Just look up a device entry, and return NULL + * if it is not found. + * BLKID_DEV_NORMAL Get a valid device structure, either from the + * cache or by probing the device. + */ +#define BLKID_DEV_FIND 0x0000 +#define BLKID_DEV_CREATE 0x0001 +#define BLKID_DEV_VERIFY 0x0002 +#define BLKID_DEV_NORMAL (BLKID_DEV_CREATE | BLKID_DEV_VERIFY) + +/* cache.c */ +extern void blkid_put_cache(blkid_cache cache); +extern int blkid_get_cache(blkid_cache *cache, const char *filename); +extern void blkid_gc_cache(blkid_cache cache); + +/* dev.c */ +extern const char *blkid_dev_devname(blkid_dev dev); + +extern blkid_dev_iterate blkid_dev_iterate_begin(blkid_cache cache); +extern int blkid_dev_set_search(blkid_dev_iterate iter, + char *search_type, char *search_value); +extern int blkid_dev_next(blkid_dev_iterate iterate, blkid_dev *dev); +extern void blkid_dev_iterate_end(blkid_dev_iterate iterate); + +/* devno.c */ +extern char *blkid_devno_to_devname(dev_t devno); +extern int blkid_devno_to_wholedisk(dev_t dev, char *diskname, + size_t len, dev_t *diskdevno); + +/* devname.c */ +extern int blkid_probe_all(blkid_cache cache); +extern int blkid_probe_all_new(blkid_cache cache); +extern int blkid_probe_all_removable(blkid_cache cache); +extern blkid_dev blkid_get_dev(blkid_cache cache, const char *devname, + int flags); + +/* getsize.c */ +extern blkid_loff_t blkid_get_dev_size(int fd); + +/* verify.c */ +extern blkid_dev blkid_verify(blkid_cache cache, blkid_dev dev); + +/* read.c */ + +/* resolve.c */ +extern char *blkid_get_tag_value(blkid_cache cache, const char *tagname, + const char *devname); +extern char *blkid_get_devname(blkid_cache cache, const char *token, + const char *value); + +/* tag.c */ +extern blkid_tag_iterate blkid_tag_iterate_begin(blkid_dev dev); +extern int blkid_tag_next(blkid_tag_iterate iterate, + const char **type, const char **value); +extern void blkid_tag_iterate_end(blkid_tag_iterate iterate); +extern int blkid_dev_has_tag(blkid_dev dev, const char *type, + const char *value); +extern blkid_dev blkid_find_dev_with_tag(blkid_cache cache, + const char *type, + const char *value); +extern int blkid_parse_tag_string(const char *token, char **ret_type, + char **ret_val); + +/* version.c */ +extern int blkid_parse_version_string(const char *ver_string); +extern int blkid_get_library_version(const char **ver_string, + const char **date_string); + +/* encode.c */ +extern int blkid_encode_string(const char *str, char *str_enc, size_t len); +extern int blkid_safe_string(const char *str, char *str_safe, size_t len); + +/* evaluate.c */ +extern int blkid_send_uevent(const char *devname, const char *action); +extern char *blkid_evaluate_tag(const char *token, const char *value, + blkid_cache *cache); +extern char *blkid_evaluate_spec(const char *spec, blkid_cache *cache); + +/* probe.c */ +extern blkid_probe blkid_new_probe(void); +extern blkid_probe blkid_new_probe_from_filename(const char *filename); +extern void blkid_free_probe(blkid_probe pr); +extern void blkid_reset_probe(blkid_probe pr); + +extern int blkid_probe_set_device(blkid_probe pr, int fd, + blkid_loff_t off, blkid_loff_t size); + +extern dev_t blkid_probe_get_devno(blkid_probe pr); +extern dev_t blkid_probe_get_wholedisk_devno(blkid_probe pr); +extern int blkid_probe_is_wholedisk(blkid_probe pr); + +extern blkid_loff_t blkid_probe_get_size(blkid_probe pr); +extern blkid_loff_t blkid_probe_get_offset(blkid_probe pr); +extern unsigned int blkid_probe_get_sectorsize(blkid_probe pr); +extern blkid_loff_t blkid_probe_get_sectors(blkid_probe pr); + +extern int blkid_probe_get_fd(blkid_probe pr); + +/* + * superblocks probing + */ +extern int blkid_known_fstype(const char *fstype); +extern int blkid_probe_enable_superblocks(blkid_probe pr, int enable); + +#define BLKID_SUBLKS_LABEL (1 << 1) /* read LABEL from superblock */ +#define BLKID_SUBLKS_LABELRAW (1 << 2) /* read and define LABEL_RAW result value*/ +#define BLKID_SUBLKS_UUID (1 << 3) /* read UUID from superblock */ +#define BLKID_SUBLKS_UUIDRAW (1 << 4) /* read and define UUID_RAW result value */ +#define BLKID_SUBLKS_TYPE (1 << 5) /* define TYPE result value */ +#define BLKID_SUBLKS_SECTYPE (1 << 6) /* define compatible fs type (second type) */ +#define BLKID_SUBLKS_USAGE (1 << 7) /* define USAGE result value */ +#define BLKID_SUBLKS_VERSION (1 << 8) /* read FS type from superblock */ +#define BLKID_SUBLKS_MAGIC (1 << 9) /* define SBMAGIC and SBMAGIC_OFFSET */ + +#define BLKID_SUBLKS_DEFAULT (BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID | \ + BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE) + +extern int blkid_probe_set_superblocks_flags(blkid_probe pr, int flags); + +extern int blkid_probe_reset_superblocks_filter(blkid_probe pr); +extern int blkid_probe_invert_superblocks_filter(blkid_probe pr); + +#define BLKID_FLTR_NOTIN 1 +#define BLKID_FLTR_ONLYIN 2 +extern int blkid_probe_filter_superblocks_type(blkid_probe pr, int flag, char *names[]); + +#define BLKID_USAGE_FILESYSTEM (1 << 1) +#define BLKID_USAGE_RAID (1 << 2) +#define BLKID_USAGE_CRYPTO (1 << 3) +#define BLKID_USAGE_OTHER (1 << 4) +extern int blkid_probe_filter_superblocks_usage(blkid_probe pr, int flag, int usage); + +/* + * topology probing + */ +extern int blkid_probe_enable_topology(blkid_probe pr, int enable); + +/* binary interface */ +extern blkid_topology blkid_probe_get_topology(blkid_probe pr); + +extern unsigned long blkid_topology_get_alignment_offset(blkid_topology tp); +extern unsigned long blkid_topology_get_minimum_io_size(blkid_topology tp); +extern unsigned long blkid_topology_get_optimal_io_size(blkid_topology tp); +extern unsigned long blkid_topology_get_logical_sector_size(blkid_topology tp); +extern unsigned long blkid_topology_get_physical_sector_size(blkid_topology tp); + +/* + * partitions probing + */ +extern int blkid_known_pttype(const char *pttype); +extern int blkid_probe_enable_partitions(blkid_probe pr, int enable); + +extern int blkid_probe_reset_partitions_filter(blkid_probe pr); +extern int blkid_probe_invert_partitions_filter(blkid_probe pr); +extern int blkid_probe_filter_partitions_type(blkid_probe pr, int flag, char *names[]); + + +/* partitions probing flags */ +#define BLKID_PARTS_FORCE_GPT (1 << 1) +#define BLKID_PARTS_ENTRY_DETAILS (1 << 2) +extern int blkid_probe_set_partitions_flags(blkid_probe pr, int flags); + +/* binary interface */ +extern blkid_partlist blkid_probe_get_partitions(blkid_probe pr); + +extern int blkid_partlist_numof_partitions(blkid_partlist ls); +extern blkid_parttable blkid_partlist_get_table(blkid_partlist ls); +extern blkid_partition blkid_partlist_get_partition(blkid_partlist ls, int n); +extern blkid_partition blkid_partlist_devno_to_partition(blkid_partlist ls, dev_t devno); + +extern blkid_parttable blkid_partition_get_table(blkid_partition par); +extern const char *blkid_partition_get_name(blkid_partition par); +extern const char *blkid_partition_get_uuid(blkid_partition par); +extern int blkid_partition_get_partno(blkid_partition par); +extern blkid_loff_t blkid_partition_get_start(blkid_partition par); +extern blkid_loff_t blkid_partition_get_size(blkid_partition par); +extern int blkid_partition_get_type(blkid_partition par); +extern const char *blkid_partition_get_type_string(blkid_partition par); +extern unsigned long long blkid_partition_get_flags(blkid_partition par); +extern int blkid_partition_is_logical(blkid_partition par); +extern int blkid_partition_is_extended(blkid_partition par); +extern int blkid_partition_is_primary(blkid_partition par); + +extern const char *blkid_parttable_get_type(blkid_parttable tab); +extern blkid_loff_t blkid_parttable_get_offset(blkid_parttable tab); +extern blkid_partition blkid_parttable_get_parent(blkid_parttable tab); + +/* + * NAME=value low-level interface + */ +extern int blkid_do_probe(blkid_probe pr); +extern int blkid_do_safeprobe(blkid_probe pr); +extern int blkid_do_fullprobe(blkid_probe pr); + +extern int blkid_probe_numof_values(blkid_probe pr); +extern int blkid_probe_get_value(blkid_probe pr, int num, const char **name, + const char **data, size_t *len); +extern int blkid_probe_lookup_value(blkid_probe pr, const char *name, + const char **data, size_t *len); +extern int blkid_probe_has_value(blkid_probe pr, const char *name); + +/*** + * Deprecated functions/macros + */ +#define BLKID_PROBREQ_LABEL BLKID_SUBLKS_LABEL +#define BLKID_PROBREQ_LABELRAW BLKID_SUBLKS_LABELRAW +#define BLKID_PROBREQ_UUID BLKID_SUBLKS_UUID +#define BLKID_PROBREQ_UUIDRAW BLKID_SUBLKS_UUIDRAW +#define BLKID_PROBREQ_TYPE BLKID_SUBLKS_TYPE +#define BLKID_PROBREQ_SECTYPE BLKID_SUBLKS_SECTYPE +#define BLKID_PROBREQ_USAGE BLKID_SUBLKS_USAGE +#define BLKID_PROBREQ_VERSION BLKID_SUBLKS_VERSION + +extern int blkid_probe_set_request(blkid_probe pr, int flags); +extern int blkid_probe_filter_usage(blkid_probe pr, int flag, int usage); +extern int blkid_probe_filter_types(blkid_probe pr, int flag, char *names[]); +extern int blkid_probe_invert_filter(blkid_probe pr); +extern int blkid_probe_reset_filter(blkid_probe pr); + +#ifdef __cplusplus +} +#endif + +#endif /* _BLKID_BLKID_H */ diff --git a/libblkid/src/blkid.sym b/libblkid/src/blkid.sym new file mode 100644 index 00000000..e758ff1a --- /dev/null +++ b/libblkid/src/blkid.sym @@ -0,0 +1,141 @@ +/* + * The symbol versioning ensures that a new application requiring symbol foo() + * can't run with old libblkid.so not providing foo() - the global SONAME + * version info can't enforce this since we never change the SONAME. + * + * The original libblkid from e2fsprogs (<=1.41.4) does not to use + * symbol versioning -- all the original symbols are in BLKID_1.0 now. + */ +BLKID_1.0 { +global: + blkid_dev_devname; + blkid_dev_has_tag; + blkid_dev_iterate_begin; + blkid_dev_iterate_end; + blkid_dev_next; + blkid_devno_to_devname; + blkid_dev_set_search; + blkid_find_dev_with_tag; + blkid_gc_cache; + blkid_get_cache; + blkid_get_dev; + blkid_get_devname; + blkid_get_dev_size; + blkid_get_library_version; + blkid_get_tag_value; + blkid_known_fstype; + blkid_parse_tag_string; + blkid_parse_version_string; + blkid_probe_all; + blkid_probe_all_new; + blkid_put_cache; + blkid_tag_iterate_begin; + blkid_tag_iterate_end; + blkid_tag_next; + blkid_verify; +local: + *; +}; + + +/* + * symbols since util-linux 2.15 + */ +BLKID_2.15 { +global: + blkid_do_probe; + blkid_do_safeprobe; + blkid_encode_string; + blkid_evaluate_tag; + blkid_free_probe; + blkid_new_probe; + blkid_probe_all; + blkid_probe_all_new; + blkid_probe_filter_types; + blkid_probe_filter_usage; + blkid_probe_get_value; + blkid_probe_has_value; + blkid_probe_invert_filter; + blkid_probe_lookup_value; + blkid_probe_numof_values; + blkid_probe_reset_filter; + blkid_probe_set_device; + blkid_probe_set_request; + blkid_reset_probe; + blkid_safe_string; + blkid_send_uevent; +} BLKID_1.0; + +/* + * symbols since util-linux 2.17 + */ +BLKID_2.17 { +global: + blkid_devno_to_wholedisk; + blkid_do_fullprobe; + blkid_known_pttype; + blkid_new_probe_from_filename; + blkid_partition_get_name; + blkid_partition_get_partno; + blkid_partition_get_size; + blkid_partition_get_start; + blkid_partition_get_table; + blkid_partition_get_type; + blkid_partition_get_type_string; + blkid_partition_get_uuid; + blkid_partition_is_extended; + blkid_partition_is_logical; + blkid_partition_is_primary; + blkid_partlist_get_partition; + blkid_partlist_numof_partitions; + blkid_parttable_get_offset; + blkid_parttable_get_parent; + blkid_parttable_get_type; + blkid_probe_enable_partitions; + blkid_probe_enable_superblocks; + blkid_probe_enable_topology; + blkid_probe_filter_partitions_type; + blkid_probe_filter_superblocks_type; + blkid_probe_filter_superblocks_usage; + blkid_probe_get_devno; + blkid_probe_get_partitions; + blkid_probe_get_sectorsize; + blkid_probe_get_sectors; + blkid_probe_get_size; + blkid_probe_get_topology; + blkid_probe_invert_partitions_filter; + blkid_probe_invert_superblocks_filter; + blkid_probe_reset_partitions_filter; + blkid_probe_reset_superblocks_filter; + blkid_probe_set_partitions_flags; + blkid_probe_set_superblocks_flags; + blkid_topology_get_alignment_offset; + blkid_topology_get_logical_sector_size; + blkid_topology_get_minimum_io_size; + blkid_topology_get_optimal_io_size; + blkid_topology_get_physical_sector_size; +} BLKID_2.15; + +/* + * symbols since util-linux 2.18 + */ +BLKID_2.18 { +global: + blkid_partition_get_flags; + blkid_partlist_devno_to_partition; + blkid_partlist_get_table; + blkid_probe_all_removable; + blkid_probe_get_fd; + blkid_probe_get_offset; + blkid_probe_get_wholedisk_devno; + blkid_probe_is_wholedisk; +} BLKID_2.17; + +/* + * symbols since util-linux 2.20 + */ +BLKID_2.20 { +global: + blkid_evaluate_spec; +} BLKID_2.18; + diff --git a/libblkid/src/blkidP.h b/libblkid/src/blkidP.h new file mode 100644 index 00000000..aeeebc16 --- /dev/null +++ b/libblkid/src/blkidP.h @@ -0,0 +1,466 @@ +/* + * blkidP.h - Internal interfaces for libblkid + * + * Copyright (C) 2001 Andreas Dilger + * Copyright (C) 2003 Theodore Ts'o + * + * %Begin-Header% + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * %End-Header% + */ + +#ifndef _BLKID_BLKIDP_H +#define _BLKID_BLKIDP_H + + +#define CONFIG_BLKID_DEBUG 1 + +#include +#include +#include +#include +#include +#include + +#include "c.h" +#include "bitops.h" /* $(top_srcdir)/include/ */ +#include "blkdev.h" + +#include "blkid.h" +#include "list.h" + +/* + * This describes the attributes of a specific device. + * We can traverse all of the tags by bid_tags (linking to the tag bit_names). + * The bid_label and bid_uuid fields are shortcuts to the LABEL and UUID tag + * values, if they exist. + */ +struct blkid_struct_dev +{ + struct list_head bid_devs; /* All devices in the cache */ + struct list_head bid_tags; /* All tags for this device */ + blkid_cache bid_cache; /* Dev belongs to this cache */ + char *bid_name; /* Device inode pathname */ + char *bid_type; /* Preferred device TYPE */ + int bid_pri; /* Device priority */ + dev_t bid_devno; /* Device major/minor number */ + time_t bid_time; /* Last update time of device */ + suseconds_t bid_utime; /* Last update time (microseconds) */ + unsigned int bid_flags; /* Device status bitflags */ + char *bid_label; /* Shortcut to device LABEL */ + char *bid_uuid; /* Shortcut to binary UUID */ +}; + +#define BLKID_BID_FL_VERIFIED 0x0001 /* Device data validated from disk */ +#define BLKID_BID_FL_INVALID 0x0004 /* Device is invalid */ +#define BLKID_BID_FL_REMOVABLE 0x0008 /* Device added by blkid_probe_all_removable() */ + +/* + * Each tag defines a NAME=value pair for a particular device. The tags + * are linked via bit_names for a single device, so that traversing the + * names list will get you a list of all tags associated with a device. + * They are also linked via bit_values for all devices, so one can easily + * search all tags with a given NAME for a specific value. + */ +struct blkid_struct_tag +{ + struct list_head bit_tags; /* All tags for this device */ + struct list_head bit_names; /* All tags with given NAME */ + char *bit_name; /* NAME of tag (shared) */ + char *bit_val; /* value of tag */ + blkid_dev bit_dev; /* pointer to device */ +}; +typedef struct blkid_struct_tag *blkid_tag; + +/* + * Chain IDs + */ +enum { + BLKID_CHAIN_SUBLKS, /* FS/RAID superblocks (enabled by default) */ + BLKID_CHAIN_TOPLGY, /* Block device topology */ + BLKID_CHAIN_PARTS, /* Partition tables */ + + BLKID_NCHAINS /* number of chains */ +}; + +struct blkid_chain { + const struct blkid_chaindrv *driver; /* chain driver */ + + int enabled; /* boolean */ + int flags; /* BLKID__* */ + int binary; /* boolean */ + int idx; /* index of the current prober */ + unsigned long *fltr; /* filter or NULL */ + void *data; /* private chain data or NULL */ +}; + +/* + * Chain driver + */ +struct blkid_chaindrv { + const int id; /* BLKID_CHAIN_* */ + const char *name; /* name of chain (for debug purpose) */ + const int dflt_flags; /* default chain flags */ + const int dflt_enabled; /* default enabled boolean */ + int has_fltr; /* boolean */ + + const struct blkid_idinfo **idinfos; /* description of probing functions */ + const size_t nidinfos; /* number of idinfos */ + + /* driver operations */ + int (*probe)(blkid_probe, struct blkid_chain *); + int (*safeprobe)(blkid_probe, struct blkid_chain *); + void (*free_data)(blkid_probe, void *); +}; + +/* + * Low-level probe result + */ +#define BLKID_PROBVAL_BUFSIZ 64 + +#define BLKID_NVALS_SUBLKS 14 +#define BLKID_NVALS_TOPLGY 5 +#define BLKID_NVALS_PARTS 13 + +/* Max number of all values in probing result */ +#define BLKID_NVALS (BLKID_NVALS_SUBLKS + \ + BLKID_NVALS_TOPLGY + \ + BLKID_NVALS_PARTS) + +struct blkid_prval +{ + const char *name; /* value name */ + unsigned char data[BLKID_PROBVAL_BUFSIZ]; /* value data */ + size_t len; /* length of value data */ + + struct blkid_chain *chain; /* owner */ +}; + +/* + * Filesystem / Raid magic strings + */ +struct blkid_idmag +{ + const char *magic; /* magic string */ + unsigned int len; /* length of magic */ + + long kboff; /* kilobyte offset of superblock */ + unsigned int sboff; /* byte offset within superblock */ +}; + +/* + * Filesystem / Raid description + */ +struct blkid_idinfo +{ + const char *name; /* fs, raid or partition table name */ + int usage; /* BLKID_USAGE_* flag */ + int flags; /* BLKID_IDINFO_* flags */ + int minsz; /* minimal device size */ + + /* probe function */ + int (*probefunc)(blkid_probe pr, const struct blkid_idmag *mag); + + struct blkid_idmag magics[]; /* NULL or array with magic strings */ +}; + +#define BLKID_NONE_MAGIC {{ NULL }} + +/* + * tolerant FS - can share the same device with more filesystems (e.g. typical + * on CD-ROMs). We need this flag to detect ambivalent results (e.g. valid fat + * and valid linux swap on the same device). + */ +#define BLKID_IDINFO_TOLERANT (1 << 1) + +struct blkid_bufinfo { + unsigned char *data; + blkid_loff_t off; + blkid_loff_t len; + struct list_head bufs; /* list of buffers */ +}; + +/* + * Low-level probing control struct + */ +struct blkid_struct_probe +{ + int fd; /* device file descriptor */ + blkid_loff_t off; /* begin of data on the device */ + blkid_loff_t size; /* end of data on the device */ + + dev_t devno; /* device number (st.st_rdev) */ + dev_t disk_devno; /* devno of the whole-disk or 0 */ + unsigned int blkssz; /* sector size (BLKSSZGET ioctl) */ + mode_t mode; /* struct stat.sb_mode */ + + int flags; /* private libray flags */ + int prob_flags; /* always zeroized by blkid_do_*() */ + + blkid_loff_t wipe_off; /* begin of the wiped area */ + blkid_loff_t wipe_size; /* size of the wiped area */ + struct blkid_chain *wipe_chain; /* superblock, partition, ... */ + + struct list_head buffers; /* list of buffers */ + + struct blkid_chain chains[BLKID_NCHAINS]; /* array of chains */ + struct blkid_chain *cur_chain; /* current chain */ + + struct blkid_prval vals[BLKID_NVALS]; /* results */ + int nvals; /* number of assigned vals */ + + struct blkid_struct_probe *parent; /* for clones */ + struct blkid_struct_probe *disk_probe; /* whole-disk probing */ +}; + +/* private flags library flags */ +#define BLKID_FL_PRIVATE_FD (1 << 1) /* see blkid_new_probe_from_filename() */ +#define BLKID_FL_TINY_DEV (1 << 2) /* <= 1.47MiB (floppy or so) */ +#define BLKID_FL_CDROM_DEV (1 << 3) /* is a CD/DVD drive */ + +/* private per-probing flags */ +#define BLKID_PROBE_FL_IGNORE_PT (1 << 1) /* ignore partition table */ + +extern blkid_probe blkid_clone_probe(blkid_probe parent); +extern blkid_probe blkid_probe_get_wholedisk_probe(blkid_probe pr); + +/* + * Evaluation methods (for blkid_eval_* API) + */ +enum { + BLKID_EVAL_UDEV = 0, + BLKID_EVAL_SCAN, + + __BLKID_EVAL_LAST +}; + +/* + * Library config options + */ +struct blkid_config { + int eval[__BLKID_EVAL_LAST]; /* array with EVALUATION= options */ + int nevals; /* number of elems in eval array */ + int uevent; /* SEND_UEVENT= option */ + char *cachefile; /* CACHE_FILE= option */ +}; + +extern struct blkid_config *blkid_read_config(const char *filename); +extern void blkid_free_config(struct blkid_config *conf); + +/* + * Minimum number of seconds between device probes, even when reading + * from the cache. This is to avoid re-probing all devices which were + * just probed by another program that does not share the cache. + */ +#define BLKID_PROBE_MIN 2 + +/* + * Time in seconds an entry remains verified in the in-memory cache + * before being reverified (in case of long-running processes that + * keep a cache in memory and continue to use it for a long time). + */ +#define BLKID_PROBE_INTERVAL 200 + +/* This describes an entire blkid cache file and probed devices. + * We can traverse all of the found devices via bic_list. + * We can traverse all of the tag types by bic_tags, which hold empty tags + * for each tag type. Those tags can be used as list_heads for iterating + * through all devices with a specific tag type (e.g. LABEL). + */ +struct blkid_struct_cache +{ + struct list_head bic_devs; /* List head of all devices */ + struct list_head bic_tags; /* List head of all tag types */ + time_t bic_time; /* Last probe time */ + time_t bic_ftime; /* Mod time of the cachefile */ + unsigned int bic_flags; /* Status flags of the cache */ + char *bic_filename; /* filename of cache */ + blkid_probe probe; /* low-level probing stuff */ +}; + +#define BLKID_BIC_FL_PROBED 0x0002 /* We probed /proc/partition devices */ +#define BLKID_BIC_FL_CHANGED 0x0004 /* Cache has changed from disk */ + +extern char *blkid_strdup(const char *s); +extern char *blkid_strndup(const char *s, const int length); +extern char *blkid_strconcat(const char *a, const char *b, const char *c); + +#define BLKID_CACHE_FILE "/etc/blkid.tab" +#define BLKID_CONFIG_FILE "/etc/blkid.conf" + +#define BLKID_ERR_IO 5 +#define BLKID_ERR_PROC 9 +#define BLKID_ERR_MEM 12 +#define BLKID_ERR_CACHE 14 +#define BLKID_ERR_DEV 19 +#define BLKID_ERR_PARAM 22 +#define BLKID_ERR_BIG 27 + +/* + * Priority settings for different types of devices + */ +#define BLKID_PRI_UBI 50 +#define BLKID_PRI_DM 40 +#define BLKID_PRI_EVMS 30 +#define BLKID_PRI_LVM 20 +#define BLKID_PRI_MD 10 + +#if defined(TEST_PROGRAM) && !defined(CONFIG_BLKID_DEBUG) +#define CONFIG_BLKID_DEBUG +#endif + +#define DEBUG_CACHE 0x0001 +#define DEBUG_DUMP 0x0002 +#define DEBUG_DEV 0x0004 +#define DEBUG_DEVNAME 0x0008 +#define DEBUG_DEVNO 0x0010 +#define DEBUG_PROBE 0x0020 +#define DEBUG_READ 0x0040 +#define DEBUG_RESOLVE 0x0080 +#define DEBUG_SAVE 0x0100 +#define DEBUG_TAG 0x0200 +#define DEBUG_LOWPROBE 0x0400 +#define DEBUG_CONFIG 0x0800 +#define DEBUG_EVALUATE 0x1000 +#define DEBUG_INIT 0x8000 +#define DEBUG_ALL 0xFFFF + +#ifdef CONFIG_BLKID_DEBUG +extern int blkid_debug_mask; +extern void blkid_init_debug(int mask); +extern void blkid_debug_dump_dev(blkid_dev dev); +extern void blkid_debug_dump_tag(blkid_tag tag); + +#define DBG(m,x) if ((m) & blkid_debug_mask) x; + +#else /* !CONFIG_BLKID_DEBUG */ +#define DBG(m,x) +#define blkid_init_debug(x) +#endif /* CONFIG_BLKID_DEBUG */ + +/* devno.c */ +struct dir_list { + char *name; + struct dir_list *next; +}; +extern void blkid__scan_dir(char *, dev_t, struct dir_list **, char **); +extern int blkid_driver_has_major(const char *drvname, int major); + +/* lseek.c */ +extern blkid_loff_t blkid_llseek(int fd, blkid_loff_t offset, int whence); + +/* read.c */ +extern void blkid_read_cache(blkid_cache cache); + +/* save.c */ +extern int blkid_flush_cache(blkid_cache cache); + +/* cache */ +extern char *blkid_safe_getenv(const char *arg); +extern char *blkid_get_cache_filename(struct blkid_config *conf); + +/* + * Functions to create and find a specific tag type: tag.c + */ +extern void blkid_free_tag(blkid_tag tag); +extern blkid_tag blkid_find_tag_dev(blkid_dev dev, const char *type); +extern int blkid_set_tag(blkid_dev dev, const char *name, + const char *value, const int vlength); + +/* + * Functions to create and find a specific tag type: dev.c + */ +extern blkid_dev blkid_new_dev(void); +extern void blkid_free_dev(blkid_dev dev); + +/* probe.c */ +extern int blkid_probe_is_tiny(blkid_probe pr); +extern int blkid_probe_is_cdrom(blkid_probe pr); +extern unsigned char *blkid_probe_get_buffer(blkid_probe pr, + blkid_loff_t off, blkid_loff_t len); + +extern unsigned char *blkid_probe_get_sector(blkid_probe pr, unsigned int sector); + +extern int blkid_probe_get_dimension(blkid_probe pr, + blkid_loff_t *off, blkid_loff_t *size); + +extern int blkid_probe_set_dimension(blkid_probe pr, + blkid_loff_t off, blkid_loff_t size); + +extern int blkid_probe_get_idmag(blkid_probe pr, const struct blkid_idinfo *id, + blkid_loff_t *offset, const struct blkid_idmag **res); + +/* returns superblok according to 'struct blkid_idmag' */ +#define blkid_probe_get_sb(_pr, _mag, type) \ + ((type *) blkid_probe_get_buffer((_pr),\ + (_mag)->kboff << 10, sizeof(type))) + +extern blkid_partlist blkid_probe_get_partlist(blkid_probe pr); + +extern int blkid_probe_is_covered_by_pt(blkid_probe pr, + blkid_loff_t offset, blkid_loff_t size); + +extern void blkid_probe_chain_reset_vals(blkid_probe pr, struct blkid_chain *chn); +extern int blkid_probe_chain_copy_vals(blkid_probe pr, struct blkid_chain *chn, + struct blkid_prval *vals, int nvals); +extern struct blkid_prval *blkid_probe_assign_value(blkid_probe pr, const char *name); +extern int blkid_probe_reset_last_value(blkid_probe pr); +extern void blkid_probe_append_vals(blkid_probe pr, struct blkid_prval *vals, int nvals); + +extern struct blkid_chain *blkid_probe_get_chain(blkid_probe pr); + +extern struct blkid_prval *__blkid_probe_get_value(blkid_probe pr, int num); +extern struct blkid_prval *__blkid_probe_lookup_value(blkid_probe pr, const char *name); + +extern unsigned long *blkid_probe_get_filter(blkid_probe pr, int chain, int create); +extern int __blkid_probe_invert_filter(blkid_probe pr, int chain); +extern int __blkid_probe_reset_filter(blkid_probe pr, int chain); +extern int __blkid_probe_filter_types(blkid_probe pr, int chain, int flag, char *names[]); + +extern void *blkid_probe_get_binary_data(blkid_probe pr, struct blkid_chain *chn); + +extern int blkid_probe_set_value(blkid_probe pr, const char *name, + unsigned char *data, size_t len); +extern int blkid_probe_vsprintf_value(blkid_probe pr, const char *name, + const char *fmt, va_list ap); +extern int blkid_probe_sprintf_value(blkid_probe pr, const char *name, + const char *fmt, ...); + +extern void blkid_unparse_uuid(const unsigned char *uuid, char *str, size_t len); +extern size_t blkid_rtrim_whitespace(unsigned char *str); + +extern void blkid_probe_set_wiper(blkid_probe pr, blkid_loff_t off, + blkid_loff_t size); +extern int blkid_probe_is_wiped(blkid_probe pr, struct blkid_chain **chn, + blkid_loff_t off, blkid_loff_t size); +extern void blkid_probe_use_wiper(blkid_probe pr, blkid_loff_t off, blkid_loff_t size); + +/* filter bitmap macros */ +#define blkid_bmp_wordsize (8 * sizeof(unsigned long)) +#define blkid_bmp_idx_bit(item) (1UL << ((item) % blkid_bmp_wordsize)) +#define blkid_bmp_idx_byte(item) ((item) / blkid_bmp_wordsize) + +#define blkid_bmp_set_item(bmp, item) \ + ((bmp)[ blkid_bmp_idx_byte(item) ] |= blkid_bmp_idx_bit(item)) + +#define blkid_bmp_unset_item(bmp, item) \ + ((bmp)[ blkid_bmp_idx_byte(item) ] &= ~blkid_bmp_idx_bit(item)) + +#define blkid_bmp_get_item(bmp, item) \ + ((bmp)[ blkid_bmp_idx_byte(item) ] & blkid_bmp_idx_bit(item)) + +#define blkid_bmp_nwords(max_items) \ + (((max_items) + blkid_bmp_wordsize) / blkid_bmp_wordsize) + +#define blkid_bmp_nbytes(max_items) \ + (blkid_bmp_nwords(max_items) * sizeof(unsigned long)) + +/* encode.c */ +extern size_t blkid_encode_to_utf8(int enc, unsigned char *dest, size_t len, + const unsigned char *src, size_t count); + +#define BLKID_ENC_UTF16BE 0 +#define BLKID_ENC_UTF16LE 1 + +#endif /* _BLKID_BLKIDP_H */ diff --git a/libblkid/src/cache.c b/libblkid/src/cache.c new file mode 100644 index 00000000..feec6ddf --- /dev/null +++ b/libblkid/src/cache.c @@ -0,0 +1,264 @@ +/* + * cache.c - allocation/initialization/free routines for cache + * + * Copyright (C) 2001 Andreas Dilger + * Copyright (C) 2003 Theodore Ts'o + * + * %Begin-Header% + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * %End-Header% + */ + +#if HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_ERRNO_H +#include +#endif +#include +#include +#ifdef HAVE_SYS_STAT_H +#include +#endif +#include "blkidP.h" +#include "env.h" + +int blkid_debug_mask = 0; + +/** + * SECTION:cache + * @title: Cache + * @short_description: basic routines to work with libblkid cache + * + * Block device information is normally kept in a cache file /etc/blkid.tab and is + * verified to still be valid before being returned to the user (if the user has + * read permission on the raw block device, otherwise not). The cache file also + * allows unprivileged users (normally anyone other than root, or those not in the + * "disk" group) to locate devices by label/id. The standard location of the + * cache file can be overridden by the environment variable BLKID_FILE. + * + * In situations where one is getting information about a single known device, it + * does not impact performance whether the cache is used or not (unless you are + * not able to read the block device directly). If you are dealing with multiple + * devices, use of the cache is highly recommended (even if empty) as devices will + * be scanned at most one time and the on-disk cache will be updated if possible. + * There is rarely a reason not to use the cache. + * + * In some cases (modular kernels), block devices are not even visible until after + * they are accessed the first time, so it is critical that there is some way to + * locate these devices without enumerating only visible devices, so the use of + * the cache file is required in this situation. + */ + +#if 0 /* ifdef CONFIG_BLKID_DEBUG */ +static blkid_debug_dump_cache(int mask, blkid_cache cache) +{ + struct list_head *p; + + if (!cache) { + printf("cache: NULL\n"); + return; + } + + printf("cache: time = %lu\n", cache->bic_time); + printf("cache: flags = 0x%08X\n", cache->bic_flags); + + list_for_each(p, &cache->bic_devs) { + blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs); + blkid_debug_dump_dev(dev); + } +} +#endif + +#ifdef CONFIG_BLKID_DEBUG +void blkid_init_debug(int mask) +{ + if (blkid_debug_mask & DEBUG_INIT) + return; + + if (!mask) + { + char *dstr = getenv("LIBBLKID_DEBUG"); + + if (!dstr) + dstr = getenv("BLKID_DEBUG"); /* for backward compatibility */ + if (dstr) + blkid_debug_mask = strtoul(dstr, 0, 0); + } else + blkid_debug_mask = mask; + + if (blkid_debug_mask) + printf("libblkid: debug mask set to 0x%04x.\n", blkid_debug_mask); + + blkid_debug_mask |= DEBUG_INIT; +} +#endif + +/* returns allocated path to cache */ +char *blkid_get_cache_filename(struct blkid_config *conf) +{ + char *filename; + + filename = safe_getenv("BLKID_FILE"); + if (filename) + filename = blkid_strdup(filename); + else if (conf) + filename = blkid_strdup(conf->cachefile); + else { + struct blkid_config *c = blkid_read_config(NULL); + if (!c) + filename = blkid_strdup(BLKID_CACHE_FILE); + else { + filename = c->cachefile; /* already allocated */ + c->cachefile = NULL; + blkid_free_config(c); + } + } + return filename; +} + +/** + * blkid_get_cache: + * @cache: pointer to return cache handler + * @filename: path to the cache file or NULL for the default path + * + * Allocates and initialize librray cache handler. + * + * Returns: 0 on success or number less than zero in case of error. + */ +int blkid_get_cache(blkid_cache *ret_cache, const char *filename) +{ + blkid_cache cache; + + blkid_init_debug(0); + + DBG(DEBUG_CACHE, printf("creating blkid cache (using %s)\n", + filename ? filename : "default cache")); + + if (!(cache = (blkid_cache) calloc(1, sizeof(struct blkid_struct_cache)))) + return -BLKID_ERR_MEM; + + INIT_LIST_HEAD(&cache->bic_devs); + INIT_LIST_HEAD(&cache->bic_tags); + + if (filename && !*filename) + filename = NULL; + if (filename) + cache->bic_filename = blkid_strdup(filename); + else + cache->bic_filename = blkid_get_cache_filename(NULL); + + blkid_read_cache(cache); + *ret_cache = cache; + return 0; +} + +/** + * blkid_put_cache: + * @cache: cache handler + * + * Saves changes to cache file. + */ +void blkid_put_cache(blkid_cache cache) +{ + if (!cache) + return; + + (void) blkid_flush_cache(cache); + + DBG(DEBUG_CACHE, printf("freeing cache struct\n")); + + /* DBG(DEBUG_CACHE, blkid_debug_dump_cache(cache)); */ + + while (!list_empty(&cache->bic_devs)) { + blkid_dev dev = list_entry(cache->bic_devs.next, + struct blkid_struct_dev, + bid_devs); + blkid_free_dev(dev); + } + + while (!list_empty(&cache->bic_tags)) { + blkid_tag tag = list_entry(cache->bic_tags.next, + struct blkid_struct_tag, + bit_tags); + + while (!list_empty(&tag->bit_names)) { + blkid_tag bad = list_entry(tag->bit_names.next, + struct blkid_struct_tag, + bit_names); + + DBG(DEBUG_CACHE, printf("warning: unfreed tag %s=%s\n", + bad->bit_name, bad->bit_val)); + blkid_free_tag(bad); + } + blkid_free_tag(tag); + } + + blkid_free_probe(cache->probe); + + free(cache->bic_filename); + free(cache); +} + +/** + * blkid_gc_cache: + * @cache: cache handler + * + * Removes garbage (non-existing devices) from the cache. + */ +void blkid_gc_cache(blkid_cache cache) +{ + struct list_head *p, *pnext; + struct stat st; + + if (!cache) + return; + + list_for_each_safe(p, pnext, &cache->bic_devs) { + blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs); + if (!p) + break; + if (stat(dev->bid_name, &st) < 0) { + DBG(DEBUG_CACHE, + printf("freeing %s\n", dev->bid_name)); + blkid_free_dev(dev); + cache->bic_flags |= BLKID_BIC_FL_CHANGED; + } else { + DBG(DEBUG_CACHE, + printf("Device %s exists\n", dev->bid_name)); + } + } +} + +#ifdef TEST_PROGRAM +int main(int argc, char** argv) +{ + blkid_cache cache = NULL; + int ret; + + blkid_init_debug(DEBUG_ALL); + + if ((argc > 2)) { + fprintf(stderr, "Usage: %s [filename] \n", argv[0]); + exit(1); + } + + if ((ret = blkid_get_cache(&cache, argv[1])) < 0) { + fprintf(stderr, "error %d parsing cache file %s\n", ret, + argv[1] ? argv[1] : BLKID_CACHE_FILE); + exit(1); + } + if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) { + fprintf(stderr, "%s: error creating cache (%d)\n", + argv[0], ret); + exit(1); + } + if ((ret = blkid_probe_all(cache) < 0)) + fprintf(stderr, "error probing devices\n"); + + blkid_put_cache(cache); + + return ret; +} +#endif diff --git a/libblkid/src/config.c b/libblkid/src/config.c new file mode 100644 index 00000000..110251a9 --- /dev/null +++ b/libblkid/src/config.c @@ -0,0 +1,201 @@ +/* + * config.c - blkid.conf routines + * + * Copyright (C) 2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ + +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_STAT_H +#include +#endif +#ifdef HAVE_ERRNO_H +#include +#endif +#include +#include + +#include "blkidP.h" +#include "env.h" + +static int parse_evaluate(struct blkid_config *conf, char *s) +{ + while(s && *s) { + char *sep; + + if (conf->nevals >= __BLKID_EVAL_LAST) + goto err; + sep = strchr(s, ','); + if (sep) + *sep = '\0'; + if (strcmp(s, "udev") == 0) + conf->eval[conf->nevals] = BLKID_EVAL_UDEV; + else if (strcmp(s, "scan") == 0) + conf->eval[conf->nevals] = BLKID_EVAL_SCAN; + else + goto err; + conf->nevals++; + if (sep) + s = sep + 1; + else + break; + } + return 0; +err: + DBG(DEBUG_CONFIG, printf( + "config file: unknown evaluation method '%s'.\n", s)); + return -1; +} + +static int parse_next(FILE *fd, struct blkid_config *conf) +{ + char buf[BUFSIZ]; + char *s; + + /* read the next non-blank non-comment line */ + do { + if (fgets (buf, sizeof(buf), fd) == NULL) + return feof(fd) ? 0 : -1; + s = strchr (buf, '\n'); + if (!s) { + /* Missing final newline? Otherwise extremely */ + /* long line - assume file was corrupted */ + if (feof(fd)) + s = strchr (buf, '\0'); + else { + DBG(DEBUG_CONFIG, fprintf(stderr, + "libblkid: config file: missing newline at line '%s'.\n", + buf)); + return -1; + } + } + *s = '\0'; + if (--s >= buf && *s == '\r') + *s = '\0'; + + s = buf; + while (*s == ' ' || *s == '\t') /* skip space */ + s++; + + } while (*s == '\0' || *s == '#'); + + if (!strncmp(s, "SEND_UEVENT=", 12)) { + s += 13; + if (*s && !strcasecmp(s, "yes")) + conf->uevent = TRUE; + else if (*s) + conf->uevent = FALSE; + } else if (!strncmp(s, "CACHE_FILE=", 11)) { + s += 11; + if (*s) + conf->cachefile = blkid_strdup(s); + } else if (!strncmp(s, "EVALUATE=", 9)) { + s += 9; + if (*s && parse_evaluate(conf, s) == -1) + return -1; + } else { + DBG(DEBUG_CONFIG, printf( + "config file: unknown option '%s'.\n", s)); + return -1; + } + return 0; +} + +/* return real config data or built-in default */ +struct blkid_config *blkid_read_config(const char *filename) +{ + struct blkid_config *conf; + FILE *f; + + if (!filename) + filename = safe_getenv("BLKID_CONF"); + if (!filename) + filename = BLKID_CONFIG_FILE; + + conf = (struct blkid_config *) calloc(1, sizeof(*conf)); + if (!conf) + return NULL; + conf->uevent = -1; + + DBG(DEBUG_CONFIG, fprintf(stderr, + "reading config file: %s.\n", filename)); + + f = fopen(filename, "r"); + if (!f) { + DBG(DEBUG_CONFIG, fprintf(stderr, + "%s: does not exist, using built-in default\n", filename)); + goto dflt; + } + while (!feof(f)) { + if (parse_next(f, conf)) { + DBG(DEBUG_CONFIG, fprintf(stderr, + "%s: parse error\n", filename)); + goto err; + } + } +dflt: + if (!conf->nevals) { + conf->eval[0] = BLKID_EVAL_UDEV; + conf->eval[1] = BLKID_EVAL_SCAN; + conf->nevals = 2; + } + if (!conf->cachefile) + conf->cachefile = blkid_strdup(BLKID_CACHE_FILE); + if (conf->uevent == -1) + conf->uevent = TRUE; + if (f) + fclose(f); + return conf; +err: + free(conf); + fclose(f); + return NULL; +} + +void blkid_free_config(struct blkid_config *conf) +{ + if (!conf) + return; + free(conf->cachefile); + free(conf); +} + +#ifdef TEST_PROGRAM +/* + * usage: tst_config [] + */ +int main(int argc, char *argv[]) +{ + int i; + struct blkid_config *conf; + char *filename = NULL; + + blkid_init_debug(DEBUG_ALL); + + if (argc == 2) + filename = argv[1]; + + conf = blkid_read_config(filename); + if (!conf) + return EXIT_FAILURE; + + printf("EVALUATE: "); + for (i = 0; i < conf->nevals; i++) + printf("%s ", conf->eval[i] == BLKID_EVAL_UDEV ? "udev" : "scan"); + printf("\n"); + + printf("SEND UEVENT: %s\n", conf->uevent ? "TRUE" : "FALSE"); + printf("CACHE_FILE: %s\n", conf->cachefile); + + blkid_free_config(conf); + return EXIT_SUCCESS; +} +#endif diff --git a/libblkid/src/dev.c b/libblkid/src/dev.c new file mode 100644 index 00000000..791a6c18 --- /dev/null +++ b/libblkid/src/dev.c @@ -0,0 +1,272 @@ +/* + * dev.c - allocation/initialization/free routines for dev + * + * Copyright (C) 2001 Andreas Dilger + * Copyright (C) 2003 Theodore Ts'o + * + * %Begin-Header% + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * %End-Header% + */ + +#include +#include + +#include "blkidP.h" + +/* + * NOTE: reference manual is not structured as code. The following section is a generic + * section for all high-level cache search+iterate routines. + */ + +/** + * SECTION:search + * @title: Search and iterate + * @short_description: search devices and iterate over devices in the cache. + * + * Note that high-level probing API provides information about superblocks + * (filesystems/raids) only. For partitions and topology is necessary to use + * the low-level API. + */ + +blkid_dev blkid_new_dev(void) +{ + blkid_dev dev; + + if (!(dev = (blkid_dev) calloc(1, sizeof(struct blkid_struct_dev)))) + return NULL; + + INIT_LIST_HEAD(&dev->bid_devs); + INIT_LIST_HEAD(&dev->bid_tags); + + return dev; +} + +void blkid_free_dev(blkid_dev dev) +{ + if (!dev) + return; + + DBG(DEBUG_DEV, + printf(" freeing dev %s (%s)\n", dev->bid_name, dev->bid_type ? + dev->bid_type : "(null)")); + DBG(DEBUG_DEV, blkid_debug_dump_dev(dev)); + + list_del(&dev->bid_devs); + while (!list_empty(&dev->bid_tags)) { + blkid_tag tag = list_entry(dev->bid_tags.next, + struct blkid_struct_tag, + bit_tags); + blkid_free_tag(tag); + } + free(dev->bid_name); + free(dev); +} + +/* + * Given a blkid device, return its name + */ +extern const char *blkid_dev_devname(blkid_dev dev) +{ + return dev->bid_name; +} + +#ifdef CONFIG_BLKID_DEBUG +void blkid_debug_dump_dev(blkid_dev dev) +{ + struct list_head *p; + + if (!dev) { + printf(" dev: NULL\n"); + return; + } + + printf(" dev: name = %s\n", dev->bid_name); + printf(" dev: DEVNO=\"0x%0llx\"\n", (long long)dev->bid_devno); + printf(" dev: TIME=\"%ld.%ld\"\n", (long)dev->bid_time, (long)dev->bid_utime); + printf(" dev: PRI=\"%d\"\n", dev->bid_pri); + printf(" dev: flags = 0x%08X\n", dev->bid_flags); + + list_for_each(p, &dev->bid_tags) { + blkid_tag tag = list_entry(p, struct blkid_struct_tag, bit_tags); + if (tag) + printf(" tag: %s=\"%s\"\n", tag->bit_name, + tag->bit_val); + else + printf(" tag: NULL\n"); + } + printf("\n"); +} +#endif + +/* + * dev iteration routines for the public libblkid interface. + * + * These routines do not expose the list.h implementation, which are a + * contamination of the namespace, and which force us to reveal far, far + * too much of our internal implemenation. I'm not convinced I want + * to keep list.h in the long term, anyway. It's fine for kernel + * programming, but performance is not the #1 priority for this + * library, and I really don't like the tradeoff of type-safety for + * performance for this application. [tytso:20030125.2007EST] + */ + +/* + * This series of functions iterate over all devices in a blkid cache + */ +#define DEV_ITERATE_MAGIC 0x01a5284c + +struct blkid_struct_dev_iterate { + int magic; + blkid_cache cache; + char *search_type; + char *search_value; + struct list_head *p; +}; + +extern blkid_dev_iterate blkid_dev_iterate_begin(blkid_cache cache) +{ + blkid_dev_iterate iter; + + iter = malloc(sizeof(struct blkid_struct_dev_iterate)); + if (iter) { + iter->magic = DEV_ITERATE_MAGIC; + iter->cache = cache; + iter->p = cache->bic_devs.next; + iter->search_type = 0; + iter->search_value = 0; + } + return (iter); +} + +extern int blkid_dev_set_search(blkid_dev_iterate iter, + char *search_type, char *search_value) +{ + char *new_type, *new_value; + + if (!iter || iter->magic != DEV_ITERATE_MAGIC || !search_type || + !search_value) + return -1; + new_type = malloc(strlen(search_type)+1); + new_value = malloc(strlen(search_value)+1); + if (!new_type || !new_value) { + free(new_type); + free(new_value); + return -1; + } + strcpy(new_type, search_type); + strcpy(new_value, search_value); + free(iter->search_type); + free(iter->search_value); + iter->search_type = new_type; + iter->search_value = new_value; + return 0; +} + +/* + * Return 0 on success, -1 on error + */ +extern int blkid_dev_next(blkid_dev_iterate iter, + blkid_dev *ret_dev) +{ + blkid_dev dev; + + *ret_dev = 0; + if (!iter || iter->magic != DEV_ITERATE_MAGIC) + return -1; + while (iter->p != &iter->cache->bic_devs) { + dev = list_entry(iter->p, struct blkid_struct_dev, bid_devs); + iter->p = iter->p->next; + if (iter->search_type && + !blkid_dev_has_tag(dev, iter->search_type, + iter->search_value)) + continue; + *ret_dev = dev; + return 0; + } + return -1; +} + +extern void blkid_dev_iterate_end(blkid_dev_iterate iter) +{ + if (!iter || iter->magic != DEV_ITERATE_MAGIC) + return; + iter->magic = 0; + free(iter->search_type); + free(iter->search_value); + free(iter); +} + +#ifdef TEST_PROGRAM +#ifdef HAVE_GETOPT_H +#include +#else +extern char *optarg; +extern int optind; +#endif + +void usage(char *prog) +{ + fprintf(stderr, "Usage: %s [-f blkid_file] [-m debug_mask]\n", prog); + fprintf(stderr, "\tList all devices and exit\n"); + exit(1); +} + +int main(int argc, char **argv) +{ + blkid_dev_iterate iter; + blkid_cache cache = NULL; + blkid_dev dev; + int c, ret; + char *tmp; + char *file = NULL; + char *search_type = NULL; + char *search_value = NULL; + + while ((c = getopt (argc, argv, "m:f:")) != EOF) + switch (c) { + case 'f': + file = optarg; + break; + case 'm': + { + int mask = strtoul (optarg, &tmp, 0); + if (*tmp) { + fprintf(stderr, "Invalid debug mask: %s\n", + optarg); + exit(1); + } + blkid_init_debug(mask); + break; + } + case '?': + usage(argv[0]); + } + if (argc >= optind+2) { + search_type = argv[optind]; + search_value = argv[optind+1]; + optind += 2; + } + if (argc != optind) + usage(argv[0]); + + if ((ret = blkid_get_cache(&cache, file)) != 0) { + fprintf(stderr, "%s: error creating cache (%d)\n", + argv[0], ret); + exit(1); + } + + iter = blkid_dev_iterate_begin(cache); + if (search_type) + blkid_dev_set_search(iter, search_type, search_value); + while (blkid_dev_next(iter, &dev) == 0) { + printf("Device: %s\n", blkid_dev_devname(dev)); + } + blkid_dev_iterate_end(iter); + + + blkid_put_cache(cache); + return (0); +} +#endif diff --git a/libblkid/src/devname.c b/libblkid/src/devname.c new file mode 100644 index 00000000..e1fc2c84 --- /dev/null +++ b/libblkid/src/devname.c @@ -0,0 +1,680 @@ +/* + * devname.c - get a dev by its device inode name + * + * Copyright (C) Andries Brouwer + * Copyright (C) 1999, 2000, 2001, 2002, 2003 Theodore Ts'o + * Copyright (C) 2001 Andreas Dilger + * + * %Begin-Header% + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * %End-Header% + */ + +#define _GNU_SOURCE 1 + +#include +#include +#include +#if HAVE_UNISTD_H +#include +#endif +#include +#include +#include +#if HAVE_SYS_TYPES_H +#include +#endif +#include +#if HAVE_SYS_STAT_H +#include +#endif +#if HAVE_ERRNO_H +#include +#endif +#include + +#include "blkidP.h" + +#include "canonicalize.h" /* $(top_srcdir)/include */ +#include "pathnames.h" +#include "sysfs.h" +#include "at.h" + +/* + * Find a dev struct in the cache by device name, if available. + * + * If there is no entry with the specified device name, and the create + * flag is set, then create an empty device entry. + */ +blkid_dev blkid_get_dev(blkid_cache cache, const char *devname, int flags) +{ + blkid_dev dev = NULL, tmp; + struct list_head *p, *pnext; + + if (!cache || !devname) + return NULL; + + list_for_each(p, &cache->bic_devs) { + tmp = list_entry(p, struct blkid_struct_dev, bid_devs); + if (strcmp(tmp->bid_name, devname)) + continue; + + DBG(DEBUG_DEVNAME, + printf("found devname %s in cache\n", tmp->bid_name)); + dev = tmp; + break; + } + + if (!dev && (flags & BLKID_DEV_CREATE)) { + if (access(devname, F_OK) < 0) + return NULL; + dev = blkid_new_dev(); + if (!dev) + return NULL; + dev->bid_time = INT_MIN; + dev->bid_name = blkid_strdup(devname); + dev->bid_cache = cache; + list_add_tail(&dev->bid_devs, &cache->bic_devs); + cache->bic_flags |= BLKID_BIC_FL_CHANGED; + } + + if (flags & BLKID_DEV_VERIFY) { + dev = blkid_verify(cache, dev); + if (!dev || !(dev->bid_flags & BLKID_BID_FL_VERIFIED)) + return dev; + /* + * If the device is verified, then search the blkid + * cache for any entries that match on the type, uuid, + * and label, and verify them; if a cache entry can + * not be verified, then it's stale and so we remove + * it. + */ + list_for_each_safe(p, pnext, &cache->bic_devs) { + blkid_dev dev2; + if (!p) + break; + dev2 = list_entry(p, struct blkid_struct_dev, bid_devs); + if (dev2->bid_flags & BLKID_BID_FL_VERIFIED) + continue; + if (!dev->bid_type || !dev2->bid_type || + strcmp(dev->bid_type, dev2->bid_type)) + continue; + if (dev->bid_label && dev2->bid_label && + strcmp(dev->bid_label, dev2->bid_label)) + continue; + if (dev->bid_uuid && dev2->bid_uuid && + strcmp(dev->bid_uuid, dev2->bid_uuid)) + continue; + if ((dev->bid_label && !dev2->bid_label) || + (!dev->bid_label && dev2->bid_label) || + (dev->bid_uuid && !dev2->bid_uuid) || + (!dev->bid_uuid && dev2->bid_uuid)) + continue; + dev2 = blkid_verify(cache, dev2); + if (dev2 && !(dev2->bid_flags & BLKID_BID_FL_VERIFIED)) + blkid_free_dev(dev2); + } + } + return dev; +} + +/* Directories where we will try to search for device names */ +static const char *dirlist[] = { "/dev", "/devfs", "/devices", NULL }; + +static int is_dm_leaf(const char *devname) +{ + struct dirent *de, *d_de; + DIR *dir, *d_dir; + char path[256]; + int ret = 1; + + if ((dir = opendir("/sys/block")) == NULL) + return 0; + while ((de = readdir(dir)) != NULL) { + if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..") || + !strcmp(de->d_name, devname) || + strncmp(de->d_name, "dm-", 3) || + strlen(de->d_name) > sizeof(path)-32) + continue; + sprintf(path, "/sys/block/%s/slaves", de->d_name); + if ((d_dir = opendir(path)) == NULL) + continue; + while ((d_de = readdir(d_dir)) != NULL) { + if (!strcmp(d_de->d_name, devname)) { + ret = 0; + break; + } + } + closedir(d_dir); + if (!ret) + break; + } + closedir(dir); + return ret; +} + +/* + * Probe a single block device to add to the device cache. + */ +static void probe_one(blkid_cache cache, const char *ptname, + dev_t devno, int pri, int only_if_new, int removable) +{ + blkid_dev dev = NULL; + struct list_head *p, *pnext; + const char **dir; + char *devname = NULL; + + /* See if we already have this device number in the cache. */ + list_for_each_safe(p, pnext, &cache->bic_devs) { + blkid_dev tmp = list_entry(p, struct blkid_struct_dev, + bid_devs); + if (tmp->bid_devno == devno) { + if (only_if_new && !access(tmp->bid_name, F_OK)) + return; + dev = blkid_verify(cache, tmp); + if (dev && (dev->bid_flags & BLKID_BID_FL_VERIFIED)) + break; + dev = 0; + } + } + if (dev && dev->bid_devno == devno) + goto set_pri; + + /* Try to translate private device-mapper dm- names + * to standard /dev/mapper/. + */ + if (!strncmp(ptname, "dm-", 3) && isdigit(ptname[3])) { + devname = canonicalize_dm_name(ptname); + if (!devname) + blkid__scan_dir("/dev/mapper", devno, 0, &devname); + if (devname) + goto get_dev; + } + + /* + * Take a quick look at /dev/ptname for the device number. We check + * all of the likely device directories. If we don't find it, or if + * the stat information doesn't check out, use blkid_devno_to_devname() + * to find it via an exhaustive search for the device major/minor. + */ + for (dir = dirlist; *dir; dir++) { + struct stat st; + char device[256]; + + sprintf(device, "%s/%s", *dir, ptname); + if ((dev = blkid_get_dev(cache, device, BLKID_DEV_FIND)) && + dev->bid_devno == devno) + goto set_pri; + + if (stat(device, &st) == 0 && + (S_ISBLK(st.st_mode) || + (S_ISCHR(st.st_mode) && !strncmp(ptname, "ubi", 3))) && + st.st_rdev == devno) { + devname = blkid_strdup(device); + goto get_dev; + } + } + /* Do a short-cut scan of /dev/mapper first */ + if (!devname) + blkid__scan_dir("/dev/mapper", devno, 0, &devname); + if (!devname) { + devname = blkid_devno_to_devname(devno); + if (!devname) + return; + } + +get_dev: + dev = blkid_get_dev(cache, devname, BLKID_DEV_NORMAL); + free(devname); + +set_pri: + if (dev) { + if (pri) + dev->bid_pri = pri; + else if (!strncmp(dev->bid_name, "/dev/mapper/", 11)) { + dev->bid_pri = BLKID_PRI_DM; + if (is_dm_leaf(ptname)) + dev->bid_pri += 5; + } else if (!strncmp(ptname, "md", 2)) + dev->bid_pri = BLKID_PRI_MD; + if (removable) + dev->bid_flags |= BLKID_BID_FL_REMOVABLE; + } + return; +} + +#define PROC_PARTITIONS "/proc/partitions" +#define VG_DIR "/proc/lvm/VGs" + +/* + * This function initializes the UUID cache with devices from the LVM + * proc hierarchy. We currently depend on the names of the LVM + * hierarchy giving us the device structure in /dev. (XXX is this a + * safe thing to do?) + */ +#ifdef VG_DIR +static dev_t lvm_get_devno(const char *lvm_device) +{ + FILE *lvf; + char buf[1024]; + int ma, mi; + dev_t ret = 0; + + DBG(DEBUG_DEVNAME, printf("opening %s\n", lvm_device)); + if ((lvf = fopen(lvm_device, "r")) == NULL) { + DBG(DEBUG_DEVNAME, printf("%s: (%d) %s\n", lvm_device, errno, + strerror(errno))); + return 0; + } + + while (fgets(buf, sizeof(buf), lvf)) { + if (sscanf(buf, "device: %d:%d", &ma, &mi) == 2) { + ret = makedev(ma, mi); + break; + } + } + fclose(lvf); + + return ret; +} + +static void lvm_probe_all(blkid_cache cache, int only_if_new) +{ + DIR *vg_list; + struct dirent *vg_iter; + int vg_len = strlen(VG_DIR); + dev_t dev; + + if ((vg_list = opendir(VG_DIR)) == NULL) + return; + + DBG(DEBUG_DEVNAME, printf("probing LVM devices under %s\n", VG_DIR)); + + while ((vg_iter = readdir(vg_list)) != NULL) { + DIR *lv_list; + char *vdirname; + char *vg_name; + struct dirent *lv_iter; + + vg_name = vg_iter->d_name; + if (!strcmp(vg_name, ".") || !strcmp(vg_name, "..")) + continue; + vdirname = malloc(vg_len + strlen(vg_name) + 8); + if (!vdirname) + goto exit; + sprintf(vdirname, "%s/%s/LVs", VG_DIR, vg_name); + + lv_list = opendir(vdirname); + free(vdirname); + if (lv_list == NULL) + continue; + + while ((lv_iter = readdir(lv_list)) != NULL) { + char *lv_name, *lvm_device; + + lv_name = lv_iter->d_name; + if (!strcmp(lv_name, ".") || !strcmp(lv_name, "..")) + continue; + + lvm_device = malloc(vg_len + strlen(vg_name) + + strlen(lv_name) + 8); + if (!lvm_device) { + closedir(lv_list); + goto exit; + } + sprintf(lvm_device, "%s/%s/LVs/%s", VG_DIR, vg_name, + lv_name); + dev = lvm_get_devno(lvm_device); + sprintf(lvm_device, "%s/%s", vg_name, lv_name); + DBG(DEBUG_DEVNAME, printf("LVM dev %s: devno 0x%04X\n", + lvm_device, + (unsigned int) dev)); + probe_one(cache, lvm_device, dev, BLKID_PRI_LVM, + only_if_new, 0); + free(lvm_device); + } + closedir(lv_list); + } +exit: + closedir(vg_list); +} +#endif + +#define PROC_EVMS_VOLUMES "/proc/evms/volumes" + +static int +evms_probe_all(blkid_cache cache, int only_if_new) +{ + char line[100]; + int ma, mi, sz, num = 0; + FILE *procpt; + char device[110]; + + procpt = fopen(PROC_EVMS_VOLUMES, "r"); + if (!procpt) + return 0; + while (fgets(line, sizeof(line), procpt)) { + if (sscanf (line, " %d %d %d %*s %*s %[^\n ]", + &ma, &mi, &sz, device) != 4) + continue; + + DBG(DEBUG_DEVNAME, printf("Checking partition %s (%d, %d)\n", + device, ma, mi)); + + probe_one(cache, device, makedev(ma, mi), BLKID_PRI_EVMS, + only_if_new, 0); + num++; + } + fclose(procpt); + return num; +} + +static void +ubi_probe_all(blkid_cache cache, int only_if_new) +{ + const char **dirname; + + for (dirname = dirlist; *dirname; dirname++) { + DBG(DEBUG_DEVNAME, printf("probing UBI volumes under %s\n", + *dirname)); + + DIR *dir; + struct dirent *iter; + + dir = opendir(*dirname); + if (dir == NULL) + continue ; + + while ((iter = readdir(dir)) != NULL) { + char *name; + struct stat st; + dev_t dev; + + name = iter->d_name; +#ifdef _DIRENT_HAVE_D_TYPE + if (iter->d_type != DT_UNKNOWN && + iter->d_type != DT_CHR && iter->d_type != DT_LNK) + continue; +#endif + if (!strcmp(name, ".") || !strcmp(name, "..") || + !strstr(name, "ubi")) + continue; + if (!strcmp(name, "ubi_ctrl")) + continue; + if (fstat_at(dirfd(dir), *dirname, name, &st, 0)) + continue; + + dev = st.st_rdev; + + if (!S_ISCHR(st.st_mode) || !minor(dev)) + continue; + DBG(DEBUG_DEVNAME, printf("UBI vol %s/%s: devno 0x%04X\n", + *dirname, name, (int) dev)); + probe_one(cache, name, dev, BLKID_PRI_UBI, only_if_new, 0); + } + closedir(dir); + } +} + +/* + * Read the device data for all available block devices in the system. + */ +static int probe_all(blkid_cache cache, int only_if_new) +{ + FILE *proc; + char line[1024]; + char ptname0[128], ptname1[128], *ptname = 0; + char *ptnames[2]; + dev_t devs[2]; + int ma, mi; + unsigned long long sz; + int lens[2] = { 0, 0 }; + int which = 0, last = 0; + struct list_head *p, *pnext; + + ptnames[0] = ptname0; + ptnames[1] = ptname1; + + if (!cache) + return -BLKID_ERR_PARAM; + + if (cache->bic_flags & BLKID_BIC_FL_PROBED && + time(0) - cache->bic_time < BLKID_PROBE_INTERVAL) + return 0; + + blkid_read_cache(cache); + evms_probe_all(cache, only_if_new); +#ifdef VG_DIR + lvm_probe_all(cache, only_if_new); +#endif + ubi_probe_all(cache, only_if_new); + + proc = fopen(PROC_PARTITIONS, "r"); + if (!proc) + return -BLKID_ERR_PROC; + + while (fgets(line, sizeof(line), proc)) { + last = which; + which ^= 1; + ptname = ptnames[which]; + + if (sscanf(line, " %d %d %llu %128[^\n ]", + &ma, &mi, &sz, ptname) != 4) + continue; + devs[which] = makedev(ma, mi); + + DBG(DEBUG_DEVNAME, printf("read partition name %s\n", ptname)); + + /* Skip whole disk devs unless they have no partitions. + * If base name of device has changed, also + * check previous dev to see if it didn't have a partn. + * heuristic: partition name ends in a digit, & partition + * names contain whole device name as substring. + * + * Skip extended partitions. + * heuristic: size is 1 + * + * FIXME: skip /dev/{ida,cciss,rd} whole-disk devs + */ + + lens[which] = strlen(ptname); + + /* ends in a digit, clearly a partition, so check */ + if (isdigit(ptname[lens[which] - 1])) { + DBG(DEBUG_DEVNAME, + printf("partition dev %s, devno 0x%04X\n", + ptname, (unsigned int) devs[which])); + + if (sz > 1) + probe_one(cache, ptname, devs[which], 0, + only_if_new, 0); + lens[which] = 0; /* mark as checked */ + } + + /* + * If last was a whole disk and we just found a partition + * on it, remove the whole-disk dev from the cache if + * it exists. + */ + if (lens[last] && !strncmp(ptnames[last], ptname, lens[last])) { + list_for_each_safe(p, pnext, &cache->bic_devs) { + blkid_dev tmp; + + /* find blkid dev for the whole-disk devno */ + tmp = list_entry(p, struct blkid_struct_dev, + bid_devs); + if (tmp->bid_devno == devs[last]) { + DBG(DEBUG_DEVNAME, + printf("freeing %s\n", + tmp->bid_name)); + blkid_free_dev(tmp); + cache->bic_flags |= BLKID_BIC_FL_CHANGED; + break; + } + } + lens[last] = 0; + } + /* + * If last was not checked because it looked like a whole-disk + * dev, and the device's base name has changed, + * check last as well. + */ + if (lens[last] && strncmp(ptnames[last], ptname, lens[last])) { + DBG(DEBUG_DEVNAME, + printf("whole dev %s, devno 0x%04X\n", + ptnames[last], (unsigned int) devs[last])); + probe_one(cache, ptnames[last], devs[last], 0, + only_if_new, 0); + lens[last] = 0; + } + } + + /* Handle the last device if it wasn't partitioned */ + if (lens[which]) + probe_one(cache, ptname, devs[which], 0, only_if_new, 0); + + fclose(proc); + blkid_flush_cache(cache); + return 0; +} + +/* Don't use it by default -- it's pretty slow (because cdroms, floppy, ...) + */ +static int probe_all_removable(blkid_cache cache) +{ + DIR *dir; + struct dirent *d; + + if (!cache) + return -BLKID_ERR_PARAM; + + dir = opendir(_PATH_SYS_BLOCK); + if (!dir) + return -BLKID_ERR_PROC; + + while((d = readdir(dir))) { + struct sysfs_cxt sysfs; + int removable = 0; + dev_t devno; + +#ifdef _DIRENT_HAVE_D_TYPE + if (d->d_type != DT_UNKNOWN && d->d_type != DT_LNK) + continue; +#endif + if (d->d_name[0] == '.' && + ((d->d_name[1] == 0) || + ((d->d_name[1] == '.') && (d->d_name[2] == 0)))) + continue; + + devno = sysfs_devname_to_devno(d->d_name, NULL); + if (!devno) + continue; + + if (sysfs_init(&sysfs, devno, NULL) == 0) { + sysfs_read_int(&sysfs, "removable", &removable); + sysfs_deinit(&sysfs); + } + + if (removable) + probe_one(cache, d->d_name, devno, 0, 0, 1); + } + + closedir(dir); + return 0; +} + + +/** + * blkid_probe_all: + * @cache: cache handler + * + * Probes all block devices. + * + * Returns: 0 on success, or number less than zero in case of error. + */ +int blkid_probe_all(blkid_cache cache) +{ + int ret; + + DBG(DEBUG_PROBE, printf("Begin blkid_probe_all()\n")); + ret = probe_all(cache, 0); + cache->bic_time = time(0); + cache->bic_flags |= BLKID_BIC_FL_PROBED; + DBG(DEBUG_PROBE, printf("End blkid_probe_all()\n")); + return ret; +} + +/** + * blkid_probe_all_new: + * @cache: cache handler + * + * Probes all new block devices. + * + * Returns: 0 on success, or number less than zero in case of error. + */ +int blkid_probe_all_new(blkid_cache cache) +{ + int ret; + + DBG(DEBUG_PROBE, printf("Begin blkid_probe_all_new()\n")); + ret = probe_all(cache, 1); + DBG(DEBUG_PROBE, printf("End blkid_probe_all_new()\n")); + return ret; +} + +/** + * blkid_probe_all_removable: + * @cache: cache handler + * + * The libblkid probing is based on devices from /proc/partitions by default. + * This file usually does not contain removable devices (e.g. CDROMs) and this kind + * of devices are invisible for libblkid. + * + * This function adds removable block devices to @cache (probing is based on + * information from the /sys directory). Don't forget that removable devices + * (floppies, CDROMs, ...) could be pretty slow. It's very bad idea to call + * this function by default. + * + * Note that devices which were detected by this function won't be written to + * blkid.tab cache file. + * + * Returns: 0 on success, or number less than zero in case of error. + */ +int blkid_probe_all_removable(blkid_cache cache) +{ + int ret; + + DBG(DEBUG_PROBE, printf("Begin blkid_probe_all_removable()\n")); + ret = probe_all_removable(cache); + DBG(DEBUG_PROBE, printf("End blkid_probe_all_removable()\n")); + return ret; +} + +#ifdef TEST_PROGRAM +int main(int argc, char **argv) +{ + blkid_cache cache = NULL; + int ret; + + blkid_init_debug(DEBUG_ALL); + if (argc != 1) { + fprintf(stderr, "Usage: %s\n" + "Probe all devices and exit\n", argv[0]); + exit(1); + } + if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) { + fprintf(stderr, "%s: error creating cache (%d)\n", + argv[0], ret); + exit(1); + } + if (blkid_probe_all(cache) < 0) + printf("%s: error probing devices\n", argv[0]); + + if (blkid_probe_all_removable(cache) < 0) + printf("%s: error probing removable devices\n", argv[0]); + + blkid_put_cache(cache); + return (0); +} +#endif diff --git a/libblkid/src/devno.c b/libblkid/src/devno.c new file mode 100644 index 00000000..9a356a84 --- /dev/null +++ b/libblkid/src/devno.c @@ -0,0 +1,527 @@ +/* + * devno.c - find a particular device by its device number (major/minor) + * + * Copyright (C) 2000, 2001, 2003 Theodore Ts'o + * Copyright (C) 2001 Andreas Dilger + * + * %Begin-Header% + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * %End-Header% + */ + +#include +#include +#if HAVE_UNISTD_H +#include +#endif +#include +#if HAVE_SYS_TYPES_H +#include +#endif +#if HAVE_SYS_STAT_H +#include +#endif +#include +#if HAVE_ERRNO_H +#include +#endif +#if HAVE_SYS_MKDEV_H +#include +#endif +#include +#include + +#include "blkidP.h" +#include "pathnames.h" +#include "at.h" +#include "sysfs.h" + +char *blkid_strndup(const char *s, int length) +{ + char *ret; + + if (!s) + return NULL; + + if (!length) + length = strlen(s); + + ret = malloc(length + 1); + if (ret) { + strncpy(ret, s, length); + ret[length] = '\0'; + } + return ret; +} + +char *blkid_strdup(const char *s) +{ + return blkid_strndup(s, 0); +} + +char *blkid_strconcat(const char *a, const char *b, const char *c) +{ + char *res, *p; + size_t len, al, bl, cl; + + al = a ? strlen(a) : 0; + bl = b ? strlen(b) : 0; + cl = c ? strlen(c) : 0; + + len = al + bl + cl; + if (!len) + return NULL; + p = res = malloc(len + 1); + if (!res) + return NULL; + if (al) { + memcpy(p, a, al); + p += al; + } + if (bl) { + memcpy(p, b, bl); + p += bl; + } + if (cl) { + memcpy(p, c, cl); + p += cl; + } + *p = '\0'; + return res; +} + +/* + * This function adds an entry to the directory list + */ +static void add_to_dirlist(const char *dir, const char *subdir, + struct dir_list **list) +{ + struct dir_list *dp; + + dp = malloc(sizeof(struct dir_list)); + if (!dp) + return; + dp->name = subdir ? blkid_strconcat(dir, "/", subdir) : + blkid_strdup(dir); + if (!dp->name) { + free(dp); + return; + } + dp->next = *list; + *list = dp; +} + +/* + * This function frees a directory list + */ +static void free_dirlist(struct dir_list **list) +{ + struct dir_list *dp, *next; + + for (dp = *list; dp; dp = next) { + next = dp->next; + free(dp->name); + free(dp); + } + *list = NULL; +} + +void blkid__scan_dir(char *dirname, dev_t devno, struct dir_list **list, + char **devname) +{ + DIR *dir; + struct dirent *dp; + struct stat st; + + if ((dir = opendir(dirname)) == NULL) + return; + + while ((dp = readdir(dir)) != 0) { +#ifdef _DIRENT_HAVE_D_TYPE + if (dp->d_type != DT_UNKNOWN && dp->d_type != DT_BLK && + dp->d_type != DT_LNK && dp->d_type != DT_DIR) + continue; +#endif + if (dp->d_name[0] == '.' && + ((dp->d_name[1] == 0) || + ((dp->d_name[1] == '.') && (dp->d_name[2] == 0)))) + continue; + + if (fstat_at(dirfd(dir), dirname, dp->d_name, &st, 0)) + continue; + + if (S_ISBLK(st.st_mode) && st.st_rdev == devno) { + *devname = blkid_strconcat(dirname, "/", dp->d_name); + DBG(DEBUG_DEVNO, + printf("found 0x%llx at %s\n", (long long)devno, + *devname)); + break; + } + + if (!list || !S_ISDIR(st.st_mode)) + continue; + + /* add subdirectory (but not symlink) to the list */ +#ifdef _DIRENT_HAVE_D_TYPE + if (dp->d_type == DT_LNK) + continue; + if (dp->d_type == DT_UNKNOWN) +#endif + { + if (fstat_at(dirfd(dir), dirname, dp->d_name, &st, 1) || + !S_ISDIR(st.st_mode)) + continue; /* symlink or lstat() failed */ + } + + if (*dp->d_name == '.' || ( +#ifdef _DIRENT_HAVE_D_TYPE + dp->d_type == DT_DIR && +#endif + strcmp(dp->d_name, "shm") == 0)) + /* ignore /dev/.{udev,mount,mdadm} and /dev/shm */ + continue; + + add_to_dirlist(dirname, dp->d_name, list); + } + closedir(dir); + return; +} + +/* Directories where we will try to search for device numbers */ +static const char *devdirs[] = { "/devices", "/devfs", "/dev", NULL }; + +/** + * SECTION: misc + * @title: Miscellaneous utils + * @short_description: mix of various utils for low-level and high-level API + */ + +/* returns basename and keeps dirname in the @path */ +static char *stripoff_last_component(char *path) +{ + char *p = strrchr(path, '/'); + + if (!p) + return NULL; + *p = '\0'; + return ++p; +} + +static char *scandev_devno_to_devpath(dev_t devno) +{ + struct dir_list *list = NULL, *new_list = NULL; + char *devname = NULL; + const char **dir; + + /* + * Add the starting directories to search in reverse order of + * importance, since we are using a stack... + */ + for (dir = devdirs; *dir; dir++) + add_to_dirlist(*dir, NULL, &list); + + while (list) { + struct dir_list *current = list; + + list = list->next; + DBG(DEBUG_DEVNO, printf("directory %s\n", current->name)); + blkid__scan_dir(current->name, devno, &new_list, &devname); + free(current->name); + free(current); + if (devname) + break; + /* + * If we're done checking at this level, descend to + * the next level of subdirectories. (breadth-first) + */ + if (list == NULL) { + list = new_list; + new_list = NULL; + } + } + free_dirlist(&list); + free_dirlist(&new_list); + + return devname; +} + +/** + * blkid_devno_to_devname: + * @devno: device number + * + * This function finds the pathname to a block device with a given + * device number. + * + * Returns: a pointer to allocated memory to the pathname on success, + * and NULL on failure. + */ +char *blkid_devno_to_devname(dev_t devno) +{ + char *path = NULL; + char buf[PATH_MAX]; + + path = sysfs_devno_to_devpath(devno, buf, sizeof(buf)); + if (path) + path = strdup(path); + if (!path) + path = scandev_devno_to_devpath(devno); + + if (!path) { + DBG(DEBUG_DEVNO, + printf("blkid: couldn't find devno 0x%04lx\n", + (unsigned long) devno)); + } else { + DBG(DEBUG_DEVNO, + printf("found devno 0x%04llx as %s\n", (long long)devno, path)); + } + + return path; +} + +static int get_dm_wholedisk(struct sysfs_cxt *cxt, char *diskname, + size_t len, dev_t *diskdevno) +{ + int rc = 0; + char *name; + + /* Note, sysfs_get_slave() returns the first slave only, + * if there is more slaves, then return NULL + */ + name = sysfs_get_slave(cxt); + if (!name) + return -1; + + if (diskname && len) { + strncpy(diskname, name, len); + diskname[len - 1] = '\0'; + } + + if (diskdevno) { + *diskdevno = sysfs_devname_to_devno(name, NULL); + if (!*diskdevno) + rc = -1; + } + + free(name); + return rc; +} + +/** + * blkid_devno_to_wholedisk: + * @dev: device number + * @diskname: buffer to return diskname (or NULL) + * @len: diskname buffer size (or 0) + * @diskdevno: pointer to returns devno of entire disk (or NULL) + * + * This function uses sysfs to convert the @devno device number to the *name* + * of the whole disk. The function DOES NOT return full device name. The @dev + * argument could be partition or whole disk -- both is converted. + * + * For example: sda1, 0x0801 --> sda, 0x0800 + * + * For conversion to the full disk *path* use blkid_devno_to_devname(), for + * example: + * + * + * + * + * dev_t dev = 0x0801, disk; // sda1 = 8:1 + * char *diskpath, diskname[32]; + * + * blkid_devno_to_wholedisk(dev, diskname, sizeof(diskname), &disk); + * diskpath = blkid_devno_to_devname(disk); + * + * // print "0x0801: sda, /dev/sda, 8:0 + * printf("0x%x: %s, %s, %d:%d\n", + * dev, diskname, diskpath, major(disk), minor(disk)); + * + * free(diskpath); + * + * + * + * + * Returns: 0 on success or -1 in case of error. + */ +int blkid_devno_to_wholedisk(dev_t dev, char *diskname, + size_t len, dev_t *diskdevno) +{ + struct sysfs_cxt cxt; + int is_part = 0; + + if (!dev || sysfs_init(&cxt, dev, NULL) != 0) + return -1; + + is_part = sysfs_has_attribute(&cxt, "partition"); + if (!is_part) { + /* + * Extra case for partitions mapped by device-mapper. + * + * All regualar partitions (added by BLKPG ioctl or kernel PT + * parser) have the /sys/.../partition file. The partitions + * mapped by DM don't have such file, but they have "part" + * prefix in DM UUID. + */ + char *uuid = sysfs_strdup(&cxt, "dm/uuid"); + char *tmp = uuid; + char *prefix = uuid ? strsep(&tmp, "-") : NULL; + + if (prefix && strncasecmp(prefix, "part", 4) == 0) + is_part = 1; + free(uuid); + + if (is_part && + get_dm_wholedisk(&cxt, diskname, len, diskdevno) == 0) + /* + * partitioned device, mapped by DM + */ + goto done; + + is_part = 0; + } + + if (!is_part) { + /* + * unpartitioned device + */ + if (diskname && len) { + if (!sysfs_get_devname(&cxt, diskname, len)) + goto err; + } + if (diskdevno) + *diskdevno = dev; + + } else { + /* + * partitioned device + * - readlink /sys/dev/block/8:1 = ../../block/sda/sda1 + * - dirname ../../block/sda/sda1 = ../../block/sda + * - basename ../../block/sda = sda + */ + char linkpath[PATH_MAX]; + char *name; + int linklen; + + linklen = sysfs_readlink(&cxt, NULL, + linkpath, sizeof(linkpath) - 1); + if (linklen < 0) + goto err; + linkpath[linklen] = '\0'; + + stripoff_last_component(linkpath); /* dirname */ + name = stripoff_last_component(linkpath); /* basename */ + if (!name) + goto err; + + if (diskname && len) { + strncpy(diskname, name, len); + diskname[len - 1] = '\0'; + } + + if (diskdevno) { + *diskdevno = sysfs_devname_to_devno(name, NULL); + if (!*diskdevno) + goto err; + } + } + +done: + sysfs_deinit(&cxt); + + DBG(DEBUG_DEVNO, + printf("found entire diskname for devno 0x%04llx %s\n", + (long long) dev, diskname ? diskname : "")); + return 0; +err: + sysfs_deinit(&cxt); + + DBG(DEBUG_DEVNO, + printf("failed to convert 0x%04llx to wholedisk name, errno=%d\n", + (long long) dev, errno)); + return -1; +} + +/* + * Returns 1 if the @major number is associated with @drvname. + */ +int blkid_driver_has_major(const char *drvname, int major) +{ + FILE *f; + char buf[128]; + int match = 0; + + f = fopen(_PATH_PROC_DEVICES, "r"); + if (!f) + return 0; + + while (fgets(buf, sizeof(buf), f)) { /* skip to block dev section */ + if (strncmp("Block devices:\n", buf, sizeof(buf)) == 0) + break; + } + + while (fgets(buf, sizeof(buf), f)) { + unsigned int maj; + char name[64]; + + if (sscanf(buf, "%u %64[^\n ]", &maj, name) != 2) + continue; + + if (maj == major && strcmp(name, drvname) == 0) { + match = 1; + break; + } + } + + fclose(f); + + DBG(DEBUG_DEVNO, printf("major %d %s associated with '%s' driver\n", + major, match ? "is" : "is NOT", drvname)); + return match; +} + + +#ifdef TEST_PROGRAM +int main(int argc, char** argv) +{ + char *devname, *tmp; + char diskname[PATH_MAX]; + int major, minor; + dev_t devno, disk_devno; + const char *errmsg = "Couldn't parse %s: %s\n"; + + blkid_init_debug(DEBUG_ALL); + if ((argc != 2) && (argc != 3)) { + fprintf(stderr, "Usage:\t%s device_number\n\t%s major minor\n" + "Resolve a device number to a device name\n", + argv[0], argv[0]); + exit(1); + } + if (argc == 2) { + devno = strtoul(argv[1], &tmp, 0); + if (*tmp) { + fprintf(stderr, errmsg, "device number", argv[1]); + exit(1); + } + } else { + major = strtoul(argv[1], &tmp, 0); + if (*tmp) { + fprintf(stderr, errmsg, "major number", argv[1]); + exit(1); + } + minor = strtoul(argv[2], &tmp, 0); + if (*tmp) { + fprintf(stderr, errmsg, "minor number", argv[2]); + exit(1); + } + devno = makedev(major, minor); + } + printf("Looking for device 0x%04llx\n", (long long)devno); + devname = blkid_devno_to_devname(devno); + free(devname); + + printf("Looking for whole-device for 0x%04llx\n", (long long)devno); + blkid_devno_to_wholedisk(devno, diskname, sizeof(diskname), &disk_devno); + + return 0; +} +#endif diff --git a/libblkid/src/encode.c b/libblkid/src/encode.c new file mode 100644 index 00000000..03d5f4ef --- /dev/null +++ b/libblkid/src/encode.c @@ -0,0 +1,338 @@ + +/* + * encode.c - string convertion routines (mostly for compatibility with + * udev/volume_id) + * + * Copyright (C) 2008 Kay Sievers + * Copyright (C) 2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include +#include +#include + +#include "blkidP.h" + +#define UDEV_ALLOWED_CHARS_INPUT "/ $%?," + +/** + * SECTION: encode + * @title: Encoding utils + * @short_description: encode strings to safe udev-compatible formats + * + */ + +/* 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 */ +static int 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; +} + +static int replace_whitespace(const char *str, char *to, size_t len) +{ + size_t i, j; + + /* strip trailing whitespace */ + len = strnlen(str, len); + while (len && isspace(str[len-1])) + len--; + + /* strip leading whitespace */ + i = 0; + while (isspace(str[i]) && (i < len)) + i++; + + j = 0; + while (i < len) { + /* substitute multiple whitespace with a single '_' */ + if (isspace(str[i])) { + while (isspace(str[i])) + i++; + to[j++] = '_'; + } + to[j++] = str[i++]; + } + to[j] = '\0'; + return 0; +} + +static int is_whitelisted(char c, const char *white) +{ + if ((c >= '0' && c <= '9') || + (c >= 'A' && c <= 'Z') || + (c >= 'a' && c <= 'z') || + strchr("#+-.:=@_", c) != NULL || + (white != NULL && strchr(white, c) != NULL)) + return 1; + return 0; +} + +/* allow chars in whitelist, plain ascii, hex-escaping and valid utf8 */ +static int replace_chars(char *str, const char *white) +{ + size_t i = 0; + int replaced = 0; + + while (str[i] != '\0') { + int len; + + if (is_whitelisted(str[i], white)) { + i++; + continue; + } + + /* accept hex encoding */ + if (str[i] == '\\' && str[i+1] == 'x') { + i += 2; + continue; + } + + /* accept valid utf8 */ + len = utf8_encoded_valid_unichar(&str[i]); + if (len > 1) { + i += len; + continue; + } + + /* if space is allowed, replace whitespace with ordinary space */ + if (isspace(str[i]) && white != NULL && strchr(white, ' ') != NULL) { + str[i] = ' '; + i++; + replaced++; + continue; + } + + /* everything else is replaced with '_' */ + str[i] = '_'; + i++; + replaced++; + } + return replaced; +} + +size_t blkid_encode_to_utf8(int enc, unsigned char *dest, size_t len, + const unsigned char *src, size_t count) +{ + size_t i, j; + uint16_t c; + + for (j = i = 0; i + 2 <= count; i += 2) { + if (enc == BLKID_ENC_UTF16LE) + c = (src[i+1] << 8) | src[i]; + else /* BLKID_ENC_UTF16BE */ + c = (src[i] << 8) | src[i+1]; + if (c == 0) { + dest[j] = '\0'; + break; + } else if (c < 0x80) { + if (j+1 >= len) + break; + dest[j++] = (uint8_t) c; + } else if (c < 0x800) { + if (j+2 >= len) + break; + dest[j++] = (uint8_t) (0xc0 | (c >> 6)); + dest[j++] = (uint8_t) (0x80 | (c & 0x3f)); + } else { + if (j+3 >= len) + break; + dest[j++] = (uint8_t) (0xe0 | (c >> 12)); + dest[j++] = (uint8_t) (0x80 | ((c >> 6) & 0x3f)); + dest[j++] = (uint8_t) (0x80 | (c & 0x3f)); + } + } + dest[j] = '\0'; + return j; +} + +/** + * blkid_encode_string: + * @str: input string to be encoded + * @str_enc: output string to store the encoded input string + * @len: maximum size of the output 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: 0 if the entire string was copied, non-zero otherwise. + **/ +int blkid_encode_string(const char *str, char *str_enc, size_t len) +{ + size_t i, j; + + if (str == NULL || str_enc == NULL) + return -1; + + for (i = 0, j = 0; str[i] != '\0'; i++) { + int seqlen; + + seqlen = utf8_encoded_valid_unichar(&str[i]); + if (seqlen > 1) { + if (len-j < (size_t)seqlen) + goto err; + memcpy(&str_enc[j], &str[i], seqlen); + j += seqlen; + i += (seqlen-1); + } else if (str[i] == '\\' || !is_whitelisted(str[i], NULL)) { + if (len-j < 4) + goto err; + sprintf(&str_enc[j], "\\x%02x", (unsigned char) str[i]); + j += 4; + } else { + if (len-j < 1) + goto err; + str_enc[j] = str[i]; + j++; + } + if (j+3 >= len) + goto err; + } + if (len-j < 1) + goto err; + str_enc[j] = '\0'; + return 0; +err: + return -1; +} + +/** + * blkid_safe_string: + * @str: input string + * @str_safe: output string + * @len: size of output string + * + * Allows plain ascii, hex-escaping and valid utf8. Replaces all whitespaces + * with '_'. + * + * Returns: 0 on success or -1 in case of error. + */ +int blkid_safe_string(const char *str, char *str_safe, size_t len) +{ + replace_whitespace(str, str_safe, len); + replace_chars(str_safe, UDEV_ALLOWED_CHARS_INPUT); + return 0; +} diff --git a/libblkid/src/evaluate.c b/libblkid/src/evaluate.c new file mode 100644 index 00000000..88c6830e --- /dev/null +++ b/libblkid/src/evaluate.c @@ -0,0 +1,315 @@ +/* + * evaluate.c - very high-level API to evaluate LABELs or UUIDs + * + * Copyright (C) 2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_STAT_H +#include +#endif +#ifdef HAVE_ERRNO_H +#include +#endif +#include +#include + +#include "pathnames.h" +#include "canonicalize.h" + +#include "blkidP.h" + +/** + * SECTION:evaluate + * @title: Tags evaluation + * @short_description: top-level API for LABEL and UUID evaluation. + * + * This API provides very simple and portable way how evaluate LABEL and UUID + * tags. The blkid_evaluate_tag() works on 2.4 and 2.6 systems and on systems + * with or without udev. Currently, the libblkid library supports "udev" and + * "scan" methods. The "udev" method uses udev /dev/disk/by-* symlinks and the + * "scan" method scans all block devices from the /proc/partitions file. The + * evaluation could be controlled by the /etc/blkid.conf config file. The + * default is to try "udev" and then "scan" method. + * + * The blkid_evaluate_tag() also automatically informs udevd when an obsolete + * /dev/disk/by-* symlink is detected. + * + * If you are not sure how translate LABEL or UUID to the device name use this + * API. + */ + +/* returns zero when the device has NAME=value (LABEL/UUID) */ +static int verify_tag(const char *devname, const char *name, const char *value) +{ + blkid_probe pr; + int fd = -1, rc = -1; + size_t len; + const char *data; + int errsv = 0; + + pr = blkid_new_probe(); + if (!pr) + return -1; + + blkid_probe_enable_superblocks(pr, TRUE); + blkid_probe_set_superblocks_flags(pr, + BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID); + + fd = open(devname, O_RDONLY); + if (fd < 0) { + errsv = errno; + goto done; + } + if (blkid_probe_set_device(pr, fd, 0, 0)) + goto done; + rc = blkid_do_safeprobe(pr); + if (rc) + goto done; + rc = blkid_probe_lookup_value(pr, name, &data, &len); + if (!rc) + rc = memcmp(value, data, len); +done: + DBG(DEBUG_EVALUATE, printf("%s: %s verification %s\n", + devname, name, rc == 0 ? "PASS" : "FAILED")); + if (fd >= 0) + close(fd); + blkid_free_probe(pr); + + /* for non-root users we use unverified udev links */ + return errsv == EACCES ? 0 : rc; +} + +/** + * blkid_send_uevent: + * @devname: absolute path to the device + * + * Returns: -1 in case of failure, or 0 on success. + */ +int blkid_send_uevent(const char *devname, const char *action) +{ + char uevent[PATH_MAX]; + struct stat st; + FILE *f; + int rc = -1; + + DBG(DEBUG_EVALUATE, printf("%s: uevent '%s' requested\n", devname, action)); + + if (!devname || !action) + return -1; + if (stat(devname, &st) || !S_ISBLK(st.st_mode)) + return -1; + + snprintf(uevent, sizeof(uevent), "/sys/dev/block/%d:%d/uevent", + major(st.st_rdev), minor(st.st_rdev)); + + f = fopen(uevent, "w"); + if (f) { + rc = 0; + if (fputs(action, f) >= 0) + rc = 0; + fclose(f); + } + DBG(DEBUG_EVALUATE, printf("%s: send uevent %s\n", + uevent, rc == 0 ? "SUCCES" : "FAILED")); + return rc; +} + +static char *evaluate_by_udev(const char *token, const char *value, int uevent) +{ + char dev[PATH_MAX]; + char *path = NULL; + size_t len; + struct stat st; + + DBG(DEBUG_EVALUATE, + printf("evaluating by udev %s=%s\n", token, value)); + + if (!strcmp(token, "UUID")) + strcpy(dev, _PATH_DEV_BYUUID "/"); + else if (!strcmp(token, "LABEL")) + strcpy(dev, _PATH_DEV_BYLABEL "/"); + else { + DBG(DEBUG_EVALUATE, + printf("unsupported token %s\n", token)); + return NULL; /* unsupported tag */ + } + + len = strlen(dev); + if (blkid_encode_string(value, &dev[len], sizeof(dev) - len) != 0) + return NULL; + + DBG(DEBUG_EVALUATE, + printf("expected udev link: %s\n", dev)); + + if (stat(dev, &st)) + goto failed; /* link or device does not exist */ + + if (!S_ISBLK(st.st_mode)) + return NULL; + + path = canonicalize_path(dev); + if (!path) + return NULL; + + if (verify_tag(path, token, value)) + goto failed; + return path; + +failed: + DBG(DEBUG_EVALUATE, printf("failed to evaluate by udev\n")); + + if (uevent && path) + blkid_send_uevent(path, "change"); + free(path); + return NULL; +} + +static char *evaluate_by_scan(const char *token, const char *value, + blkid_cache *cache, struct blkid_config *conf) +{ + blkid_cache c = cache ? *cache : NULL; + char *res; + + DBG(DEBUG_EVALUATE, + printf("evaluating by blkid scan %s=%s\n", token, value)); + + if (!c) { + char *cachefile = blkid_get_cache_filename(conf); + blkid_get_cache(&c, cachefile); + free(cachefile); + } + if (!c) + return NULL; + + res = blkid_get_devname(c, token, value); + + if (cache) + *cache = c; + else + blkid_put_cache(c); + + return res; +} + +/** + * blkid_evaluate_tag: + * @token: token name (e.g "LABEL" or "UUID") or unparsed tag (e.g. "LABEL=foo") + * @value: token data (e.g. "foo") + * @cache: pointer to cache (or NULL when you don't want to re-use the cache) + * + * Returns: allocated string with a device name. + */ +char *blkid_evaluate_tag(const char *token, const char *value, blkid_cache *cache) +{ + struct blkid_config *conf = NULL; + char *t = NULL, *v = NULL; + char *ret = NULL; + int i; + + if (!token) + return NULL; + + if (!cache || !*cache) + blkid_init_debug(0); + + DBG(DEBUG_EVALUATE, + printf("evaluating %s%s%s\n", token, value ? "=" : "", + value ? value : "")); + + if (!value) { + if (!strchr(token, '=')) { + ret = blkid_strdup(token); + goto out; + } + blkid_parse_tag_string(token, &t, &v); + if (!t || !v) + goto out; + token = t; + value = v; + } + + conf = blkid_read_config(NULL); + if (!conf) + goto out; + + for (i = 0; i < conf->nevals; i++) { + if (conf->eval[i] == BLKID_EVAL_UDEV) + ret = evaluate_by_udev(token, value, conf->uevent); + else if (conf->eval[i] == BLKID_EVAL_SCAN) + ret = evaluate_by_scan(token, value, cache, conf); + if (ret) + break; + } + + DBG(DEBUG_EVALUATE, + printf("%s=%s evaluated as %s\n", token, value, ret)); +out: + blkid_free_config(conf); + free(t); + free(v); + return ret; +} + +/** + * blkid_evaluate_spec: + * @spec: unparsed tag (e.g. "LABEL=foo") or path (e.g. /dev/dm-0) + * @cache: pointer to cache (or NULL when you don't want to re-use the cache) + * + * All returned paths are canonicalized, device-mapper paths are converted + * to the /dev/mapper/ format. + * + * Returns: allocated string with a device name. + */ +char *blkid_evaluate_spec(const char *spec, blkid_cache *cache) +{ + char *t = NULL, *v = NULL, *res; + + if (!spec) + return NULL; + + if (strchr(spec, '=') && + blkid_parse_tag_string(spec, &t, &v) != 0) /* parse error */ + return NULL; + + if (v) + res = blkid_evaluate_tag(t, v, cache); + else + res = canonicalize_path(spec); + + free(t); + free(v); + return res; +} + + +#ifdef TEST_PROGRAM +int main(int argc, char *argv[]) +{ + blkid_cache cache = NULL; + char *res; + + if (argc < 2) { + fprintf(stderr, "usage: %s | \n", argv[0]); + return EXIT_FAILURE; + } + + blkid_init_debug(0); + + res = blkid_evaluate_spec(argv[1], &cache); + if (res) + printf("%s\n", res); + if (cache) + blkid_put_cache(cache); + + return res ? EXIT_SUCCESS : EXIT_FAILURE; +} +#endif diff --git a/libblkid/src/getsize.c b/libblkid/src/getsize.c new file mode 100644 index 00000000..abe6ebc9 --- /dev/null +++ b/libblkid/src/getsize.c @@ -0,0 +1,34 @@ +/* + * getsize.c --- get the size of a partition. + * + * Copyright (C) 1995, 1995 Theodore Ts'o. + * Copyright (C) 2010 Karel Zak + * + * %Begin-Header% + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * %End-Header% + */ + +#include +#include +#include + +#include "blkidP.h" + +/** + * blkid_get_dev_size: + * @fd: file descriptor + * + * Returns: size (in bytes) of the block device or size of the regular file or 0. + */ +blkid_loff_t blkid_get_dev_size(int fd) +{ + unsigned long long bytes; + + if (blkdev_get_size(fd, &bytes)) + return 0; + + return bytes; +} + diff --git a/libblkid/src/llseek.c b/libblkid/src/llseek.c new file mode 100644 index 00000000..5bd0e516 --- /dev/null +++ b/libblkid/src/llseek.c @@ -0,0 +1,142 @@ +/* + * llseek.c -- stub calling the llseek system call + * + * Copyright (C) 1994, 1995, 1996, 1997 Theodore Ts'o. + * + * %Begin-Header% + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * %End-Header% + */ + +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE + +#if HAVE_SYS_TYPES_H +#include +#endif + +#if HAVE_ERRNO_H +#include +#endif +#if HAVE_UNISTD_H +#include +#endif +#ifdef __MSDOS__ +#include +#endif + +#include "blkidP.h" + +#ifdef __linux__ + +#if defined(HAVE_LSEEK64) && defined(HAVE_LSEEK64_PROTOTYPE) + +#define my_llseek lseek64 + +#elif defined(HAVE_LLSEEK) +#include + +#ifndef HAVE_LLSEEK_PROTOTYPE +extern long long llseek(int fd, long long offset, int origin); +#endif + +#define my_llseek llseek + +#else /* ! HAVE_LLSEEK */ + +#if SIZEOF_LONG == SIZEOF_LONG_LONG + +#define llseek lseek + +#else /* SIZEOF_LONG != SIZEOF_LONG_LONG */ + +#include + +#ifndef __NR__llseek +#define __NR__llseek 140 +#endif + +#ifndef __i386__ +static int _llseek(unsigned int, unsigned long, unsigned long, + blkid_loff_t *, unsigned int); + +static _syscall5(int, _llseek, unsigned int, fd, unsigned long, offset_high, + unsigned long, offset_low, blkid_loff_t *, result, + unsigned int, origin) +#endif + +static blkid_loff_t my_llseek(int fd, blkid_loff_t offset, int origin) +{ + blkid_loff_t result; + int retval; + +#ifndef __i386__ + retval = _llseek(fd, ((unsigned long long) offset) >> 32, + ((unsigned long long)offset) & 0xffffffff, + &result, origin); +#else + retval = syscall(__NR__llseek, fd, ((unsigned long long) offset) >> 32, + ((unsigned long long)offset) & 0xffffffff, + &result, origin); +#endif + return (retval == -1 ? (blkid_loff_t) retval : result); +} + +#endif /* __alpha__ || __ia64__ */ + +#endif /* HAVE_LLSEEK */ + +blkid_loff_t blkid_llseek(int fd, blkid_loff_t offset, int whence) +{ + blkid_loff_t result; + static int do_compat = 0; + + if ((sizeof(off_t) >= sizeof(blkid_loff_t)) || + (offset < ((blkid_loff_t) 1 << ((sizeof(off_t)*8) -1)))) + return lseek(fd, (off_t) offset, whence); + + if (do_compat) { + errno = EOVERFLOW; + return -1; + } + + result = my_llseek(fd, offset, whence); + if (result == -1 && errno == ENOSYS) { + /* + * Just in case this code runs on top of an old kernel + * which does not support the llseek system call + */ + do_compat++; + errno = EOVERFLOW; + } + return result; +} + +#else /* !linux */ + +#ifndef EOVERFLOW +#ifdef EXT2_ET_INVALID_ARGUMENT +#define EOVERFLOW EXT2_ET_INVALID_ARGUMENT +#else +#define EOVERFLOW 112 +#endif +#endif + +blkid_loff_t blkid_llseek(int fd, blkid_loff_t offset, int origin) +{ +#if defined(HAVE_LSEEK64) && defined(HAVE_LSEEK64_PROTOTYPE) + return lseek64 (fd, offset, origin); +#else + if ((sizeof(off_t) < sizeof(blkid_loff_t)) && + (offset >= ((blkid_loff_t) 1 << ((sizeof(off_t)*8) - 1)))) { + errno = EOVERFLOW; + return -1; + } + return lseek(fd, (off_t) offset, origin); +#endif +} + +#endif /* linux */ + + diff --git a/libblkid/src/partitions/Makefile.am b/libblkid/src/partitions/Makefile.am new file mode 100644 index 00000000..f617389d --- /dev/null +++ b/libblkid/src/partitions/Makefile.am @@ -0,0 +1,22 @@ +include $(top_srcdir)/config/include-Makefile.am + +AM_CPPFLAGS += -I$(ul_libblkid_incdir) -I$(ul_libblkid_srcdir) +libblkid_partitions_la_LIBADD = + +noinst_LTLIBRARIES = libblkid_partitions.la +libblkid_partitions_la_SOURCES = partitions.c \ + partitions.h \ + blkid_parttypes.h \ + aix.c \ + aix.h \ + bsd.c \ + unixware.c \ + solaris_x86.c \ + sun.c \ + sgi.c \ + mac.c \ + dos.c \ + dos.h \ + minix.c \ + ultrix.c \ + gpt.c diff --git a/libblkid/src/partitions/aix.c b/libblkid/src/partitions/aix.c new file mode 100644 index 00000000..be0ad2b4 --- /dev/null +++ b/libblkid/src/partitions/aix.c @@ -0,0 +1,58 @@ +/* + * aix partitions + * + * Copyright (C) 2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include + +#include "partitions.h" +#include "aix.h" + +static int probe_aix_pt(blkid_probe pr, const struct blkid_idmag *mag) +{ + blkid_partlist ls; + blkid_parttable tab; + + if (blkid_partitions_need_typeonly(pr)) + /* caller does not ask for details about partitions */ + return 0; + + ls = blkid_probe_get_partlist(pr); + if (!ls) + goto err; + + tab = blkid_partlist_new_parttable(ls, "aix", 0); + if (!tab) + goto err; + + return 0; +err: + return -1; +} + +/* + * We know nothing about AIX on-disk structures. Everything what we know is the + * magic number at begin of the disk. + * + * Note, Linux kernel is tring to be smart and AIX signature is ignored when + * there is a valid DOS partitions table. We don't support such behaviour. All + * fdisk-like programs has to properly wipe the fist sector. Everything other + * is a bug. + */ +const struct blkid_idinfo aix_pt_idinfo = +{ + .name = "aix", + .probefunc = probe_aix_pt, + .magics = + { + { .magic = BLKID_AIX_MAGIC_STRING, .len = BLKID_AIX_MAGIC_STRLEN }, + { NULL } + } +}; + diff --git a/libblkid/src/partitions/aix.h b/libblkid/src/partitions/aix.h new file mode 100644 index 00000000..f767c5a3 --- /dev/null +++ b/libblkid/src/partitions/aix.h @@ -0,0 +1,7 @@ +#ifndef BLKID_PARTITIONS_AIX_H +#define BLKID_PARTITIONS_AIX_H + +#define BLKID_AIX_MAGIC_STRING "\xC9\xC2\xD4\xC1" +#define BLKID_AIX_MAGIC_STRLEN (sizeof(BLKID_AIX_MAGIC_STRING) - 1) + +#endif diff --git a/libblkid/src/partitions/blkid_parttypes.h b/libblkid/src/partitions/blkid_parttypes.h new file mode 100644 index 00000000..707e53d9 --- /dev/null +++ b/libblkid/src/partitions/blkid_parttypes.h @@ -0,0 +1,121 @@ +/* + * Partition types + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* Note, _L32M means <32M (less), for example FAT16_L32M */ + +enum { + BLKID_EMPTY_PARTITION = 0x00, + BLKID_FAT12_PARTITION = 0x01, + BLKID_XENIX_ROOT_PARTITION = 0x02, + BLKID_XENIX_USR_PARTITION = 0x03, + BLKID_FAT16_LESS32M_PARTITION = 0x04, + BLKID_DOS_EXTENDED_PARTITION = 0x05, + BLKID_FAT16_PARTITION = 0x06, /* DOS 16-bit >=32M */ + BLKID_HPFS_NTFS_PARTITION = 0x07, /* OS/2 IFS, eg, HPFS or NTFS or QNX */ + BLKID_AIX_PARTITION = 0x08, /* AIX boot (AIX -- PS/2 port) or SplitDrive */ + BLKID_AIX_BOOTABLE_PARTITION = 0x09, /* AIX data or Coherent */ + BLKID_OS2_BOOTMNGR_PARTITION = 0x0a, /* OS/2 Boot Manager */ + BLKID_W95_FAT32_PARTITION = 0x0b, + BLKID_W95_FAT32_LBA_PARTITION = 0x0c, /* LBA really is `Extended Int 13h' */ + BLKID_W95_FAT16_LBA_PARTITION = 0x0e, + BLKID_W95_EXTENDED_PARTITION = 0x0f, + BLKID_OPUS_PARTITION = 0x10, + BLKID_HIDDEN_FAT12_PARTITION = 0x11, + BLKID_COMPAQ_DIAGNOSTICS_PARTITION = 0x12, + BLKID_HIDDEN_FAT16_L32M_PARTITION = 0x14, + BLKID_HIDDEN_FAT16_PARTITION = 0x16, + BLKID_HIDDEN_HPFS_NTFS_PARTITION = 0x17, + BLKID_AST_SMARTSLEEP_PARTITION = 0x18, + BLKID_HIDDEN_W95_FAT32_PARTITION = 0x1b, + BLKID_HIDDEN_W95_FAT32LBA_PARTITION = 0x1c, + BLKID_HIDDEN_W95_FAT16LBA_PARTITION = 0x1e, + BLKID_NEC_DOS_PARTITION = 0x24, + BLKID_PLAN9_PARTITION = 0x39, + BLKID_PARTITIONMAGIC_PARTITION = 0x3c, + BLKID_VENIX80286_PARTITION = 0x40, + BLKID_PPC_PREP_BOOT_PARTITION = 0x41, + BLKID_SFS_PARTITION = 0x42, + BLKID_QNX_4X_PARTITION = 0x4d, + BLKID_QNX_4X_2ND_PARTITION = 0x4e, + BLKID_QNX_4X_3RD_PARTITION = 0x4f, + BLKID_DM_PARTITION = 0x50, + BLKID_DM6_AUX1_PARTITION = 0x51, /* (or Novell) */ + BLKID_CPM_PARTITION = 0x52, /* CP/M or Microport SysV/AT */ + BLKID_DM6_AUX3_PARTITION = 0x53, + BLKID_DM6_PARTITION = 0x54, + BLKID_EZ_DRIVE_PARTITION = 0x55, + BLKID_GOLDEN_BOW_PARTITION = 0x56, + BLKID_PRIAM_EDISK_PARTITION = 0x5c, + BLKID_SPEEDSTOR_PARTITION = 0x61, + BLKID_GNU_HURD_PARTITION = 0x63, /* GNU HURD or Mach or Sys V/386 (such as ISC UNIX) */ + BLKID_UNIXWARE_PARTITION = BLKID_GNU_HURD_PARTITION, + BLKID_NETWARE_286_PARTITION = 0x64, + BLKID_NETWARE_386_PARTITION = 0x65, + BLKID_DISKSECURE_MULTIBOOT_PARTITION = 0x70, + BLKID_PC_IX_PARTITION = 0x75, + BLKID_OLD_MINIX_PARTITION = 0x80, /* Minix 1.4a and earlier */ + BLKID_MINIX_PARTITION = 0x81, /* Minix 1.4b and later */ + BLKID_LINUX_SWAP_PARTITION = 0x82, + BLKID_SOLARIS_X86_PARTITION = BLKID_LINUX_SWAP_PARTITION, + BLKID_LINUX_DATA_PARTITION = 0x83, + BLKID_OS2_HIDDEN_DRIVE_PARTITION = 0x84, + BLKID_LINUX_EXTENDED_PARTITION = 0x85, + BLKID_NTFS_VOL_SET1_PARTITION = 0x86, + BLKID_NTFS_VOL_SET2_PARTITION = 0x87, + BLKID_LINUX_PLAINTEXT_PARTITION = 0x88, + BLKID_LINUX_LVM_PARTITION = 0x8e, + BLKID_AMOEBA_PARTITION = 0x93, + BLKID_AMOEBA_BBT_PARTITION = 0x94, /* (bad block table) */ + BLKID_BSD_OS_PARTITION = 0x9f, /* BSDI */ + BLKID_THINKPAD_HIBERNATION_PARTITION = 0xa0, + BLKID_FREEBSD_PARTITION = 0xa5, /* various BSD flavours */ + BLKID_OPENBSD_PARTITION = 0xa6, + BLKID_NEXTSTEP_PARTITION = 0xa7, + BLKID_DARWIN_UFS_PARTITION = 0xa8, + BLKID_NETBSD_PARTITION = 0xa9, + BLKID_DARWIN_BOOT_PARTITION = 0xab, + BLKID_HFS_HFS_PARTITION = 0xaf, + BLKID_BSDI_FS_PARTITION = 0xb7, + BLKID_BSDI_SWAP_PARTITION = 0xb8, + BLKID_BOOTWIZARD_HIDDEN_PARTITION = 0xbb, + BLKID_SOLARIS_BOOT_PARTITION = 0xbe, + BLKID_SOLARIS_PARTITION = 0xbf, + BLKID_DRDOS_FAT12_PARTITION = 0xc1, + BLKID_DRDOS_FAT16_L32M_PARTITION = 0xc4, + BLKID_DRDOS_FAT16_PARTITION = 0xc6, + BLKID_SYRINX_PARTITION = 0xc7, + BLKID_NONFS_DATA_PARTITION = 0xda, + BLKID_CPM_CTOS_PARTITION = 0xdb, /* CP/M or Concurrent CP/M or Concurrent DOS or CTOS */ + BLKID_DELL_UTILITY_PARTITION = 0xde, /* Dell PowerEdge Server utilities */ + BLKID_BOOTIT_PARTITION = 0xdf, /* BootIt EMBRM */ + BLKID_DOS_ACCESS_PARTITION = 0xe1, /* DOS access or SpeedStor 12-bit FAT extended partition */ + BLKID_DOS_RO_PARTITION = 0xe3, /* DOS R/O or SpeedStor */ + BLKID_SPEEDSTOR_EXTENDED_PARTITION = 0xe4, /* SpeedStor 16-bit FAT extended partition < 1024 cyl. */ + BLKID_BEOS_FS_PARTITION = 0xeb, + BLKID_GPT_PARTITION = 0xee, /* Intel EFI GUID Partition Table */ + BLKID_EFI_SYSTEM_PARTITION = 0xef, /* Intel EFI System Partition */ + BLKID_LINUX_PARISC_BOOT_PARTITION = 0xf0, /* Linux/PA-RISC boot loader */ + BLKID_SPEEDSTOR1_PARTITION = 0xf1, + BLKID_SPEEDSTOR2_PARTITION = 0xf4, /* SpeedStor large partition */ + BLKID_DOS_SECONDARY_PARTITION = 0xf2, /* DOS 3.3+ secondary */ + BLKID_VMWARE_VMFS_PARTITION = 0xfb, + BLKID_VMWARE_VMKCORE_PARTITION = 0xfc, /* VMware kernel dump partition */ + BLKID_LINUX_RAID_PARTITION = 0xfd, /* New (2.2.x) raid partition with autodetect using persistent superblock */ + BLKID_LANSTEP_PARTITION = 0xfe, /* SpeedStor >1024 cyl. or LANstep */ + BLKID_XENIX_BBT_PARTITION = 0xff, /* Xenix Bad Block Table */ +}; diff --git a/libblkid/src/partitions/bsd.c b/libblkid/src/partitions/bsd.c new file mode 100644 index 00000000..ee15ad2f --- /dev/null +++ b/libblkid/src/partitions/bsd.c @@ -0,0 +1,243 @@ +/* + * BSD/OSF partition parsing code + * + * Copyright (C) 2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * + * Inspired by fdisk, partx, Linux kernel, libparted and openbsd header files. + */ +#include +#include +#include +#include + +#include "partitions.h" + +#define BSD_MAXPARTITIONS 16 +#define BSD_FS_UNUSED 0 + +struct bsd_disklabel { + uint32_t d_magic; /* the magic number */ + int16_t d_type; /* drive type */ + int16_t d_subtype; /* controller/d_type specific */ + char d_typename[16]; /* type name, e.g. "eagle" */ + char d_packname[16]; /* pack identifier */ + + /* disk geometry: */ + uint32_t d_secsize; /* # of bytes per sector */ + uint32_t d_nsectors; /* # of data sectors per track */ + uint32_t d_ntracks; /* # of tracks per cylinder */ + uint32_t d_ncylinders; /* # of data cylinders per unit */ + uint32_t d_secpercyl; /* # of data sectors per cylinder */ + uint32_t d_secperunit; /* # of data sectors per unit */ + + /* + * Spares (bad sector replacements) below + * are not counted in d_nsectors or d_secpercyl. + * Spare sectors are assumed to be physical sectors + * which occupy space at the end of each track and/or cylinder. + */ + uint16_t d_sparespertrack; /* # of spare sectors per track */ + uint16_t d_sparespercyl; /* # of spare sectors per cylinder */ + + /* + * Alternate cylinders include maintenance, replacement, + * configuration description areas, etc. + */ + uint32_t d_acylinders; /* # of alt. cylinders per unit */ + + /* hardware characteristics: */ + /* + * d_interleave, d_trackskew and d_cylskew describe perturbations + * in the media format used to compensate for a slow controller. + * Interleave is physical sector interleave, set up by the formatter + * or controller when formatting. When interleaving is in use, + * logically adjacent sectors are not physically contiguous, + * but instead are separated by some number of sectors. + * It is specified as the ratio of physical sectors traversed + * per logical sector. Thus an interleave of 1:1 implies contiguous + * layout, while 2:1 implies that logical sector 0 is separated + * by one sector from logical sector 1. + * d_trackskew is the offset of sector 0 on track N + * relative to sector 0 on track N-1 on the same cylinder. + * Finally, d_cylskew is the offset of sector 0 on cylinder N + * relative to sector 0 on cylinder N-1. + */ + uint16_t d_rpm; /* rotational speed */ + uint16_t d_interleave; /* hardware sector interleave */ + uint16_t d_trackskew; /* sector 0 skew, per track */ + uint16_t d_cylskew; /* sector 0 skew, per cylinder */ + uint32_t d_headswitch; /* head switch time, usec */ + uint32_t d_trkseek; /* track-to-track seek, usec */ + uint32_t d_flags; /* generic flags */ + uint32_t d_drivedata[5]; /* drive-type specific information */ + uint32_t d_spare[5]; /* reserved for future use */ + uint32_t d_magic2; /* the magic number (again) */ + uint16_t d_checksum; /* xor of data incl. partitions */ + + /* filesystem and partition information: */ + uint16_t d_npartitions; /* number of partitions in following */ + uint32_t d_bbsize; /* size of boot area at sn0, bytes */ + uint32_t d_sbsize; /* max size of fs superblock, bytes */ + + struct bsd_partition { /* the partition table */ + uint32_t p_size; /* number of sectors in partition */ + uint32_t p_offset; /* starting sector */ + uint32_t p_fsize; /* filesystem basic fragment size */ + uint8_t p_fstype; /* filesystem type, see below */ + uint8_t p_frag; /* filesystem fragments per block */ + uint16_t p_cpg; /* filesystem cylinders per group */ + } __attribute__((packed)) d_partitions[BSD_MAXPARTITIONS]; /* actually may be more */ +} __attribute__((packed)); + + +/* Returns 'blkid_idmag' in 512-sectors */ +#define BLKID_MAG_SECTOR(_mag) (((_mag)->kboff * 2) + ((_mag)->sboff >> 9)) + +/* Returns 'blkid_idmag' in bytes */ +#define BLKID_MAG_OFFSET(_mag) ((_mag)->kboff >> 10) + ((_mag)->sboff) + +/* Returns 'blkid_idmag' offset in bytes within the last sector */ +#define BLKID_MAG_LASTOFFSET(_mag) \ + (BLKID_MAG_OFFSET(_mag) - (BLKID_MAG_SECTOR(_mag) << 9)) + +static int probe_bsd_pt(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct bsd_disklabel *l; + struct bsd_partition *p; + const char *name = "bsd" ; + blkid_parttable tab = NULL; + blkid_partition parent; + blkid_partlist ls; + int i, nparts = BSD_MAXPARTITIONS; + unsigned char *data; + + if (blkid_partitions_need_typeonly(pr)) + /* caller does not ask for details about partitions */ + return 0; + + data = blkid_probe_get_sector(pr, BLKID_MAG_SECTOR(mag)); + if (!data) + goto nothing; + + l = (struct bsd_disklabel *) data + BLKID_MAG_LASTOFFSET(mag); + + ls = blkid_probe_get_partlist(pr); + if (!ls) + goto err; + + /* try to determine the real type of BSD system according to + * (parental) primary partition */ + parent = blkid_partlist_get_parent(ls); + if (parent) { + switch(blkid_partition_get_type(parent)) { + case BLKID_FREEBSD_PARTITION: + name = "freebsd"; + break; + case BLKID_NETBSD_PARTITION: + name = "netbsd"; + break; + case BLKID_OPENBSD_PARTITION: + name = "openbsd"; + break; + default: + DBG(DEBUG_LOWPROBE, printf( + "WARNING: BSD label detected on unknown (0x%x) " + "primary partition\n", + blkid_partition_get_type(parent))); + break; + } + } + + tab = blkid_partlist_new_parttable(ls, name, BLKID_MAG_OFFSET(mag)); + if (!tab) + goto err; + + if (le16_to_cpu(l->d_npartitions) < BSD_MAXPARTITIONS) + nparts = le16_to_cpu(l->d_npartitions); + + else if (le16_to_cpu(l->d_npartitions) > BSD_MAXPARTITIONS) + DBG(DEBUG_LOWPROBE, printf( + "WARNING: ignore %d more BSD partitions\n", + le16_to_cpu(l->d_npartitions) - BSD_MAXPARTITIONS)); + + for (i = 0, p = l->d_partitions; i < nparts; i++, p++) { + blkid_partition par; + uint32_t start, size; + + /* TODO: in fdisk-mode returns all non-zero (p_size) partitions */ + if (p->p_fstype == BSD_FS_UNUSED) + continue; + + start = le32_to_cpu(p->p_offset); + size = le32_to_cpu(p->p_size); + + if (parent && !blkid_is_nested_dimension(parent, start, size)) { + DBG(DEBUG_LOWPROBE, printf( + "WARNING: BSD partition (%d) overflow " + "detected, ignore\n", i)); + continue; + } + + par = blkid_partlist_add_partition(ls, tab, start, size); + if (!par) + goto err; + + blkid_partition_set_type(par, p->p_fstype); + } + + return 0; + +nothing: + return 1; +err: + return -1; +} + + +/* + * All BSD variants use the same magic string (little-endian), + * and the same disklabel. + * + * The difference between {Free,Open,...}BSD is in the (parental) + * primary partition type. + * + * See also: http://en.wikipedia.org/wiki/BSD_disklabel + * + * The location of BSD disk label is architecture specific and in defined by + * LABELSECTOR and LABELOFFSET macros in the disklabel.h file. The location + * also depends on BSD variant, FreeBSD uses only one location, NetBSD and + * OpenBSD are more creative... + * + * The basic overview: + * + * arch | LABELSECTOR | LABELOFFSET + * ------------------------+-------------+------------ + * amd64 arm hppa hppa64 | | + * i386, macppc, mvmeppc | 1 | 0 + * sgi, aviion, sh, socppc | | + * ------------------------+-------------+------------ + * alpha luna88k mac68k | 0 | 64 + * sparc(OpenBSD) vax | | + * ------------------------+-------------+------------ + * spark64 sparc(NetBSD) | 0 | 128 + * ------------------------+-------------+------------ + * + * ...and more (see http://fxr.watson.org/fxr/ident?v=NETBSD;i=LABELSECTOR) + * + */ +const struct blkid_idinfo bsd_pt_idinfo = +{ + .name = "bsd", + .probefunc = probe_bsd_pt, + .magics = + { + { .magic = "\x57\x45\x56\x82", .len = 4, .sboff = 512 }, + { .magic = "\x57\x45\x56\x82", .len = 4, .sboff = 64 }, + { .magic = "\x57\x45\x56\x82", .len = 4, .sboff = 128 }, + { NULL } + } +}; + diff --git a/libblkid/src/partitions/dos.c b/libblkid/src/partitions/dos.c new file mode 100644 index 00000000..72ac7788 --- /dev/null +++ b/libblkid/src/partitions/dos.c @@ -0,0 +1,287 @@ +/* + * MS-DOS partition parsing code + * + * Copyright (C) 2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * + * Inspired by fdisk, partx, Linux kernel and libparted. + */ +#include +#include +#include +#include + +#include "partitions.h" +#include "dos.h" +#include "aix.h" + +/* see superblocks/vfat.c */ +extern int blkid_probe_is_vfat(blkid_probe pr); + +static const struct dos_subtypes { + unsigned char type; + const struct blkid_idinfo *id; +} dos_nested[] = { + { BLKID_FREEBSD_PARTITION, &bsd_pt_idinfo }, + { BLKID_NETBSD_PARTITION, &bsd_pt_idinfo }, + { BLKID_OPENBSD_PARTITION, &bsd_pt_idinfo }, + { BLKID_UNIXWARE_PARTITION, &unixware_pt_idinfo }, + { BLKID_SOLARIS_X86_PARTITION, &solaris_x86_pt_idinfo }, + { BLKID_MINIX_PARTITION, &minix_pt_idinfo } +}; + +static inline int is_extended(struct dos_partition *p) +{ + return (p->sys_type == BLKID_DOS_EXTENDED_PARTITION || + p->sys_type == BLKID_W95_EXTENDED_PARTITION || + p->sys_type == BLKID_LINUX_EXTENDED_PARTITION); +} + +static int parse_dos_extended(blkid_probe pr, blkid_parttable tab, + uint32_t ex_start, uint32_t ex_size, int ssf) +{ + blkid_partlist ls = blkid_probe_get_partlist(pr); + uint32_t cur_start = ex_start, cur_size = ex_size; + unsigned char *data; + int ct_nodata = 0; /* count ext.partitions without data partitions */ + int i; + + while (1) { + struct dos_partition *p, *p0; + uint32_t start, size; + + if (++ct_nodata > 100) + return 0; + data = blkid_probe_get_sector(pr, cur_start); + if (!data) + goto leave; /* malformed partition? */ + + if (!is_valid_mbr_signature(data)) + goto leave; + + p0 = (struct dos_partition *) (data + BLKID_MSDOS_PT_OFFSET); + + /* Usually, the first entry is the real data partition, + * the 2nd entry is the next extended partition, or empty, + * and the 3rd and 4th entries are unused. + * However, DRDOS sometimes has the extended partition as + * the first entry (when the data partition is empty), + * and OS/2 seems to use all four entries. + * -- Linux kernel fs/partitions/dos.c + * + * See also http://en.wikipedia.org/wiki/Extended_boot_record + */ + + /* Parse data partition */ + for (p = p0, i = 0; i < 4; i++, p++) { + uint32_t abs_start; + blkid_partition par; + + /* the start is relative to the parental ext.partition */ + start = dos_partition_start(p) * ssf; + size = dos_partition_size(p) * ssf; + abs_start = cur_start + start; /* absolute start */ + + if (!size || is_extended(p)) + continue; + if (i >= 2) { + /* extra checks to detect real data on + * 3rd and 4th entries */ + if (start + size > cur_size) + continue; + if (abs_start < ex_start) + continue; + if (abs_start + size > ex_start + ex_size) + continue; + } + + par = blkid_partlist_add_partition(ls, tab, abs_start, size); + if (!par) + goto err; + + blkid_partition_set_type(par, p->sys_type); + blkid_partition_set_flags(par, p->boot_ind); + ct_nodata = 0; + } + /* The first nested ext.partition should be a link to the next + * logical partition. Everything other (recursive ext.partitions) + * is junk. + */ + for (p = p0, i = 0; i < 4; i++, p++) { + start = dos_partition_start(p) * ssf; + size = dos_partition_size(p) * ssf; + + if (size && is_extended(p)) + break; + } + if (i == 4) + goto leave; + + cur_start = ex_start + start; + cur_size = size; + } +leave: + return 0; +err: + return -1; +} + +static int probe_dos_pt(blkid_probe pr, const struct blkid_idmag *mag) +{ + int i; + int ssf; + blkid_parttable tab = NULL; + blkid_partlist ls; + struct dos_partition *p0, *p; + unsigned char *data; + uint32_t start, size; + + data = blkid_probe_get_sector(pr, 0); + if (!data) + goto nothing; + + /* ignore disks with AIX magic number -- for more details see aix.c */ + if (memcmp(data, BLKID_AIX_MAGIC_STRING, BLKID_AIX_MAGIC_STRLEN) == 0) + goto nothing; + + /* + * Now that the 55aa signature is present, this is probably + * either the boot sector of a FAT filesystem or a DOS-type + * partition table. + */ + if (blkid_probe_is_vfat(pr)) { + DBG(DEBUG_LOWPROBE, printf("probably FAT -- ignore\n")); + goto nothing; + } + + p0 = (struct dos_partition *) (data + BLKID_MSDOS_PT_OFFSET); + + /* + * Reject PT where boot indicator is not 0 or 0x80. + */ + for (p = p0, i = 0; i < 4; i++, p++) + if (p->boot_ind != 0 && p->boot_ind != 0x80) { + DBG(DEBUG_LOWPROBE, printf("missing boot indicator -- ignore\n")); + goto nothing; + } + + /* + * GPT uses valid MBR + */ + for (p = p0, i = 0; i < 4; i++, p++) { + if (p->sys_type == BLKID_GPT_PARTITION) { + DBG(DEBUG_LOWPROBE, printf("probably GPT -- ignore\n")); + goto nothing; + } + } + + blkid_probe_use_wiper(pr, BLKID_MSDOS_PT_OFFSET, + 512 - BLKID_MSDOS_PT_OFFSET); + + /* + * Well, all checks pass, it's MS-DOS partiton table + */ + if (blkid_partitions_need_typeonly(pr)) + /* caller does not ask for details about partitions */ + return 0; + + ls = blkid_probe_get_partlist(pr); + + /* sector size factor (the start and size are in the real sectors, but + * we need to convert all sizes to 512 logical sectors + */ + ssf = blkid_probe_get_sectorsize(pr) / 512; + + /* allocate a new partition table */ + tab = blkid_partlist_new_parttable(ls, "dos", BLKID_MSDOS_PT_OFFSET); + if (!tab) + goto err; + + /* Parse primary partitions */ + for (p = p0, i = 0; i < 4; i++, p++) { + blkid_partition par; + + start = dos_partition_start(p) * ssf; + size = dos_partition_size(p) * ssf; + + if (!size) { + /* Linux kernel ignores empty partitions, but partno for + * the empty primary partitions is not reused */ + blkid_partlist_increment_partno(ls); + continue; + } + par = blkid_partlist_add_partition(ls, tab, start, size); + if (!par) + goto err; + + blkid_partition_set_type(par, p->sys_type); + blkid_partition_set_flags(par, p->boot_ind); + } + + /* Linux uses partition numbers greater than 4 + * for all logical partition and all nested partition tables (bsd, ..) + */ + blkid_partlist_set_partno(ls, 5); + + /* Parse logical partitions */ + for (p = p0, i = 0; i < 4; i++, p++) { + start = dos_partition_start(p) * ssf; + size = dos_partition_size(p) * ssf; + + if (!size) + continue; + if (is_extended(p) && + parse_dos_extended(pr, tab, start, size, ssf) == -1) + goto err; + } + + /* Parse subtypes (nested partitions) on large disks */ + if (!blkid_probe_is_tiny(pr)) { + for (p = p0, i = 0; i < 4; i++, p++) { + int n; + + if (!dos_partition_size(p) || is_extended(p)) + continue; + + for (n = 0; n < ARRAY_SIZE(dos_nested); n++) { + if (dos_nested[n].type != p->sys_type) + continue; + + if (blkid_partitions_do_subprobe(pr, + blkid_partlist_get_partition(ls, i), + dos_nested[n].id) == -1) + goto err; + break; + } + } + } + return 0; + +nothing: + return 1; +err: + return -1; +} + + +const struct blkid_idinfo dos_pt_idinfo = +{ + .name = "dos", + .probefunc = probe_dos_pt, + .magics = + { + /* DOS master boot sector: + * + * 0 | Code Area + * 440 | Optional Disk signature + * 446 | Partition table + * 510 | 0x55 + * 511 | 0xAA + */ + { .magic = "\x55\xAA", .len = 2, .sboff = 510 }, + { NULL } + } +}; + diff --git a/libblkid/src/partitions/dos.h b/libblkid/src/partitions/dos.h new file mode 100644 index 00000000..130aa011 --- /dev/null +++ b/libblkid/src/partitions/dos.h @@ -0,0 +1,36 @@ +#ifndef BLKID_PARTITIONS_DOS_H +#define BLKID_PARTITIONS_DOS_H + +struct dos_partition { + unsigned char boot_ind; /* 0x80 - active */ + unsigned char bh, bs, bc; /* begin CHS */ + unsigned char sys_type; + unsigned char eh, es, ec; /* end CHS */ + unsigned char start_sect[4]; + unsigned char nr_sects[4]; +} __attribute__((packed)); + +#define BLKID_MSDOS_PT_OFFSET 0x1be + +/* assemble badly aligned little endian integer */ +static inline unsigned int assemble4le(unsigned char *p) +{ + return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); +} + +static inline unsigned int dos_partition_start(struct dos_partition *p) +{ + return assemble4le(&(p->start_sect[0])); +} + +static inline unsigned int dos_partition_size(struct dos_partition *p) +{ + return assemble4le(&(p->nr_sects[0])); +} + +static inline int is_valid_mbr_signature(const unsigned char *mbr) +{ + return mbr[510] == 0x55 && mbr[511] == 0xaa ? 1 : 0; +} + +#endif /* BLKID_PARTITIONS_DOS_H */ diff --git a/libblkid/src/partitions/gpt.c b/libblkid/src/partitions/gpt.c new file mode 100644 index 00000000..9281a894 --- /dev/null +++ b/libblkid/src/partitions/gpt.c @@ -0,0 +1,401 @@ +/* + * EFI GPT partition parsing code + * + * Copyright (C) 2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * + * This code is not copy & past from any other implementation. + * + * For more information about GPT start your study at: + * http://en.wikipedia.org/wiki/GUID_Partition_Table + * http://technet.microsoft.com/en-us/library/cc739412(WS.10).aspx + */ +#include +#include +#include +#include +#include + +#include "partitions.h" +#include "crc32.h" +#include "dos.h" + +#define GPT_PRIMARY_LBA 1 + +/* Signature - “EFI PART” */ +#define GPT_HEADER_SIGNATURE 0x5452415020494645ULL + +/* basic types */ +typedef uint16_t efi_char16_t; + +/* UUID */ +typedef struct { + uint32_t time_low; + uint16_t time_mid; + uint16_t time_hi_and_version; + uint8_t clock_seq_hi; + uint8_t clock_seq_low; + uint8_t node[6]; +} efi_guid_t; + + +#define GPT_UNUSED_ENTRY_GUID \ + ((efi_guid_t) { 0x00000000, 0x0000, 0x0000, 0x00, 0x00, \ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}) +struct gpt_header { + uint64_t signature; /* "EFI PART" */ + uint32_t revision; + uint32_t header_size; /* usualy 92 bytes */ + uint32_t header_crc32; /* checksum of header with this + * field zeroed during calculation */ + uint32_t reserved1; + + uint64_t my_lba; /* location of this header copy */ + uint64_t alternate_lba; /* location of the other header copy */ + uint64_t first_usable_lba; /* lirst usable LBA for partitions */ + uint64_t last_usable_lba; /* last usable LBA for partitions */ + + efi_guid_t disk_guid; /* disk UUID */ + + uint64_t partition_entries_lba; /* always 2 in primary header copy */ + uint32_t num_partition_entries; + uint32_t sizeof_partition_entry; + uint32_t partition_entry_array_crc32; + + /* + * The rest of the block is reserved by UEFI and must be zero. EFI + * standard handles this by: + * + * uint8_t reserved2[ BLKSSZGET - 92 ]; + * + * This definition is useless in practice. It is necessary to read + * whole block from the device rather than sizeof(struct gpt_header) + * only. + */ +} __attribute__ ((packed)); + +/*** not used +struct gpt_entry_attributes { + uint64_t required_to_function:1; + uint64_t reserved:47; + uint64_t type_guid_specific:16; +} __attribute__ ((packed)); +***/ + +struct gpt_entry { + efi_guid_t partition_type_guid; /* type UUID */ + efi_guid_t unique_partition_guid; /* partition UUID */ + uint64_t starting_lba; + uint64_t ending_lba; + + /*struct gpt_entry_attributes attributes;*/ + + uint64_t attributes; + + efi_char16_t partition_name[72 / sizeof(efi_char16_t)]; /* UTF-16LE string*/ +} __attribute__ ((packed)); + + +/* + * EFI uses crc32 with ~0 seed and xor's with ~0 at the end. + */ +static inline uint32_t count_crc32(const unsigned char *buf, size_t len) +{ + return (crc32(~0L, buf, len) ^ ~0L); +} + +static inline unsigned char *get_lba_buffer(blkid_probe pr, + uint64_t lba, size_t bytes) +{ + return blkid_probe_get_buffer(pr, + blkid_probe_get_sectorsize(pr) * lba, bytes); +} + +static inline int guidcmp(efi_guid_t left, efi_guid_t right) +{ + return memcmp(&left, &right, sizeof (efi_guid_t)); +} + +/* + * UUID is traditionaly 16 byte big-endian array, except Intel EFI + * specification where the UUID is a structure of little-endian fields. + */ +static void swap_efi_guid(efi_guid_t *uid) +{ + uid->time_low = swab32(uid->time_low); + uid->time_mid = swab16(uid->time_mid); + uid->time_hi_and_version = swab16(uid->time_hi_and_version); +} + +static int last_lba(blkid_probe pr, uint64_t *lba) +{ + blkid_loff_t sz = blkid_probe_get_size(pr); + if (sz < blkid_probe_get_sectorsize(pr)) + return -1; + + *lba = (sz >> 9) - 1; + return 0; +} + +/* + * Protective (legacy) MBR. + * + * This MBR contains standard DOS partition table with a single partition, type + * of 0xEE. The partition usually encompassing the entire GPT drive - or 2TiB + * for large disks. + * + * Note that Apple uses GPT/MBR hybrid disks, where the DOS partition table is + * synchronized with GPT. This synchronization has many restriction of course + * (due DOS PT limitations). + * + * Note that the PMBR detection is optional (enabled by default) and could be + * disabled by BLKID_PARTS_FOPCE_GPT flag (see also blkid_paertitions_set_flags()). + */ +static int is_pmbr_valid(blkid_probe pr) +{ + int flags = blkid_partitions_get_flags(pr); + unsigned char *data; + struct dos_partition *p; + int i; + + if (flags & BLKID_PARTS_FORCE_GPT) + goto ok; /* skip PMBR check */ + + data = blkid_probe_get_sector(pr, 0); + if (!data) + goto failed; + + if (!is_valid_mbr_signature(data)) + goto failed; + + p = (struct dos_partition *) (data + BLKID_MSDOS_PT_OFFSET); + + for (i = 0; i < 4; i++, p++) { + if (p->sys_type == BLKID_GPT_PARTITION) + goto ok; + } +failed: + return 0; +ok: + return 1; +} + +/* + * Reads GPT header to @hdr and returns a pointer to @hdr or NULL in case of + * error. The function also returns GPT entries in @ents. + * + * Note, this function does not allocate any memory. The GPT header has fixed + * size so we use stack, and @ents returns memory from libblkid buffer (so the + * next blkid_probe_get_buffer() will overwrite this buffer). + * + * This function checks validity of header and entries array. A corrupted + * header is not returned. + */ +static struct gpt_header *get_gpt_header( + blkid_probe pr, struct gpt_header *hdr, + struct gpt_entry **ents, uint64_t lba, + uint64_t lastlba) +{ + struct gpt_header *h; + uint32_t crc, orgcrc; + uint64_t lu, fu; + size_t esz; + uint32_t hsz, ssz; + + ssz = blkid_probe_get_sectorsize(pr); + + /* whole sector is allocated for GPT header */ + h = (struct gpt_header *) get_lba_buffer(pr, lba, ssz); + if (!h) + return NULL; + + if (le64_to_cpu(h->signature) != GPT_HEADER_SIGNATURE) + return NULL; + + hsz = le32_to_cpu(h->header_size); + + /* EFI: The HeaderSize must be greater than 92 and must be less + * than or equal to the logical block size. + */ + if (hsz > ssz || hsz < sizeof(*h)) + return NULL; + + /* Header has to be verified when header_crc32 is zero */ + orgcrc = le32_to_cpu(h->header_crc32); + h->header_crc32 = 0; + + crc = count_crc32((unsigned char *) h, hsz); + if (crc != orgcrc) { + DBG(DEBUG_LOWPROBE, printf("GPT header corrupted\n")); + return NULL; + } + h->header_crc32 = cpu_to_le32(orgcrc); + + /* Valid header has to be at MyLBA */ + if (le64_to_cpu(h->my_lba) != lba) { + DBG(DEBUG_LOWPROBE, printf( + "GPT->MyLBA mismatch with real position\n")); + return NULL; + } + + fu = le64_to_cpu(h->first_usable_lba); + lu = le64_to_cpu(h->last_usable_lba); + + /* Check if First and Last usable LBA makes sense */ + if (lu < fu || fu > lastlba || lu > lastlba) { + DBG(DEBUG_LOWPROBE, printf( + "GPT->{First,Last}UsableLBA out of range\n")); + return NULL; + } + + /* The header has to be outside usable range */ + if (fu < lba && lba < lu) { + DBG(DEBUG_LOWPROBE, printf("GPT header is inside usable area\n")); + return NULL; + } + + /* Size of blocks with GPT entries */ + esz = le32_to_cpu(h->num_partition_entries) * + le32_to_cpu(h->sizeof_partition_entry); + if (!esz) { + DBG(DEBUG_LOWPROBE, printf("GPT entries undefined\n")); + return NULL; + } + + /* The header seems valid, save it + * (we don't care about zeros in hdr->reserved2 area) */ + memcpy(hdr, h, sizeof(*h)); + h = hdr; + + /* Read GPT entries */ + *ents = (struct gpt_entry *) get_lba_buffer(pr, + le64_to_cpu(h->partition_entries_lba), esz); + if (!*ents) { + DBG(DEBUG_LOWPROBE, printf("GPT entries unreadable\n")); + return NULL; + } + + /* Validate entries */ + crc = count_crc32((unsigned char *) *ents, esz); + if (crc != le32_to_cpu(h->partition_entry_array_crc32)) { + DBG(DEBUG_LOWPROBE, printf("GPT entries corrupted\n")); + return NULL; + } + + return h; +} + +static int probe_gpt_pt(blkid_probe pr, const struct blkid_idmag *mag) +{ + uint64_t lastlba = 0, lba; + struct gpt_header hdr, *h; + struct gpt_entry *e; + blkid_parttable tab = NULL; + blkid_partlist ls; + int i; + uint64_t fu, lu; + uint32_t ssf; + + + if (last_lba(pr, &lastlba)) + goto nothing; + + if (!is_pmbr_valid(pr)) + goto nothing; + + h = get_gpt_header(pr, &hdr, &e, (lba = GPT_PRIMARY_LBA), lastlba); + if (!h) + h = get_gpt_header(pr, &hdr, &e, (lba = lastlba), lastlba); + + if (!h) + goto nothing; + + blkid_probe_use_wiper(pr, lba * blkid_probe_get_size(pr), 8); + + if (blkid_partitions_need_typeonly(pr)) + /* caller does not ask for details about partitions */ + return 0; + + ls = blkid_probe_get_partlist(pr); + if (!ls) + goto err; + + tab = blkid_partlist_new_parttable(ls, "gpt", lba << 9); + if (!tab) + goto err; + + ssf = blkid_probe_get_sectorsize(pr) / 512; + + fu = le64_to_cpu(h->first_usable_lba); + lu = le64_to_cpu(h->last_usable_lba); + + for (i = 0; i < le32_to_cpu(h->num_partition_entries); i++, e++) { + + blkid_partition par; + uint64_t start = le64_to_cpu(e->starting_lba); + uint64_t size = le64_to_cpu(e->ending_lba) - + le64_to_cpu(e->starting_lba) + 1ULL; + + /* 00000000-0000-0000-0000-000000000000 entry */ + if (!guidcmp(e->partition_type_guid, GPT_UNUSED_ENTRY_GUID)) { + blkid_partlist_increment_partno(ls); + continue; + } + /* the partition has to inside usable range */ + if (start < fu || start + size - 1 > lu) { + DBG(DEBUG_LOWPROBE, printf( + "GPT entry[%d] overflows usable area - ignore\n", + i)); + blkid_partlist_increment_partno(ls); + continue; + } + + par = blkid_partlist_add_partition(ls, tab, + start * ssf, size * ssf); + if (!par) + goto err; + + blkid_partition_set_utf8name(par, + (unsigned char *) e->partition_name, + sizeof(e->partition_name), BLKID_ENC_UTF16LE); + + swap_efi_guid(&e->unique_partition_guid); + swap_efi_guid(&e->partition_type_guid); + + blkid_partition_set_uuid(par, + (const unsigned char *) &e->unique_partition_guid); + + blkid_partition_set_type_uuid(par, + (const unsigned char *) &e->partition_type_guid); + + blkid_partition_set_flags(par, e->attributes); + } + + return 0; + +nothing: + return 1; +err: + return -1; +} + + +const struct blkid_idinfo gpt_pt_idinfo = +{ + .name = "gpt", + .probefunc = probe_gpt_pt, + .minsz = 1024 * 1440 + 1, /* ignore floppies */ + + /* + * It would be possible to check for DOS signature (0xAA55), but + * unfortunately almost all EFI GPT implemenations allow to optionaly + * skip the legacy MBR. We follows this behavior and MBR is optional. + * See is_valid_pmbr(). + * + * It means we have to always call probe_gpt_pt(). + */ + .magics = BLKID_NONE_MAGIC +}; + diff --git a/libblkid/src/partitions/mac.c b/libblkid/src/partitions/mac.c new file mode 100644 index 00000000..538b2727 --- /dev/null +++ b/libblkid/src/partitions/mac.c @@ -0,0 +1,181 @@ +/* + * mac partitions parsing code + * + * Copyright (C) 2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * + */ +#include +#include +#include +#include + +#include "partitions.h" + +#define MAC_PARTITION_MAGIC 0x504d +#define MAC_PARTITION_MAGIC_OLD 0x5453 + +/* + * Mac partition entry + * http://developer.apple.com/legacy/mac/library/documentation/mac/Devices/Devices-126.html + */ +struct mac_partition { + uint16_t signature; /* expected to be MAC_PARTITION_MAGIC */ + uint16_t reserved; /* reserved */ + uint32_t map_count; /* # blocks in partition map */ + uint32_t start_block; /* absolute starting block # of partition */ + uint32_t block_count; /* number of blocks in partition */ + char name[32]; /* partition name */ + char type[32]; /* string type description */ + uint32_t data_start; /* rel block # of first data block */ + uint32_t data_count; /* number of data blocks */ + uint32_t status; /* partition status bits */ + uint32_t boot_start; /* first logical block of boot code */ + uint32_t boot_size; /* size of boot code, in bytes */ + uint32_t boot_load; /* boot code load address */ + uint32_t boot_load2; /* reserved */ + uint32_t boot_entry; /* boot code entry point */ + uint32_t boot_entry2; /* reserved */ + uint32_t boot_cksum; /* boot code checksum */ + char processor[16]; /* identifies ISA of boot */ + + /* there is more stuff after this that we don't need */ +} __attribute__((packed)); + +/* + * Driver descriptor structure, in block 0 + * http://developer.apple.com/legacy/mac/library/documentation/mac/Devices/Devices-121.html + */ +struct mac_driver_desc { + uint16_t signature; /* expected to be MAC_DRIVER_MAGIC */ + uint16_t block_size; /* block size of the device */ + uint32_t block_count; /* number of blocks on the device */ + + /* there is more stuff after this that we don't need */ +} __attribute__((packed)); + +static inline unsigned char *get_mac_block( + blkid_probe pr, + struct mac_driver_desc *md, + uint32_t num) +{ + return blkid_probe_get_buffer(pr, + (blkid_loff_t) num * md->block_size, num); +} + +static inline int has_part_signature(struct mac_partition *p) +{ + return be16_to_cpu(p->signature) == MAC_PARTITION_MAGIC || + be16_to_cpu(p->signature) == MAC_PARTITION_MAGIC_OLD; +} + +static int probe_mac_pt(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct mac_driver_desc *md; + struct mac_partition *p; + blkid_parttable tab = NULL; + blkid_partlist ls; + int i; + uint16_t ssf; /* sector size fragment */ + uint32_t nblks; + + + /* The driver descriptor record is always located at physical block 0, + * the first block on the disk. + */ + md = (struct mac_driver_desc *) blkid_probe_get_sector(pr, 0); + if (!md) + goto nothing; + + + /* The partition map always begins at physical block 1, + * the second block on the disk. + */ + p = (struct mac_partition *) get_mac_block(pr, md, 1); + if (!p) + goto nothing; + + /* check the first partition signature */ + if (!has_part_signature(p)) + goto nothing; + + if (blkid_partitions_need_typeonly(pr)) + /* caller does not ask for details about partitions */ + return 0; + + ls = blkid_probe_get_partlist(pr); + if (!ls) + goto err; + + tab = blkid_partlist_new_parttable(ls, "mac", 0); + if (!tab) + goto err; + + ssf = md->block_size / 512; + nblks = be32_to_cpu(p->map_count); + + for (i = 1; i <= nblks; ++i) { + blkid_partition par; + uint32_t start; + uint32_t size; + + p = (struct mac_partition *) get_mac_block(pr, md, i); + if (!p) + goto nothing; + if (!has_part_signature(p)) + goto nothing; + + if (be32_to_cpu(p->map_count) != nblks) { + DBG(DEBUG_LOWPROBE, printf( + "mac: inconsisten map_count in partition map, " + "entry[0]: %d, entry[%d]: %d\n", + nblks, i - 1, + be32_to_cpu(p->map_count))); + } + + /* + * note that libparted ignores some mac partitions according to + * the partition name (e.g. "Apple_Free" or "Apple_Void"). We + * follows Linux kernel and all partitions are visible + */ + + start = be32_to_cpu(p->start_block) * ssf; + size = be32_to_cpu(p->block_count) * ssf; + + par = blkid_partlist_add_partition(ls, tab, start, size); + if (!par) + goto err; + + blkid_partition_set_name(par, (unsigned char *) p->name, + sizeof(p->name)); + + blkid_partition_set_type_string(par, (unsigned char *) p->type, + sizeof(p->type)); + } + + return 0; + +nothing: + return 1; +err: + return -1; +} + +/* + * Mac disk always begin with "Driver Descriptor Record" + * (struct mac_driver_desc) and magic 0x4552. + */ +const struct blkid_idinfo mac_pt_idinfo = +{ + .name = "mac", + .probefunc = probe_mac_pt, + .magics = + { + /* big-endian magic string */ + { .magic = "\x45\x52", .len = 2 }, + { NULL } + } +}; + diff --git a/libblkid/src/partitions/minix.c b/libblkid/src/partitions/minix.c new file mode 100644 index 00000000..0887d1a3 --- /dev/null +++ b/libblkid/src/partitions/minix.c @@ -0,0 +1,103 @@ +/* + * Minix partition parsing code + * + * Copyright (C) 2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include + +#include "partitions.h" +#include "dos.h" + +/* + * Minix subpartitions are always within primary dos partition. + */ +#define MINIX_MAXPARTITIONS 4 + +static int probe_minix_pt(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct dos_partition *p; + blkid_parttable tab = NULL; + blkid_partition parent; + blkid_partlist ls; + unsigned char *data; + int i; + + data = blkid_probe_get_sector(pr, 0); + if (!data) + goto nothing; + + ls = blkid_probe_get_partlist(pr); + if (!ls) + goto err; + + /* Parent is required, because Minix uses the same PT as DOS and + * difference is only in primary partition (parent) type. + */ + parent = blkid_partlist_get_parent(ls); + if (!parent) + goto nothing; + + if (blkid_partition_get_type(parent) != BLKID_MINIX_PARTITION) + goto nothing; + + if (blkid_partitions_need_typeonly(pr)) + /* caller does not ask for details about partitions */ + return 0; + + p = (struct dos_partition *) (data + BLKID_MSDOS_PT_OFFSET); + + tab = blkid_partlist_new_parttable(ls, "minix", BLKID_MSDOS_PT_OFFSET); + if (!tab) + goto err; + + for (i = 0; i < MINIX_MAXPARTITIONS; i++, p++) { + uint32_t start, size; + blkid_partition par; + + if (p->sys_type != BLKID_MINIX_PARTITION) + continue; + + start = dos_partition_start(p); + size = dos_partition_size(p); + + if (parent && !blkid_is_nested_dimension(parent, start, size)) { + DBG(DEBUG_LOWPROBE, printf( + "WARNING: minix partition (%d) overflow " + "detected, ignore\n", i)); + continue; + } + + par = blkid_partlist_add_partition(ls, tab, start, size); + if (!par) + goto err; + + blkid_partition_set_type(par, p->sys_type); + blkid_partition_set_flags(par, p->boot_ind); + } + + return 0; + +nothing: + return 1; +err: + return -1; +} + +/* same as DOS */ +const struct blkid_idinfo minix_pt_idinfo = +{ + .name = "minix", + .probefunc = probe_minix_pt, + .magics = + { + { .magic = "\x55\xAA", .len = 2, .sboff = 510 }, + { NULL } + } +}; + diff --git a/libblkid/src/partitions/partitions.c b/libblkid/src/partitions/partitions.c new file mode 100644 index 00000000..89f05871 --- /dev/null +++ b/libblkid/src/partitions/partitions.c @@ -0,0 +1,1336 @@ +/* + * partitions - partition tables parsing + * + * Copyright (C) 2008-2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "partitions.h" +#include "sysfs.h" + +/** + * SECTION:partitions + * @title: Partitions probing + * @short_description: partitions tables detection and parsing + * + * This chain supports binary and NAME=value interfaces, but complete PT + * description is provided by binary interface only. The libblkid prober is + * compatible with kernel partition tables parser. The parser does not return + * empty (size=0) partitions or special hidden partitions. + * + * NAME=value interface, supported tags: + * + * @PTTYPE: partition table type (dos, gpt, etc.). + * + * @PART_ENTRY_SCHEME: partition table type + * + * @PART_ENTRY_NAME: partition name (gpt and mac only) + * + * @PART_ENTRY_UUID: partition UUID (gpt only) + * + * @PART_ENTRY_TYPE: partition type, 0xNN (e.g 0x82) or type UUID (gpt only) or type string (mac) + * + * @PART_ENTRY_FLAGS: partition flags (e.g. boot_ind) or attributes (e.g. gpt attributes) + * + * @PART_ENTRY_NUMBER: partition number + * + * Example: + * + * + * + * blkid_probe pr; + * const char *ptname; + * + * pr = blkid_new_probe_from_filename(devname); + * if (!pr) + * err("%s: faild to open device", devname); + * + * blkid_probe_enable_partitions(pr, TRUE); + * blkid_do_fullprobe(pr); + * + * blkid_probe_lookup_value(pr, "PTTYPE", &ptname, NULL); + * printf("%s partition type detected\n", pttype); + * + * blkid_free_probe(pr); + * + * // don't forget to check return codes in your code! + * + * + * + * Binary interface: + * + * + * + * blkid_probe pr; + * blkid_partlist ls; + * int nparts, i; + * + * pr = blkid_new_probe_from_filename(devname); + * if (!pr) + * err("%s: faild to open device", devname); + * + * ls = blkid_probe_get_partitions(pr); + * nparts = blkid_partlist_numof_partitions(ls); + * + * for (i = 0; i < nparts; i++) { + * blkid_partition par = blkid_partlist_get_partition(ls, i); + * printf("#%d: %llu %llu 0x%x", + * blkid_partition_get_partno(par), + * blkid_partition_get_start(par), + * blkid_partition_get_size(par), + * blkid_partition_get_type(par)); + * } + * + * blkid_free_probe(pr); + * + * // don't forget to check return codes in your code! + * + * + */ + +/* + * Chain driver function + */ +static int partitions_probe(blkid_probe pr, struct blkid_chain *chn); +static void partitions_free_data(blkid_probe pr, void *data); + +/* + * Partitions chain probing functions + */ +static const struct blkid_idinfo *idinfos[] = +{ + &aix_pt_idinfo, + &sgi_pt_idinfo, + &sun_pt_idinfo, + &dos_pt_idinfo, + &gpt_pt_idinfo, + &mac_pt_idinfo, + &ultrix_pt_idinfo, + &bsd_pt_idinfo, + &unixware_pt_idinfo, + &solaris_x86_pt_idinfo, + &minix_pt_idinfo +}; + +/* + * Driver definition + */ +const struct blkid_chaindrv partitions_drv = { + .id = BLKID_CHAIN_PARTS, + .name = "partitions", + .dflt_enabled = FALSE, + .idinfos = idinfos, + .nidinfos = ARRAY_SIZE(idinfos), + .has_fltr = TRUE, + .probe = partitions_probe, + .safeprobe = partitions_probe, + .free_data = partitions_free_data +}; + + +/* + * For compatibility with the rest of libblkid API (with the old high-level + * API) we use completely opaque typedefs for all structs. Don't forget that + * the final blkid_* types are pointers! See blkid.h. + * + * [Just for the record, I hate typedef for pointers --kzak] + */ + +/* exported as opaque type "blkid_parttable" */ +struct blkid_struct_parttable { + const char *type; /* partition table type */ + blkid_loff_t offset; /* begin of the partition table */ + int nparts; /* number of partitions */ + blkid_partition parent; /* parent of nested partition table */ + + struct list_head t_tabs; /* all tables */ +}; + +/* exported as opaque type "blkid_partition" */ +struct blkid_struct_partition { + blkid_loff_t start; /* begin of the partition */ + blkid_loff_t size; /* size of the partitions */ + + int type; /* partition type */ + char typestr[37]; /* partition type string (GPT and Mac) */ + + unsigned long long flags; /* partition flags / attributes */ + + int partno; /* partition number */ + char uuid[37]; /* UUID (when supported by PT), e.g GPT */ + unsigned char name[128]; /* Partition in UTF8 name (when supporte by PT), e.g. Mac */ + + blkid_parttable tab; /* partition table */ +}; + +/* exported as opaque type "blkid_partlist" */ +struct blkid_struct_partlist { + int next_partno; /* next partition number */ + blkid_partition next_parent; /* next parent if parsing nested PT */ + + int nparts; /* number of partitions */ + int nparts_max; /* max.number of partitions */ + blkid_partition parts; /* array of partitions */ + + struct list_head l_tabs; /* list of partition tables */ +}; + +static int blkid_partitions_probe_partition(blkid_probe pr); + +/** + * blkid_probe_enable_partitions: + * @pr: probe + * @enable: TRUE/FALSE + * + * Enables/disables the partitions probing for non-binary interface. + * + * Returns: 0 on success, or -1 in case of error. + */ +int blkid_probe_enable_partitions(blkid_probe pr, int enable) +{ + if (!pr) + return -1; + pr->chains[BLKID_CHAIN_PARTS].enabled = enable; + return 0; +} + +/** + * blkid_probe_set_partitions_flags: + * @pr: prober + * @flags: BLKID_PARTS_* flags + * + * Sets probing flags to the partitions prober. This function is optional. + * + * Returns: 0 on success, or -1 in case of error. + */ +int blkid_probe_set_partitions_flags(blkid_probe pr, int flags) +{ + if (!pr) + return -1; + + pr->chains[BLKID_CHAIN_PARTS].flags = flags; + return 0; +} + +/** + * blkid_probe_reset_partitions_filter: + * @pr: prober + * + * Resets partitions probing filter + * + * Returns: 0 on success, or -1 in case of error. + */ +int blkid_probe_reset_partitions_filter(blkid_probe pr) +{ + return __blkid_probe_reset_filter(pr, BLKID_CHAIN_PARTS); +} + +/** + * blkid_probe_invert_partitions_filter: + * @pr: prober + * + * Inverts partitions probing filter + * + * Returns: 0 on success, or -1 in case of error. + */ +int blkid_probe_invert_partitions_filter(blkid_probe pr) +{ + return __blkid_probe_invert_filter(pr, BLKID_CHAIN_PARTS); +} + +/** + * blkid_probe_filter_partitions_type: + * @pr: prober + * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag + * @names: NULL terminated array of probing function names (e.g. "vfat"). + * + * BLKID_FLTR_NOTIN - probe for all items which are NOT IN @names + * BLKID_FLTR_ONLYIN - probe for items which are IN @names + * + * Returns: 0 on success, or -1 in case of error. + */ +int blkid_probe_filter_partitions_type(blkid_probe pr, int flag, char *names[]) +{ + return __blkid_probe_filter_types(pr, BLKID_CHAIN_PARTS, flag, names); +} + +/** + * blkid_probe_get_partitions: + * @pr: probe + * + * This is a binary interface for partitions. See also blkid_partlist_* + * functions. + * + * This function is independent on blkid_do_[safe,full]probe() and + * blkid_probe_enable_partitions() calls. + * + * WARNING: the returned object will be overwritten by the next + * blkid_probe_get_partitions() call for the same @pr. If you want to + * use more blkid_partlist objects in the same time you have to create + * more blkid_probe handlers (see blkid_new_probe()). + * + * Returns: list of partitions, or NULL in case of error. + */ +blkid_partlist blkid_probe_get_partitions(blkid_probe pr) +{ + return (blkid_partlist) blkid_probe_get_binary_data(pr, + &pr->chains[BLKID_CHAIN_PARTS]); +} + +/* for internal usage only */ +blkid_partlist blkid_probe_get_partlist(blkid_probe pr) +{ + return (blkid_partlist) pr->chains[BLKID_CHAIN_PARTS].data; +} + +static void blkid_probe_set_partlist(blkid_probe pr, blkid_partlist ls) +{ + pr->chains[BLKID_CHAIN_PARTS].data = ls; +} + +static void ref_parttable(blkid_parttable tab) +{ + tab->nparts++; +} + +static void unref_parttable(blkid_parttable tab) +{ + tab->nparts--; + + if (tab->nparts <= 0) { + list_del(&tab->t_tabs); + free(tab); + } +} + +/* free all allocated parttables */ +static void free_parttables(blkid_partlist ls) +{ + if (!ls || !ls->l_tabs.next) + return; + + /* remove unassigned partition tables */ + while (!list_empty(&ls->l_tabs)) { + blkid_parttable tab = list_entry(ls->l_tabs.next, + struct blkid_struct_parttable, t_tabs); + unref_parttable(tab); + } +} + +static void reset_partlist(blkid_probe pr, blkid_partlist ls) +{ + if (!ls) + return; + + free_parttables(ls); + + if (ls->next_partno) { + /* already initialized - reset */ + int tmp_nparts = ls->nparts_max; + blkid_partition tmp_parts = ls->parts; + + memset(ls, 0, sizeof(struct blkid_struct_partlist)); + + ls->nparts_max = tmp_nparts; + ls->parts = tmp_parts; + } + + ls->nparts = 0; + ls->next_partno = 1; + INIT_LIST_HEAD(&ls->l_tabs); + + DBG(DEBUG_LOWPROBE, printf("partlist reseted\n")); +} + +static blkid_partlist partitions_init_data(blkid_probe pr, struct blkid_chain *chn) +{ + blkid_partlist ls; + + if (chn->data) + ls = (blkid_partlist) chn->data; + else { + /* allocate the new list of partitions */ + ls = calloc(1, sizeof(struct blkid_struct_partlist)); + if (!ls) + return NULL; + chn->data = (void *) ls; + } + + reset_partlist(pr, ls); + + DBG(DEBUG_LOWPROBE, + printf("parts: initialized partitions list (%p, size=%d)\n", + ls, ls->nparts_max)); + return ls; +} + +static void partitions_free_data(blkid_probe pr, void *data) +{ + blkid_partlist ls = (blkid_partlist) data; + + if (!ls) + return; + + free_parttables(ls); + + /* deallocate partitions and partlist */ + free(ls->parts); + free(ls); +} + +blkid_parttable blkid_partlist_new_parttable(blkid_partlist ls, + const char *type, blkid_loff_t offset) +{ + blkid_parttable tab; + + tab = calloc(1, sizeof(struct blkid_struct_parttable)); + if (!tab) + return NULL; + tab->type = type; + tab->offset = offset; + tab->parent = ls->next_parent; + + INIT_LIST_HEAD(&tab->t_tabs); + list_add_tail(&tab->t_tabs, &ls->l_tabs); + + DBG(DEBUG_LOWPROBE, + printf("parts: create a new partition table " + "(%p, type=%s, offset=%"PRId64")\n", tab, type, offset)); + return tab; +} + +static blkid_partition new_partition(blkid_partlist ls, blkid_parttable tab) +{ + blkid_partition par; + + if (ls->nparts + 1 > ls->nparts_max) { + /* Linux kernel has DISK_MAX_PARTS=256, but it's too much for + * generic Linux machine -- let start with 32 partititions. + */ + ls->parts = realloc(ls->parts, (ls->nparts_max + 32) * + sizeof(struct blkid_struct_partition)); + if (!ls->parts) + return NULL; + ls->nparts_max += 32; + } + + par = &ls->parts[ls->nparts++]; + memset(par, 0, sizeof(struct blkid_struct_partition)); + + ref_parttable(tab); + par->tab = tab; + par->partno = blkid_partlist_increment_partno(ls); + + return par; +} + +blkid_partition blkid_partlist_add_partition(blkid_partlist ls, + blkid_parttable tab, + blkid_loff_t start, blkid_loff_t size) +{ + blkid_partition par = new_partition(ls, tab); + + if (!par) + return NULL; + + par->start = start; + par->size = size; + + DBG(DEBUG_LOWPROBE, + printf("parts: add partition (%p start=%" + PRId64 ", size=%" PRId64 ", table=%p)\n", + par, par->start, par->size, tab)); + return par; +} + +/* allows to modify used partitions numbers (for example for logical partitions) */ +int blkid_partlist_set_partno(blkid_partlist ls, int partno) +{ + if (!ls) + return -1; + ls->next_partno = partno; + return 0; +} + +int blkid_partlist_increment_partno(blkid_partlist ls) +{ + return ls ? ls->next_partno++ : -1; +} + +/* allows to set "parent" for the next nested partition */ +int blkid_partlist_set_parent(blkid_partlist ls, blkid_partition par) +{ + if (!ls) + return -1; + ls->next_parent = par; + return 0; +} + +blkid_partition blkid_partlist_get_parent(blkid_partlist ls) +{ + if (!ls) + return NULL; + return ls->next_parent; +} + +int blkid_partitions_need_typeonly(blkid_probe pr) +{ + struct blkid_chain *chn = blkid_probe_get_chain(pr); + + return chn && chn->data && chn->binary ? FALSE : TRUE; +} + +/* get private chain flags */ +int blkid_partitions_get_flags(blkid_probe pr) +{ + struct blkid_chain *chn = blkid_probe_get_chain(pr); + + return chn ? chn->flags : 0; +} + +/* check if @start and @size are within @par partition */ +int blkid_is_nested_dimension(blkid_partition par, + blkid_loff_t start, blkid_loff_t size) +{ + blkid_loff_t pstart; + blkid_loff_t psize; + + if (!par) + return 0; + + pstart = blkid_partition_get_start(par); + psize = blkid_partition_get_size(par); + + if (start < pstart || start + size > pstart + psize) + return 0; + + return 1; +} + +static int idinfo_probe(blkid_probe pr, const struct blkid_idinfo *id) +{ + const struct blkid_idmag *mag; + int rc = 1; /* = nothing detected */ + + if (pr->size <= 0 || (id->minsz && id->minsz > pr->size)) + goto nothing; /* the device is too small */ + + if (blkid_probe_get_idmag(pr, id, NULL, &mag)) + goto nothing; + + /* final check by probing function */ + if (id->probefunc) { + DBG(DEBUG_LOWPROBE, printf( + "%s: ---> call probefunc()\n", id->name)); + rc = id->probefunc(pr, mag); + if (rc == -1) { + /* reset after error */ + reset_partlist(pr, blkid_probe_get_partlist(pr)); + DBG(DEBUG_LOWPROBE, printf( + "%s probefunc failed\n", id->name)); + } + DBG(DEBUG_LOWPROBE, printf( + "%s: <--- (rc = %d)\n", id->name, rc)); + } + +nothing: + return rc; +} + +/* + * The blkid_do_probe() backend. + */ +static int partitions_probe(blkid_probe pr, struct blkid_chain *chn) +{ + int i = 0, rc = 1; + + if (!pr || chn->idx < -1) + return -1; + blkid_probe_chain_reset_vals(pr, chn); + + if (chn->binary) + partitions_init_data(pr, chn); + + if (!pr->wipe_size && (pr->prob_flags & BLKID_PROBE_FL_IGNORE_PT)) + goto details_only; + + DBG(DEBUG_LOWPROBE, + printf("--> starting probing loop [PARTS idx=%d]\n", + chn->idx)); + + i = chn->idx + 1; + + for ( ; i < ARRAY_SIZE(idinfos); i++) { + const char *name; + + chn->idx = i; + + /* apply filter */ + if (chn->fltr && blkid_bmp_get_item(chn->fltr, i)) + continue; + + /* apply checks from idinfo */ + if (idinfo_probe(pr, idinfos[i]) != 0) + continue; + + name = idinfos[i]->name; + + /* all checks passed */ + if (!chn->binary) + blkid_probe_set_value(pr, "PTTYPE", + (unsigned char *) name, + strlen(name) + 1); + DBG(DEBUG_LOWPROBE, + printf("<-- leaving probing loop (type=%s) [PARTS idx=%d]\n", + name, chn->idx)); + rc = 0; + break; + } + + if (rc == 1) { + DBG(DEBUG_LOWPROBE, + printf("<-- leaving probing loop (failed) [PARTS idx=%d]\n", + chn->idx)); + } + +details_only: + /* + * Gather PART_ENTRY_* values if the current device is a partition. + */ + if (!chn->binary && + (blkid_partitions_get_flags(pr) & BLKID_PARTS_ENTRY_DETAILS)) { + + if (!blkid_partitions_probe_partition(pr)) + rc = 0; + } + + return rc; +} + +/* Probe for nested partition table within the parental partition */ +int blkid_partitions_do_subprobe(blkid_probe pr, blkid_partition parent, + const struct blkid_idinfo *id) +{ + blkid_probe prc; + int rc = 1; + blkid_partlist ls; + blkid_loff_t sz, off; + + DBG(DEBUG_LOWPROBE, printf( + "parts: ----> %s subprobe requested (parent=%p)\n", + id->name, parent)); + + if (!pr || !parent || !parent->size) + return -1; + + /* range defined by parent */ + sz = ((blkid_loff_t) parent->size) << 9; + off = ((blkid_loff_t) parent->start) << 9; + + if (off < pr->off || pr->off + pr->size < off + sz) { + DBG(DEBUG_LOWPROBE, printf( + "ERROR: parts: <---- '%s' subprobe: overflow detected.\n", + id->name)); + return -1; + } + + /* create private prober */ + prc = blkid_clone_probe(pr); + if (!prc) + return -1; + + blkid_probe_set_dimension(prc, off, sz); + + /* clone is always with reseted chain, fix it */ + prc->cur_chain = blkid_probe_get_chain(pr); + + /* + * Set 'parent' to the current list of the partitions and use the list + * in cloned prober (so the cloned prober will extend the current list + * of partitions rather than create a new). + */ + ls = blkid_probe_get_partlist(pr); + blkid_partlist_set_parent(ls, parent); + + blkid_probe_set_partlist(prc, ls); + + rc = idinfo_probe(prc, id); + + blkid_probe_set_partlist(prc, NULL); + blkid_partlist_set_parent(ls, NULL); + + blkid_free_probe(prc); /* free cloned prober */ + + DBG(DEBUG_LOWPROBE, printf( + "parts: <---- %s subprobe done (parent=%p, rc=%d)\n", + id->name, parent, rc)); + + return rc; +} + +static int blkid_partitions_probe_partition(blkid_probe pr) +{ + int rc = 1; + blkid_probe disk_pr = NULL; + blkid_partlist ls; + blkid_partition par; + dev_t devno; + + devno = blkid_probe_get_devno(pr); + if (!devno) + goto nothing; + + disk_pr = blkid_probe_get_wholedisk_probe(pr); + if (!disk_pr) + goto nothing; + + /* parse PT */ + ls = blkid_probe_get_partitions(disk_pr); + if (!ls) + goto nothing; + + par = blkid_partlist_devno_to_partition(ls, devno); + if (par) { + const char *v; + blkid_parttable tab = blkid_partition_get_table(par); + dev_t disk = blkid_probe_get_devno(disk_pr); + + if (tab) { + v = blkid_parttable_get_type(tab); + if (v) + blkid_probe_set_value(pr, "PART_ENTRY_SCHEME", + (unsigned char *) v, strlen(v) + 1); + } + + v = blkid_partition_get_name(par); + if (v) + blkid_probe_set_value(pr, "PART_ENTRY_NAME", + (unsigned char *) v, strlen(v) + 1); + + v = blkid_partition_get_uuid(par); + if (v) + blkid_probe_set_value(pr, "PART_ENTRY_UUID", + (unsigned char *) v, strlen(v) + 1); + + /* type */ + v = blkid_partition_get_type_string(par); + if (v) + blkid_probe_set_value(pr, "PART_ENTRY_TYPE", + (unsigned char *) v, strlen(v) + 1); + else + blkid_probe_sprintf_value(pr, "PART_ENTRY_TYPE", + "0x%x", blkid_partition_get_type(par)); + + if (blkid_partition_get_flags(par)) + blkid_probe_sprintf_value(pr, "PART_ENTRY_FLAGS", + "0x%llx", blkid_partition_get_flags(par)); + + blkid_probe_sprintf_value(pr, "PART_ENTRY_NUMBER", + "%d", blkid_partition_get_partno(par)); + + blkid_probe_sprintf_value(pr, "PART_ENTRY_OFFSET", "%jd", + blkid_partition_get_start(par)); + blkid_probe_sprintf_value(pr, "PART_ENTRY_SIZE", "%jd", + blkid_partition_get_size(par)); + + blkid_probe_sprintf_value(pr, "PART_ENTRY_DISK", "%u:%u", + major(disk), minor(disk)); + } + rc = 0; +nothing: + return rc; +} + +/* + * Returns 1 if the device is whole-disk and the area specified by @offset and + * @size is covered by any partition. + */ +int blkid_probe_is_covered_by_pt(blkid_probe pr, + blkid_loff_t offset, blkid_loff_t size) +{ + blkid_probe prc; + blkid_partlist ls = NULL; + blkid_loff_t start, end; + int nparts, i, rc = 0; + + DBG(DEBUG_LOWPROBE, printf( + "=> checking if off=%jd size=%jd covered by PT\n", + offset, size)); + + prc = blkid_clone_probe(pr); + if (!prc) + goto done; + + ls = blkid_probe_get_partitions(prc); + if (!ls) + goto done; + + nparts = blkid_partlist_numof_partitions(ls); + if (!nparts) + goto done; + + end = (offset + size) >> 9; + start = offset >> 9; + + /* check if the partition table fits into the device */ + for (i = 0; i < nparts; i++) { + blkid_partition par = &ls->parts[i]; + + if (par->start + par->size > (pr->size >> 9)) { + DBG(DEBUG_LOWPROBE, printf("partition #%d overflows " + "device (off=%" PRId64 " size=%" PRId64 ")\n", + par->partno, par->start, par->size)); + goto done; + } + } + + /* check if the requested area is covered by PT */ + for (i = 0; i < nparts; i++) { + blkid_partition par = &ls->parts[i]; + + if (start >= par->start && end <= par->start + par->size) { + rc = 1; + break; + } + } +done: + blkid_free_probe(prc); + + DBG(DEBUG_LOWPROBE, printf("<= %s covered by PT\n", rc ? "IS" : "NOT")); + return rc; +} + +/** + * blkid_known_pttype: + * @pttype: partiton name + * + * Returns: 1 for known or 0 for unknown partition type. + */ +int blkid_known_pttype(const char *pttype) +{ + int i; + + if (!pttype) + return 0; + + for (i = 0; i < ARRAY_SIZE(idinfos); i++) { + const struct blkid_idinfo *id = idinfos[i]; + if (strcmp(id->name, pttype) == 0) + return 1; + } + return 0; +} + +/** + * blkid_partlist_numof_partitions: + * @ls: partitions list + * + * Returns: number of partitions in the list or -1 in case of error. + */ +int blkid_partlist_numof_partitions(blkid_partlist ls) +{ + return ls ? ls->nparts : -1; +} + +/** + * blkid_partlist_get_table: + * + * Returns top-level partition table or NULL of there is not a partition table + * on the device. + */ +blkid_parttable blkid_partlist_get_table(blkid_partlist ls) +{ + if (!ls || list_empty(&ls->l_tabs)) + return NULL; + + return list_entry(ls->l_tabs.next, + struct blkid_struct_parttable, t_tabs); +} + + +/** + * blkid_partlist_get_partition: + * @ls: partitions list + * @n: partition number in range 0..N, where 'N' is blkid_partlist_numof_partitions(). + * + * It's possible that the list of partitions is *empty*, but there is a valid + * partition table on the disk. This happen when on-disk details about + * partitions are unknown or the partition table is empty. + * + * See also blkid_partlist_get_table(). + * + * Returns: partition object or NULL in case or error. + */ +blkid_partition blkid_partlist_get_partition(blkid_partlist ls, int n) +{ + if (!ls || n < 0 || n >= ls->nparts) + return NULL; + + return &ls->parts[n]; +} + +/** + * blkid_partlist_devno_to_partition: + * @ls: partitions list + * @devno: requested partition + * + * This function tries to get start and size for @devno from sysfs and + * returns a partition from @ls which matches with the values from sysfs. + * + * This funtion is necessary when you want to make a relation between an entry + * in the partition table (@ls) and block devices in your system. + * + * Returns: partition object or NULL in case or error. + */ +blkid_partition blkid_partlist_devno_to_partition(blkid_partlist ls, dev_t devno) +{ + struct sysfs_cxt sysfs; + uint64_t start, size; + int i, rc, partno = 0; + + DBG(DEBUG_LOWPROBE, + printf("triyng to convert devno 0x%llx to partition\n", + (long long) devno)); + + if (sysfs_init(&sysfs, devno, NULL)) { + DBG(DEBUG_LOWPROBE, printf("failed t init sysfs context\n")); + return NULL; + } + rc = sysfs_read_u64(&sysfs, "size", &size); + if (!rc) { + rc = sysfs_read_u64(&sysfs, "start", &start); + if (rc) { + /* try to get partition number from DM uuid. + */ + char *uuid = sysfs_strdup(&sysfs, "dm/uuid"); + char *tmp = uuid; + char *prefix = uuid ? strsep(&tmp, "-") : NULL; + + if (prefix && strncasecmp(prefix, "part", 4) == 0) { + char *end = NULL; + + partno = strtol(prefix + 4, &end, 10); + if (prefix == end || (end && *end)) + partno = 0; + else + rc = 0; /* success */ + } + free(uuid); + } + } + + sysfs_deinit(&sysfs); + + if (rc) + return NULL; + + if (partno) { + DBG(DEBUG_LOWPROBE, printf("mapped by DM, using partno %d\n", partno)); + + /* + * Partition mapped by kpartx does not provide "start" offset + * in /sys, but if we know partno and size of the partition + * that we can probably make the releation bettween the device + * and an entry in partition table. + */ + for (i = 0; i < ls->nparts; i++) { + blkid_partition par = &ls->parts[i]; + + if (partno != blkid_partition_get_partno(par)) + continue; + + if (size == blkid_partition_get_size(par) || + (blkid_partition_is_extended(par) && size <= 1024)) + return par; + + } + return NULL; + } + + DBG(DEBUG_LOWPROBE, printf("searching by offset/size\n")); + + for (i = 0; i < ls->nparts; i++) { + blkid_partition par = &ls->parts[i]; + + if (blkid_partition_get_start(par) == start && + blkid_partition_get_size(par) == size) + return par; + + /* exception for extended dos partitions */ + if (blkid_partition_get_start(par) == start && + blkid_partition_is_extended(par) && size <= 1024) + return par; + + } + + DBG(DEBUG_LOWPROBE, printf("not found partition for device\n")); + return NULL; +} + +int blkid_partition_set_type(blkid_partition par, int type) +{ + if (!par) + return -1; + par->type = type; + return 0; +} + +/** + * blkid_parttable_get_type: + * @tab: partition table + * + * Returns: partition table type (type name, e.g. "dos", "gpt", ...) + */ +const char *blkid_parttable_get_type(blkid_parttable tab) +{ + return tab ? tab->type : NULL; +} + +/** + * blkid_parttable_get_parent: + * @tab: partition table + * + * Returns: parent for nexted partitition tables or NULL. + */ +blkid_partition blkid_parttable_get_parent(blkid_parttable tab) +{ + return tab ? tab->parent : NULL; +} + +/** + * blkid_parttable_get_offset: + * @tab: partition table + * + * Returns: position (in bytes) of the partition table or -1 in case of error. + * + * Note the position is relative to begin of the device as defined by + * blkid_probe_set_device() for primary partition table, and relative + * to parental partition for nested patition tables. + * + * + * + * off_t offset; + * blkid_partition parent = blkid_parttable_get_parent(tab); + * + * offset = blkid_parttable_get_offset(tab); + * + * if (parent) + * / * 'tab' is nested partition table * / + * offset += blkid_partition_get_start(parent); + * + * + */ +blkid_loff_t blkid_parttable_get_offset(blkid_parttable tab) +{ + return tab ? tab->offset : -1; +} + +/** + * blkid_partition_get_table: + * @par: partition + * + * The "parttable" describes partition table. The table is usually the same for + * all partitions -- except nested partition tables. + * + * For example bsd, solaris, etc. use a nested partition table within + * standard primary dos partition: + * + * + * + * + * -- dos partition table + * 0: sda1 dos primary partition + * 1: sda2 dos primary partition + * -- bsd partition table (with in sda2) + * 2: sda5 bds partition + * 3: sda6 bds partition + * + * + * + * + * The library does not to use a separate partition table object for dos logical + * partitions (partitions within extended partition). It's possible to + * differentiate between logical, extended and primary partitions by + * + * blkid_partition_is_{extended,primary,logical}(). + * + * Returns: partition table object or NULL in case of error. + */ +blkid_parttable blkid_partition_get_table(blkid_partition par) +{ + return par ? par->tab : NULL; +} + +static int partition_get_logical_type(blkid_partition par) +{ + blkid_parttable tab; + + if (!par) + return -1; + + tab = blkid_partition_get_table(par); + if (!tab || !tab->type) + return -1; + + if (tab->parent) + return 'L'; /* report nested partitions as logical */ + + if (!strcmp(tab->type, "dos")) { + if (par->partno > 4) + return 'L'; /* logical */ + + if(par->type == BLKID_DOS_EXTENDED_PARTITION || + par->type == BLKID_W95_EXTENDED_PARTITION || + par->type == BLKID_LINUX_EXTENDED_PARTITION) + return 'E'; + } + return 'P'; +} + +/** + * blkid_partition_is_primary: + * @par: partition + * + * Note, this function returns FALSE for DOS extended partitions and + * all partitions in nested partition tables. + * + * Returns: 1 if the partitions is primary partition or 0 if not. + */ +int blkid_partition_is_primary(blkid_partition par) +{ + return partition_get_logical_type(par) == 'P' ? TRUE : FALSE; +} + +/** + * blkid_partition_is_extended: + * @par: partition + * + * Returns: 1 if the partitions is extended (dos, windows or linux) + * partition or 0 if not. + */ +int blkid_partition_is_extended(blkid_partition par) +{ + return partition_get_logical_type(par) == 'E' ? TRUE : FALSE; +} + +/** + * blkid_partition_is_logical: + * @par: partition + * + * Note that this function returns TRUE for all partitions in all + * nested partition tables (e.g. BSD labels). + * + * Returns: 1 if the partitions is logical partition or 0 if not. + */ +int blkid_partition_is_logical(blkid_partition par) +{ + return partition_get_logical_type(par) == 'L' ? TRUE : FALSE; +} + +static void set_string(unsigned char *item, size_t max, + const unsigned char *data, size_t len) +{ + if (len >= max) + len = max - 1; + + memcpy(item, data, len); + item[len] = '\0'; + + blkid_rtrim_whitespace(item); +} + +int blkid_partition_set_name(blkid_partition par, + const unsigned char *name, size_t len) +{ + if (!par) + return -1; + + set_string(par->name, sizeof(par->name), name, len); + return 0; +} + +int blkid_partition_set_utf8name(blkid_partition par, const unsigned char *name, + size_t len, int enc) +{ + if (!par) + return -1; + + blkid_encode_to_utf8(enc, par->name, sizeof(par->name), name, len); + blkid_rtrim_whitespace(par->name); + return 0; +} + +int blkid_partition_set_uuid(blkid_partition par, const unsigned char *uuid) +{ + if (!par) + return -1; + + blkid_unparse_uuid(uuid, par->uuid, sizeof(par->uuid)); + return 0; +} + +/** + * blkid_partition_get_name: + * @par: partition + * + * Returns: partition name string if supported by PT (e.g. Mac) or NULL. + */ +const char *blkid_partition_get_name(blkid_partition par) +{ + return par && *par->name ? (char *) par->name : NULL; +} + +/** + * blkid_partition_get_uuid: + * @par: partition + * + * Returns: partition UUID string if supported by PT (e.g. GPT) or NULL. + */ +const char *blkid_partition_get_uuid(blkid_partition par) +{ + return par && *par->uuid ? par->uuid : NULL; +} + +/** + * blkid_partition_get_partno: + * @par: partition + * + * Returns: proposed partitin number (e.g. 'N' from sda'N') or -1 in case of + * error. Note that the number is generate by library independenly on your OS. + */ +int blkid_partition_get_partno(blkid_partition par) +{ + return par ? par->partno : -1; +} + +/** + * blkid_partition_get_start: + * @par: partition + * + * Be careful if you _not_ probe whole disk: + * + * 1) the offset is usully relative to begin of the disk -- but if you probe a + * fragment of the disk only -- then the offset could be still relative to + * the begin of the disk rather that relative to the fragment. + * + * 2) the offset for nested partitions could be releative to parent (e.g. Solaris) + * _or_ relative to the begin of the whole disk (e.g. bsd). + * + * You don't have to care about such details if you proble whole disk. In such + * a case libblkid always returns the offset relative to the begin of the disk. + * + * Returns: start of the partition (in 512-sectors). + */ +blkid_loff_t blkid_partition_get_start(blkid_partition par) +{ + return par ? par->start : -1; +} + +/** + * blkid_partition_get_size: + * @par: partition + * + * WARNING: be very careful when you work with MS-DOS extended partitions. The + * library always returns full size of the partition. If you want add + * the partition to the Linux system (BLKPG_ADD_PARTITION ioctl) you + * need to reduce the size of the partition to 1 or 2 blocks. The + * rest of the partition has to be unaccessible for mkfs or mkswap + * programs, we need a small space for boot loaders only. + * + * For some unknown reason this (safe) practice is not to used for + * nested BSD, Solaris, ..., partition tables in Linux kernel. + * + * Returns: size of the partition (in 512-sectors). + */ +blkid_loff_t blkid_partition_get_size(blkid_partition par) +{ + return par ? par->size : -1; +} + +/** + * blkid_partition_get_type: + * @par: partition + * + * Returns: partition type. + */ +int blkid_partition_get_type(blkid_partition par) +{ + return par ? par->type : 0; +} + +/* Sets partition 'type' for PT where the type is defined by string rather + * than by number + */ +int blkid_partition_set_type_string(blkid_partition par, + const unsigned char *type, size_t len) +{ + if (!par) + return -1; + + set_string((unsigned char *) par->typestr, + sizeof(par->typestr), type, len); + return 0; +} + +/* Sets partition 'type' for PT where the type is defined by UUIDrather + * than by number + */ +int blkid_partition_set_type_uuid(blkid_partition par, const unsigned char *uuid) +{ + if (!par) + return -1; + + blkid_unparse_uuid(uuid, par->typestr, sizeof(par->typestr)); + return 0; +} + +/** + * blkid_partition_get_type_string: + * @par: partition + * + * The type string is supported by a small subset of partition tables (e.g Mac + * and EFI GPT). Note that GPT uses type UUID and this function returns this + * UUID as string. + * + * Returns: partition type string or NULL. + */ +const char *blkid_partition_get_type_string(blkid_partition par) +{ + return par && *par->typestr ? par->typestr : NULL; +} + + +int blkid_partition_set_flags(blkid_partition par, unsigned long long flags) +{ + if (!par) + return -1; + par->flags = flags; + return 0; +} + +/** + * blkid_partition_get_flags + * @par: partition + * + * Returns: partition flags (or attributes for gpt). + */ +unsigned long long blkid_partition_get_flags(blkid_partition par) +{ + return par ? par->flags : 0; +} + diff --git a/libblkid/src/partitions/partitions.h b/libblkid/src/partitions/partitions.h new file mode 100644 index 00000000..c4ccd3b6 --- /dev/null +++ b/libblkid/src/partitions/partitions.h @@ -0,0 +1,62 @@ +#ifndef BLKID_PARTITIONS_H +#define BLKID_PARTITIONS_H + +#include "blkidP.h" +#include "blkid_parttypes.h" + +extern int blkid_partitions_get_flags(blkid_probe pr); + +extern blkid_parttable blkid_partlist_new_parttable(blkid_partlist ls, + const char *type, blkid_loff_t offset); + +extern blkid_partition blkid_partlist_add_partition(blkid_partlist ls, + blkid_parttable tab, + blkid_loff_t start, blkid_loff_t size); + +extern int blkid_partlist_set_partno(blkid_partlist ls, int partno); +extern int blkid_partlist_increment_partno(blkid_partlist ls); + +extern blkid_partition blkid_partlist_get_parent(blkid_partlist ls); + +extern int blkid_partitions_do_subprobe(blkid_probe pr, + blkid_partition parent, const struct blkid_idinfo *id); + +extern int blkid_partitions_need_typeonly(blkid_probe pr); +extern int blkid_is_nested_dimension(blkid_partition par, + blkid_loff_t start, blkid_loff_t size); + +extern int blkid_partition_set_name(blkid_partition par, + const unsigned char *name, size_t len); + +extern int blkid_partition_set_utf8name(blkid_partition par, + const unsigned char *name, size_t len, int enc); + +extern int blkid_partition_set_uuid(blkid_partition par, + const unsigned char *uuid); + +extern int blkid_partition_set_type(blkid_partition par, int type); + +extern int blkid_partition_set_type_string(blkid_partition par, + const unsigned char *type, size_t len); + +extern int blkid_partition_set_type_uuid(blkid_partition par, + const unsigned char *uuid); + +extern int blkid_partition_set_flags(blkid_partition par, unsigned long long flags); + +/* + * partition probers + */ +extern const struct blkid_idinfo aix_pt_idinfo; +extern const struct blkid_idinfo bsd_pt_idinfo; +extern const struct blkid_idinfo unixware_pt_idinfo; +extern const struct blkid_idinfo solaris_x86_pt_idinfo; +extern const struct blkid_idinfo sun_pt_idinfo; +extern const struct blkid_idinfo sgi_pt_idinfo; +extern const struct blkid_idinfo mac_pt_idinfo; +extern const struct blkid_idinfo dos_pt_idinfo; +extern const struct blkid_idinfo minix_pt_idinfo; +extern const struct blkid_idinfo gpt_pt_idinfo; +extern const struct blkid_idinfo ultrix_pt_idinfo; + +#endif /* BLKID_PARTITIONS_H */ diff --git a/libblkid/src/partitions/sgi.c b/libblkid/src/partitions/sgi.c new file mode 100644 index 00000000..945ead54 --- /dev/null +++ b/libblkid/src/partitions/sgi.c @@ -0,0 +1,158 @@ +/* + * sgi partition parsing code + * + * Copyright (C) 2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * + */ +#include +#include +#include +#include + +#include "partitions.h" + +#define SGI_MAXPARTITIONS 16 + +/* partition type */ +#define SGI_TYPE_VOLHDR 0x00 +#define SGI_TYPE_VOLULME 0x06 /* entire disk */ + +struct sgi_device_parameter { + unsigned char skew; + unsigned char gap1; + unsigned char gap2; + unsigned char sparecyl; + + uint16_t pcylcount; + uint16_t head_vol0; + uint16_t ntrks; /* tracks in cyl 0 or vol 0 */ + + unsigned char cmd_tag_queue_depth; + unsigned char unused0; + + uint16_t unused1; + uint16_t nsect; /* sectors/tracks in cyl 0 or vol 0 */ + uint16_t bytes; + uint16_t ilfact; + uint32_t flags; /* controller flags */ + uint32_t datarate; + uint32_t retries_on_error; + uint32_t ms_per_word; + uint16_t xylogics_gap1; + uint16_t xylogics_syncdelay; + uint16_t xylogics_readdelay; + uint16_t xylogics_gap2; + uint16_t xylogics_readgate; + uint16_t xylogics_writecont; +} __attribute__((packed)); + +struct sgi_disklabel { + uint32_t magic; /* magic number */ + uint16_t root_part_num; /* # root partition */ + uint16_t swap_part_num; /* # swap partition */ + unsigned char boot_file[16]; /* name of boot file */ + + struct sgi_device_parameter devparam; /* not used now */ + + struct sgi_volume { + unsigned char name[8]; /* name of volume */ + uint32_t block_num; /* logical block number */ + uint32_t num_bytes; /* how big, in bytes */ + } __attribute__((packed)) volume[15]; + + struct sgi_partition { + uint32_t num_blocks; /* size in logical blocks */ + uint32_t first_block; /* first logical block */ + uint32_t type; /* type of this partition */ + } __attribute__((packed)) partitions[SGI_MAXPARTITIONS]; + + /* checksum is the 32bit 2's complement sum of the disklabel */ + uint32_t csum; /* disk label checksum */ + uint32_t padding; /* padding */ +} __attribute__((packed)); + +static uint32_t count_checksum(struct sgi_disklabel *label) +{ + int i; + uint32_t *ptr = (uint32_t *) label; + uint32_t sum = 0; + + i = sizeof(*label) / sizeof(*ptr); + + while (i--) + sum += be32_to_cpu(ptr[i]); + + return sum; +} + + +static int probe_sgi_pt(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct sgi_disklabel *l; + struct sgi_partition *p; + blkid_parttable tab = NULL; + blkid_partlist ls; + int i; + + l = (struct sgi_disklabel *) blkid_probe_get_sector(pr, 0); + if (!l) + goto nothing; + + if (count_checksum(l)) { + DBG(DEBUG_LOWPROBE, printf( + "detected corrupted sgi disk label -- ignore\n")); + goto nothing; + } + + if (blkid_partitions_need_typeonly(pr)) + /* caller does not ask for details about partitions */ + return 0; + + ls = blkid_probe_get_partlist(pr); + if (!ls) + goto err; + + tab = blkid_partlist_new_parttable(ls, "sgi", 0); + if (!tab) + goto err; + + for(i = 0, p = &l->partitions[0]; i < SGI_MAXPARTITIONS; i++, p++) { + uint32_t size = be32_to_cpu(p->num_blocks); + uint32_t start = be32_to_cpu(p->first_block); + uint32_t type = be32_to_cpu(p->type); + blkid_partition par; + + if (size == 0 || type == SGI_TYPE_VOLULME || + type == SGI_TYPE_VOLHDR) { + blkid_partlist_increment_partno(ls); + continue; + } + par = blkid_partlist_add_partition(ls, tab, start, size); + if (!par) + goto err; + + blkid_partition_set_type(par, type); + } + + return 0; + +nothing: + return 1; +err: + return -1; +} + +const struct blkid_idinfo sgi_pt_idinfo = +{ + .name = "sgi", + .probefunc = probe_sgi_pt, + .magics = + { + { .magic = "\x0B\xE5\xA9\x41", .len = 4 }, + { NULL } + } +}; + diff --git a/libblkid/src/partitions/solaris_x86.c b/libblkid/src/partitions/solaris_x86.c new file mode 100644 index 00000000..ce102bd8 --- /dev/null +++ b/libblkid/src/partitions/solaris_x86.c @@ -0,0 +1,150 @@ +/* + * Solaris x86 partition parsing code + * + * Copyright (C) 2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include + +#include "partitions.h" + +/* + * Solaris-x86 is always within primary dos partition (nested PT table). The + * solaris-x86 vtoc allows to split the entire partition to "slices". The + * offset (start) of the slice is always relatively to the primary dos + * partition. + * + * Note that Solaris-SPARC uses entire disk with a different partitionning + * scheme. + */ + +/* some other implementation than Linux kernel assume 8 partitions only */ +#define SOLARIS_MAXPARTITIONS 16 + +/* disklabel (vtoc) location */ +#define SOLARIS_SECTOR 1 /* in 512-sectors */ +#define SOLARIS_OFFSET (SOLARIS_SECTOR << 9) /* in bytes */ +#define SOLARIS_MAGICOFFSET (SOLARIS_OFFSET + 12) /* v_sanity offset in bytes */ + +/* slice tags */ +#define SOLARIS_TAG_WHOLEDISK 5 + +struct solaris_slice { + uint16_t s_tag; /* ID tag of partition */ + uint16_t s_flag; /* permission flags */ + uint32_t s_start; /* start sector no of partition */ + uint32_t s_size; /* # of blocks in partition */ +} __attribute__((packed)); + +struct solaris_vtoc { + unsigned int v_bootinfo[3]; /* info needed by mboot (unsupported) */ + + uint32_t v_sanity; /* to verify vtoc sanity */ + uint32_t v_version; /* layout version */ + char v_volume[8]; /* volume name */ + uint16_t v_sectorsz; /* sector size in bytes */ + uint16_t v_nparts; /* number of partitions */ + unsigned int v_reserved[10]; /* free space */ + + struct solaris_slice v_slice[SOLARIS_MAXPARTITIONS]; /* slices */ + + unsigned int timestamp[SOLARIS_MAXPARTITIONS]; /* timestamp (unsupported) */ + char v_asciilabel[128]; /* for compatibility */ +} __attribute__((packed)); + +static int probe_solaris_pt(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct solaris_vtoc *l; /* disk label */ + struct solaris_slice *p; /* partitsion */ + blkid_parttable tab = NULL; + blkid_partition parent; + blkid_partlist ls; + int i; + uint16_t nparts; + + l = (struct solaris_vtoc *) blkid_probe_get_sector(pr, SOLARIS_SECTOR); + if (!l) + goto nothing; + + if (le32_to_cpu(l->v_version) != 1) { + DBG(DEBUG_LOWPROBE, printf( + "WARNING: unsupported solaris x86 version %d, ignore\n", + le32_to_cpu(l->v_version))); + goto nothing; + } + + if (blkid_partitions_need_typeonly(pr)) + /* caller does not ask for details about partitions */ + return 0; + + ls = blkid_probe_get_partlist(pr); + if (!ls) + goto err; + + parent = blkid_partlist_get_parent(ls); + + tab = blkid_partlist_new_parttable(ls, "solaris", SOLARIS_OFFSET); + if (!tab) + goto err; + + nparts = le16_to_cpu(l->v_nparts); + if (nparts > SOLARIS_MAXPARTITIONS) + nparts = SOLARIS_MAXPARTITIONS; + + for (i = 1, p = &l->v_slice[0]; i < nparts; i++, p++) { + + uint32_t start = le32_to_cpu(p->s_start); + uint32_t size = le32_to_cpu(p->s_size); + blkid_partition par; + + if (size == 0 || le16_to_cpu(p->s_tag) == SOLARIS_TAG_WHOLEDISK) + continue; + + if (parent) + /* Solaris slices are relative to the parent (primary + * DOS partition) */ + start += blkid_partition_get_start(parent); + + if (parent && !blkid_is_nested_dimension(parent, start, size)) { + DBG(DEBUG_LOWPROBE, printf( + "WARNING: solaris partition (%d) overflow " + "detected, ignore\n", i)); + continue; + } + + par = blkid_partlist_add_partition(ls, tab, start, size); + if (!par) + goto err; + + blkid_partition_set_type(par, le16_to_cpu(p->s_tag)); + blkid_partition_set_flags(par, le16_to_cpu(p->s_flag)); + } + + return 0; + +nothing: + return 1; +err: + return -1; +} + +const struct blkid_idinfo solaris_x86_pt_idinfo = +{ + .name = "solaris", + .probefunc = probe_solaris_pt, + .magics = + { + { + .magic = "\xEE\xDE\x0D\x60", /* little-endian magic string */ + .len = 4, /* v_sanity size in bytes */ + .sboff = SOLARIS_MAGICOFFSET /* offset of v_sanity */ + }, + { NULL } + } +}; + diff --git a/libblkid/src/partitions/sun.c b/libblkid/src/partitions/sun.c new file mode 100644 index 00000000..dffab24c --- /dev/null +++ b/libblkid/src/partitions/sun.c @@ -0,0 +1,187 @@ +/* + * sun (solaris-sparc) partition parsing code + * + * Copyright (C) 2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include + +#include "partitions.h" + +/* Supported VTOC setting */ +#define SUN_VTOC_SANITY 0x600DDEEE /* magic number */ +#define SUN_VTOC_VERSION 1 + +#define SUN_MAXPARTITIONS 8 + +/* Partition IDs */ +#define SUN_TAG_WHOLEDISK 0x05 + +struct sun_disklabel { + unsigned char info[128]; /* Informative text string */ + + struct sun_vtoc { + uint32_t version; /* version */ + char volume[8]; /* volume name */ + uint16_t nparts; /* num of partitions */ + + struct sun_info { /* partition information */ + uint16_t id; /* tag */ + uint16_t flags; + } __attribute__ ((packed)) infos[8]; + + uint16_t padding; /* padding */ + uint32_t bootinfo[3]; /* info needed by mboot */ + uint32_t sanity; /* magic number */ + uint32_t reserved[10]; /* padding */ + uint32_t timestamp[8]; /* partition timestamp */ + } __attribute__ ((packed)) vtoc; + + uint32_t write_reinstruct; /* sectors to skip, writes */ + uint32_t read_reinstruct; /* sectors to skip, reads */ + unsigned char spare[148]; /* padding */ + uint16_t rspeed; /* disk rotational speed */ + uint16_t pcylcount; /* physical cylinder count */ + uint16_t sparecyl; /* extra sects per cylinder */ + uint16_t obs1; + uint16_t obs2; + uint16_t ilfact; /* interleave factor */ + uint16_t ncyl; /* data cylinder count */ + uint16_t nacyl; /* alt. cylinder count */ + uint16_t ntrks; /* tracks per cylinder <---- */ + uint16_t nsect; /* sectors per track <---- */ + uint16_t obs3; + uint16_t obs4; + + struct sun_partition { /* partitions */ + uint32_t start_cylinder; + uint32_t num_sectors; + } __attribute__ ((packed)) partitions[8]; + + uint16_t magic; /* magic number */ + uint16_t csum; /* label xor'd checksum */ +} __attribute__ ((packed)); + + +uint16_t count_checksum(struct sun_disklabel *label) +{ + uint16_t *ptr = ((uint16_t *) (label + 1)) - 1; + uint16_t sum; + + for (sum = 0; ptr >= ((uint16_t *) label);) + sum ^= *ptr--; + + return sum; +} + +static int probe_sun_pt(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct sun_disklabel *l; + struct sun_partition *p; + blkid_parttable tab = NULL; + blkid_partlist ls; + uint16_t nparts; + blkid_loff_t spc; + int i, use_vtoc; + + l = (struct sun_disklabel *) blkid_probe_get_sector(pr, 0); + if (!l) + goto nothing; + + if (count_checksum(l)) { + DBG(DEBUG_LOWPROBE, printf( + "detected corrupted sun disk label -- ignore\n")); + goto nothing; + } + + if (blkid_partitions_need_typeonly(pr)) + /* caller does not ask for details about partitions */ + return 0; + + ls = blkid_probe_get_partlist(pr); + if (!ls) + goto err; + + tab = blkid_partlist_new_parttable(ls, "sun", 0); + if (!tab) + goto err; + + /* sectors per cylinder (partition offset is in cylinders...) */ + spc = be16_to_cpu(l->ntrks) * be16_to_cpu(l->nsect); + + DBG(DEBUG_LOWPROBE, + printf("Sun VTOC sanity=%u version=%u nparts=%u\n", + be32_to_cpu(l->vtoc.sanity), + be32_to_cpu(l->vtoc.version), + be16_to_cpu(l->vtoc.nparts))); + + /* Check to see if we can use the VTOC table */ + use_vtoc = ((be32_to_cpu(l->vtoc.sanity) == SUN_VTOC_SANITY) && + (be32_to_cpu(l->vtoc.version) == SUN_VTOC_VERSION) && + (be16_to_cpu(l->vtoc.nparts) <= SUN_MAXPARTITIONS)); + + /* Use 8 partition entries if not specified in validated VTOC */ + nparts = use_vtoc ? be16_to_cpu(l->vtoc.nparts) : SUN_MAXPARTITIONS; + + /* + * So that old Linux-Sun partitions continue to work, + * alow the VTOC to be used under the additional condition ... + */ + use_vtoc = use_vtoc || !(l->vtoc.sanity || l->vtoc.version || l->vtoc.nparts); + + for (i = 0, p = l->partitions; i < nparts; i++, p++) { + + blkid_loff_t start, size; + uint16_t type = 0, flags = 0; + blkid_partition par; + + start = be32_to_cpu(p->start_cylinder) * spc; + size = be32_to_cpu(p->num_sectors); + if (use_vtoc) { + type = be16_to_cpu(l->vtoc.infos[i].id); + flags = be16_to_cpu(l->vtoc.infos[i].flags); + } + + if (type == SUN_TAG_WHOLEDISK || !size) { + blkid_partlist_increment_partno(ls); + continue; + } + par = blkid_partlist_add_partition(ls, tab, start, size); + if (!par) + goto err; + + if (type) + blkid_partition_set_type(par, type); + if (flags) + blkid_partition_set_flags(par, flags); + } + return 0; + +nothing: + return 1; +err: + return -1; +} + + +const struct blkid_idinfo sun_pt_idinfo = +{ + .name = "sun", + .probefunc = probe_sun_pt, + .magics = + { + { + .magic = "\xDA\xBE", /* big-endian magic string */ + .len = 2, + .sboff = offsetof(struct sun_disklabel, magic) + }, + { NULL } + } +}; + diff --git a/libblkid/src/partitions/ultrix.c b/libblkid/src/partitions/ultrix.c new file mode 100644 index 00000000..cc848d0a --- /dev/null +++ b/libblkid/src/partitions/ultrix.c @@ -0,0 +1,88 @@ +/* + * uktrix partition parsing code + * + * Copyright (C) 2010 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * + */ +#include +#include +#include +#include + +#include "partitions.h" + +#define ULTRIX_MAXPARTITIONS 8 +#define ULTRIX_MAGIC 0x032957 + +/* sector with partition table */ +#define ULTRIX_SECTOR ((16384 - sizeof(struct ultrix_disklabel)) >> 9) +/* position of partition table within ULTRIX_SECTOR */ +#define ULTRIX_OFFSET (512 - sizeof(struct ultrix_disklabel)) + +struct ultrix_disklabel { + int32_t pt_magic; /* magic no. indicating part. info exits */ + int32_t pt_valid; /* set by driver if pt is current */ + struct pt_info { + int32_t pi_nblocks; /* no. of sectors */ + uint32_t pi_blkoff; /* block offset for start */ + } pt_part[ULTRIX_MAXPARTITIONS]; +} __attribute__((packed)); + + +static int probe_ultrix_pt(blkid_probe pr, const struct blkid_idmag *mag) +{ + unsigned char *data; + struct ultrix_disklabel *l; + blkid_parttable tab = NULL; + blkid_partlist ls; + int i; + + data = blkid_probe_get_sector(pr, ULTRIX_SECTOR); + if (!data) + goto nothing; + + l = (struct ultrix_disklabel *) (data + ULTRIX_OFFSET); + + if (l->pt_magic != ULTRIX_MAGIC || l->pt_valid != 1) + goto nothing; + + if (blkid_partitions_need_typeonly(pr)) + /* caller does not ask for details about partitions */ + return 0; + + ls = blkid_probe_get_partlist(pr); + if (!ls) + goto err; + + tab = blkid_partlist_new_parttable(ls, "ultrix", 0); + if (!tab) + goto err; + + for (i = 0; i < ULTRIX_MAXPARTITIONS; i++) { + if (!l->pt_part[i].pi_nblocks) + blkid_partlist_increment_partno(ls); + else { + if (!blkid_partlist_add_partition(ls, tab, + l->pt_part[i].pi_blkoff, + l->pt_part[i].pi_nblocks)) + goto err; + } + } + + return 0; +nothing: + return 1; +err: + return -1; +} + +const struct blkid_idinfo ultrix_pt_idinfo = +{ + .name = "ultrix", + .probefunc = probe_ultrix_pt, + .magics = BLKID_NONE_MAGIC +}; + diff --git a/libblkid/src/partitions/unixware.c b/libblkid/src/partitions/unixware.c new file mode 100644 index 00000000..ac11a46d --- /dev/null +++ b/libblkid/src/partitions/unixware.c @@ -0,0 +1,193 @@ +/* + * unixware partition parsing code + * + * Copyright (C) 2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * + * + * The intersting information about unixware PT: + * - Linux kernel / partx + * - vtoc(7) SCO UNIX command man page + * - evms source code (http://evms.sourceforge.net/) + * - vxtools source code (http://martin.hinner.info/fs/vxfs/) + */ +#include +#include +#include +#include + +#include "partitions.h" + +/* disklabel location */ +#define UNIXWARE_SECTOR 29 +#define UNIXWARE_OFFSET (UNIXWARE_SECTOR << 9) /* offset in bytes */ +#define UNIXWARE_KBOFFSET (UNIXWARE_OFFSET >> 10) /* offset in 1024-blocks */ + +/* disklabel->d_magic offset within the last 1024 block */ +#define UNIXWARE_MAGICOFFSET (UNIXWARE_OFFSET - UNIXWARE_KBOFFSET + 4) + +#define UNIXWARE_VTOCMAGIC 0x600DDEEEUL +#define UNIXWARE_MAXPARTITIONS 16 + +/* unixware_partition->s_label flags */ +#define UNIXWARE_TAG_UNUSED 0x0000 /* unused partition */ +#define UNIXWARE_TAG_BOOT 0x0001 /* boot fs */ +#define UNIXWARE_TAG_ROOT 0x0002 /* root fs */ +#define UNIXWARE_TAG_SWAP 0x0003 /* swap fs */ +#define UNIXWARE_TAG_USER 0x0004 /* user fs */ +#define UNIXWARE_TAG_ENTIRE_DISK 0x0005 /* whole disk */ +#define UNIXWARE_TAG_ALT_S 0x0006 /* alternate sector space */ +#define UNIXWARE_TAG_OTHER 0x0007 /* non unix */ +#define UNIXWARE_TAG_ALT_T 0x0008 /* alternate track space */ +#define UNIXWARE_TAG_STAND 0x0009 /* stand partition */ +#define UNIXWARE_TAG_VAR 0x000a /* var partition */ +#define UNIXWARE_TAG_HOME 0x000b /* home partition */ +#define UNIXWARE_TAG_DUMP 0x000c /* dump partition */ +#define UNIXWARE_TAG_ALT_ST 0x000d /* alternate sector track */ +#define UNIXWARE_TAG_VM_PUBLIC 0x000e /* volume mgt public partition */ +#define UNIXWARE_TAG_VM_PRIVATE 0x000f /* volume mgt private partition */ + + +/* unixware_partition->s_flags flags */ +#define UNIXWARE_FLAG_VALID 0x0200 + +struct unixware_partition { + uint16_t s_label; /* partition label (tag) */ + uint16_t s_flags; /* permission flags */ + uint32_t start_sect; /* starting sector */ + uint32_t nr_sects; /* number of sectors */ +} __attribute__((packed)); + +struct unixware_disklabel { + uint32_t d_type; /* drive type */ + uint32_t d_magic; /* the magic number */ + uint32_t d_version; /* version number */ + char d_serial[12]; /* serial number of the device */ + uint32_t d_ncylinders; /* # of data cylinders per device */ + uint32_t d_ntracks; /* # of tracks per cylinder */ + uint32_t d_nsectors; /* # of data sectors per track */ + uint32_t d_secsize; /* # of bytes per sector */ + uint32_t d_part_start; /* # of first sector of this partition */ + uint32_t d_unknown1[12]; /* ? */ + uint32_t d_alt_tbl; /* byte offset of alternate table */ + uint32_t d_alt_len; /* byte length of alternate table */ + uint32_t d_phys_cyl; /* # of physical cylinders per device */ + uint32_t d_phys_trk; /* # of physical tracks per cylinder */ + uint32_t d_phys_sec; /* # of physical sectors per track */ + uint32_t d_phys_bytes; /* # of physical bytes per sector */ + uint32_t d_unknown2; /* ? */ + uint32_t d_unknown3; /* ? */ + uint32_t d_pad[8]; /* pad */ + + struct unixware_vtoc { + uint32_t v_magic; /* the magic number */ + uint32_t v_version; /* version number */ + char v_name[8]; /* volume name */ + uint16_t v_nslices; /* # of partitions */ + uint16_t v_unknown1; /* ? */ + uint32_t v_reserved[10]; /* reserved */ + + struct unixware_partition + v_slice[UNIXWARE_MAXPARTITIONS]; /* partition */ + } __attribute__((packed)) vtoc; +}; + +static int probe_unixware_pt(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct unixware_disklabel *l; + struct unixware_partition *p; + blkid_parttable tab = NULL; + blkid_partition parent; + blkid_partlist ls; + int i; + + l = (struct unixware_disklabel *) + blkid_probe_get_sector(pr, UNIXWARE_SECTOR); + if (!l) + goto nothing; + + if (le32_to_cpu(l->vtoc.v_magic) != UNIXWARE_VTOCMAGIC) + goto nothing; + + if (blkid_partitions_need_typeonly(pr)) + /* caller does not ask for details about partitions */ + return 0; + + ls = blkid_probe_get_partlist(pr); + if (!ls) + goto err; + + parent = blkid_partlist_get_parent(ls); + + tab = blkid_partlist_new_parttable(ls, "unixware", UNIXWARE_OFFSET); + if (!tab) + goto err; + + /* Skip the first partition that describe whole disk + */ + for (i = 1, p = &l->vtoc.v_slice[1]; + i < UNIXWARE_MAXPARTITIONS; i++, p++) { + + uint32_t start, size; + uint16_t tag, flg; + blkid_partition par; + + tag = le16_to_cpu(p->s_label); + flg = le16_to_cpu(p->s_flags); + + if (tag == UNIXWARE_TAG_UNUSED || + tag == UNIXWARE_TAG_ENTIRE_DISK || + flg != UNIXWARE_FLAG_VALID) + continue; + + start = le32_to_cpu(p->start_sect); + size = le32_to_cpu(p->nr_sects); + + if (parent && !blkid_is_nested_dimension(parent, start, size)) { + DBG(DEBUG_LOWPROBE, printf( + "WARNING: unixware partition (%d) overflow " + "detected, ignore\n", i)); + continue; + } + + par = blkid_partlist_add_partition(ls, tab, start, size); + if (!par) + goto err; + + blkid_partition_set_type(par, tag); + blkid_partition_set_flags(par, flg); + } + + return 0; + +nothing: + return 1; +err: + return -1; +} + + +/* + * The unixware partition table is within primary DOS partition. The PT is + * located on 29 sector, PT magic string is d_magic member of 'struct + * unixware_disklabel'. + */ +const struct blkid_idinfo unixware_pt_idinfo = +{ + .name = "unixware", + .probefunc = probe_unixware_pt, + .minsz = 1024 * 1440 + 1, /* ignore floppies */ + .magics = + { + { + .magic = "\x0D\x60\xE5\xCA", /* little-endian magic string */ + .len = 4, /* d_magic size in bytes */ + .kboff = UNIXWARE_KBOFFSET, + .sboff = UNIXWARE_MAGICOFFSET + }, + { NULL } + } +}; + diff --git a/libblkid/src/probe.c b/libblkid/src/probe.c new file mode 100644 index 00000000..85db814f --- /dev/null +++ b/libblkid/src/probe.c @@ -0,0 +1,1509 @@ +/* + * Low-level libblkid probing API + * + * Copyright (C) 2008-2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ + +/** + * SECTION: lowprobe + * @title: Low-level probing + * @short_description: low-level prober initialization + * + * The low-level probing routines always and directly read information from + * the selected (see blkid_probe_set_device()) device. + * + * The probing routines are grouped together into separate chains. Currently, + * the library provides superblocks, partitions and topology chains. + * + * The probing routines is possible to filter (enable/disable) by type (e.g. + * fstype "vfat" or partype "gpt") or by usage flags (e.g. BLKID_USAGE_RAID). + * These filters are per-chain. Note that always when you touch the chain + * filter the current probing position is reseted and probing starts from + * scratch. It means that the chain filter should not be modified during + * probing, for example in loop where you call blkid_do_probe(). + * + * For more details see the chain specific documentation. + * + * The low-level API provides two ways how access to probing results. + * + * 1. The NAME=value (tag) interface. This interface is older and returns all data + * as strings. This interface is generic for all chains. + * + * 2. The binary interfaces. These interfaces return data in the native formats. + * The interface is always specific to the probing chain. + * + * Note that the previous probing result (binary or NAME=value) is always + * zeroized when a chain probing function is called. For example + * + * + * + * blkid_probe_enable_partitions(pr, TRUE); + * blkid_probe_enable_superblocks(pr, FALSE); + * + * blkid_do_safeprobe(pr); + * + * + * + * overwrites the previous probing result for the partitions chain, the superblocks + * result is not modified. + */ + +/** + * SECTION: lowprobe-tags + * @title: Low-level tags + * @short_description: generic NAME=value interface. + * + * The probing routines inside the chain are mutually exclusive by default -- + * only few probing routines are marked as "tolerant". The "tolerant" probing + * routines are used for filesystem which can share the same device with any + * other filesystem. The blkid_do_safeprobe() checks for the "tolerant" flag. + * + * The SUPERBLOCKS chain is enabled by default. The all others chains is + * necessary to enable by blkid_probe_enable_'CHAINNAME'(). See chains specific + * documentation. + * + * The blkid_do_probe() function returns a result from only one probing + * routine, and the next call from the next probing routine. It means you need + * to call the function in loop, for example: + * + * + * + * while((blkid_do_probe(pr) == 0) + * ... use result ... + * + * + * + * The blkid_do_safeprobe() is the same as blkid_do_probe(), but returns only + * first probing result for every enabled chain. This function checks for + * ambivalent results (e.g. more "intolerant" filesystems superblocks on the + * device). + * + * The probing result is set of NAME=value pairs (the NAME is always unique). + */ + +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_LINUX_CDROM_H +#include +#endif +#ifdef HAVE_SYS_STAT_H +#include +#endif +#ifdef HAVE_ERRNO_H +#include +#endif +#include +#include +#include + +#ifdef HAVE_LIBUUID +# include +#endif + +#include "blkidP.h" + +/* chains */ +extern const struct blkid_chaindrv superblocks_drv; +extern const struct blkid_chaindrv topology_drv; +extern const struct blkid_chaindrv partitions_drv; + +/* + * All supported chains + */ +static const struct blkid_chaindrv *chains_drvs[] = { + [BLKID_CHAIN_SUBLKS] = &superblocks_drv, + [BLKID_CHAIN_TOPLGY] = &topology_drv, + [BLKID_CHAIN_PARTS] = &partitions_drv +}; + +static void blkid_probe_reset_vals(blkid_probe pr); +static void blkid_probe_reset_buffer(blkid_probe pr); + +/** + * blkid_new_probe: + * + * Returns: a pointer to the newly allocated probe struct. + */ +blkid_probe blkid_new_probe(void) +{ + int i; + blkid_probe pr; + + blkid_init_debug(0); + pr = calloc(1, sizeof(struct blkid_struct_probe)); + if (!pr) + return NULL; + + DBG(DEBUG_LOWPROBE, printf("allocate a new probe %p\n", pr)); + + /* initialize chains */ + for (i = 0; i < BLKID_NCHAINS; i++) { + pr->chains[i].driver = chains_drvs[i]; + pr->chains[i].flags = chains_drvs[i]->dflt_flags; + pr->chains[i].enabled = chains_drvs[i]->dflt_enabled; + } + INIT_LIST_HEAD(&pr->buffers); + return pr; +} + +/* + * Clone @parent, the new clone shares all, but except: + * + * - probing result + * - bufferes if another device (or offset) is set to the prober + */ +blkid_probe blkid_clone_probe(blkid_probe parent) +{ + blkid_probe pr; + + if (!parent) + return NULL; + + DBG(DEBUG_LOWPROBE, printf("allocate a probe clone\n")); + + pr = blkid_new_probe(); + if (!pr) + return NULL; + + pr->fd = parent->fd; + pr->off = parent->off; + pr->size = parent->size; + pr->devno = parent->devno; + pr->disk_devno = parent->disk_devno; + pr->blkssz = parent->blkssz; + pr->flags = parent->flags; + pr->parent = parent; + + return pr; +} + + + +/** + * blkid_new_probe_from_filename: + * @filename: device or regular file + * + * This function is same as call open(filename), blkid_new_probe() and + * blkid_probe_set_device(pr, fd, 0, 0). + * + * The @filename is closed by blkid_free_probe() or by the + * blkid_probe_set_device() call. + * + * Returns: a pointer to the newly allocated probe struct or NULL in case of + * error. + */ +blkid_probe blkid_new_probe_from_filename(const char *filename) +{ + int fd = -1; + blkid_probe pr = NULL; + + if (!filename) + return NULL; + + fd = open(filename, O_RDONLY); + if (fd < 0) + return NULL; + + pr = blkid_new_probe(); + if (!pr) + goto err; + + if (blkid_probe_set_device(pr, fd, 0, 0)) + goto err; + + pr->flags |= BLKID_FL_PRIVATE_FD; + return pr; +err: + if (fd >= 0) + close(fd); + blkid_free_probe(pr); + return NULL; +} + +/** + * blkid_free_probe: + * @pr: probe + * + * Deallocates the probe struct, buffers and all allocated + * data that are associated with this probing control struct. + */ +void blkid_free_probe(blkid_probe pr) +{ + int i; + + if (!pr) + return; + + for (i = 0; i < BLKID_NCHAINS; i++) { + struct blkid_chain *ch = &pr->chains[i]; + + if (ch->driver->free_data) + ch->driver->free_data(pr, ch->data); + free(ch->fltr); + } + + if ((pr->flags & BLKID_FL_PRIVATE_FD) && pr->fd >= 0) + close(pr->fd); + blkid_probe_reset_buffer(pr); + blkid_free_probe(pr->disk_probe); + + DBG(DEBUG_LOWPROBE, printf("free probe %p\n", pr)); + free(pr); +} + + +/* + * Removes chain values from probing result. + */ +void blkid_probe_chain_reset_vals(blkid_probe pr, struct blkid_chain *chn) +{ + int nvals = pr->nvals; + int i, x; + + for (x = 0, i = 0; i < pr->nvals; i++) { + struct blkid_prval *v = &pr->vals[i]; + + if (v->chain != chn && x == i) { + x++; + continue; + } + if (v->chain == chn) { + --nvals; + continue; + } + memcpy(&pr->vals[x++], v, sizeof(struct blkid_prval)); + } + pr->nvals = nvals; +} + +static void blkid_probe_chain_reset_position(struct blkid_chain *chn) +{ + if (chn) + chn->idx = -1; +} + +/* + * Copies chain values from probing result to @vals, the max size of @vals is + * @nvals and returns real number of values. + */ +int blkid_probe_chain_copy_vals(blkid_probe pr, struct blkid_chain *chn, + struct blkid_prval *vals, int nvals) +{ + int i, x; + + for (x = 0, i = 0; i < pr->nvals && x < nvals; i++) { + struct blkid_prval *v = &pr->vals[i]; + + if (v->chain != chn) + continue; + memcpy(&vals[x++], v, sizeof(struct blkid_prval)); + } + return x; +} + +/* + * Appends values from @vals to the probing result + */ +void blkid_probe_append_vals(blkid_probe pr, struct blkid_prval *vals, int nvals) +{ + int i = 0; + + while (i < nvals && pr->nvals < BLKID_NVALS) { + memcpy(&pr->vals[pr->nvals++], &vals[i++], + sizeof(struct blkid_prval)); + } +} + +static void blkid_probe_reset_vals(blkid_probe pr) +{ + memset(pr->vals, 0, sizeof(pr->vals)); + pr->nvals = 0; +} + +struct blkid_chain *blkid_probe_get_chain(blkid_probe pr) +{ + return pr->cur_chain; +} + +void *blkid_probe_get_binary_data(blkid_probe pr, struct blkid_chain *chn) +{ + int rc, org_prob_flags; + struct blkid_chain *org_chn; + + if (!pr || !chn) + return NULL; + + /* save the current setting -- the binary API has to be completely + * independent on the current probing status + */ + org_chn = pr->cur_chain; + org_prob_flags = pr->prob_flags; + + pr->cur_chain = chn; + pr->prob_flags = 0; + chn->binary = TRUE; + blkid_probe_chain_reset_position(chn); + + rc = chn->driver->probe(pr, chn); + + chn->binary = FALSE; + blkid_probe_chain_reset_position(chn); + + /* restore the original setting + */ + pr->cur_chain = org_chn; + pr->prob_flags = org_prob_flags; + + if (rc != 0) + return NULL; + + DBG(DEBUG_LOWPROBE, + printf("returning %s binary data\n", chn->driver->name)); + return chn->data; +} + + +/** + * blkid_reset_probe: + * @pr: probe + * + * Zeroize probing results and resets the current probing (this has impact to + * blkid_do_probe() only). This function does not touch probing filters and + * keeps assigned device. + */ +void blkid_reset_probe(blkid_probe pr) +{ + int i; + + if (!pr) + return; + + blkid_probe_reset_vals(pr); + + pr->cur_chain = NULL; + + for (i = 0; i < BLKID_NCHAINS; i++) + blkid_probe_chain_reset_position(&pr->chains[i]); +} + +/*** +static int blkid_probe_dump_filter(blkid_probe pr, int chain) +{ + struct blkid_chain *chn; + int i; + + if (!pr || chain < 0 || chain >= BLKID_NCHAINS) + return -1; + + chn = &pr->chains[chain]; + + if (!chn->fltr) + return -1; + + for (i = 0; i < chn->driver->nidinfos; i++) { + const struct blkid_idinfo *id = chn->driver->idinfos[i]; + + DBG(DEBUG_LOWPROBE, printf("%d: %s: %s\n", + i, + id->name, + blkid_bmp_get_item(chn->fltr, i) + ? "disabled" : "enabled <--")); + } + return 0; +} +***/ + +/* + * Returns properly initialized chain filter + */ +unsigned long *blkid_probe_get_filter(blkid_probe pr, int chain, int create) +{ + struct blkid_chain *chn; + + if (!pr || chain < 0 || chain >= BLKID_NCHAINS) + return NULL; + + chn = &pr->chains[chain]; + + /* always when you touch the chain filter all indexes are reseted and + * probing starts from scratch + */ + blkid_probe_chain_reset_position(chn); + pr->cur_chain = NULL; + + if (!chn->driver->has_fltr || (!chn->fltr && !create)) + return NULL; + + if (!chn->fltr) + chn->fltr = calloc(1, blkid_bmp_nbytes(chn->driver->nidinfos)); + else + memset(chn->fltr, 0, blkid_bmp_nbytes(chn->driver->nidinfos)); + + /* blkid_probe_dump_filter(pr, chain); */ + return chn->fltr; +} + +/* + * Generic private functions for filter setting + */ +int __blkid_probe_invert_filter(blkid_probe pr, int chain) +{ + int i; + struct blkid_chain *chn; + + chn = &pr->chains[chain]; + + if (!chn->driver->has_fltr || !chn->fltr) + return -1; + + for (i = 0; i < blkid_bmp_nwords(chn->driver->nidinfos); i++) + chn->fltr[i] = ~chn->fltr[i]; + + DBG(DEBUG_LOWPROBE, printf("probing filter inverted\n")); + /* blkid_probe_dump_filter(pr, chain); */ + return 0; +} + +int __blkid_probe_reset_filter(blkid_probe pr, int chain) +{ + return blkid_probe_get_filter(pr, chain, FALSE) ? 0 : -1; +} + +int __blkid_probe_filter_types(blkid_probe pr, int chain, int flag, char *names[]) +{ + unsigned long *fltr; + struct blkid_chain *chn; + int i; + + fltr = blkid_probe_get_filter(pr, chain, TRUE); + if (!fltr) + return -1; + + chn = &pr->chains[chain]; + + for (i = 0; i < chn->driver->nidinfos; i++) { + int has = 0; + const struct blkid_idinfo *id = chn->driver->idinfos[i]; + char **n; + + for (n = names; *n; n++) { + if (!strcmp(id->name, *n)) { + has = 1; + break; + } + } + if (flag & BLKID_FLTR_ONLYIN) { + if (!has) + blkid_bmp_set_item(fltr, i); + } else if (flag & BLKID_FLTR_NOTIN) { + if (has) + blkid_bmp_set_item(fltr, i); + } + } + + DBG(DEBUG_LOWPROBE, + printf("%s: a new probing type-filter initialized\n", + chn->driver->name)); + /* blkid_probe_dump_filter(pr, chain); */ + return 0; +} + +unsigned char *blkid_probe_get_buffer(blkid_probe pr, + blkid_loff_t off, blkid_loff_t len) +{ + struct list_head *p; + struct blkid_bufinfo *bf = NULL; + + if (pr->size <= 0) + return NULL; + + if (pr->parent && + pr->parent->devno == pr->devno && + pr->parent->off <= pr->off && + pr->parent->off + pr->parent->size >= pr->off + pr->size) { + /* + * This is a cloned prober and points to the same area as + * parent. Let's use parent's buffers. + * + * Note that pr->off (and pr->parent->off) is always from the + * beginig of the device. + */ + return blkid_probe_get_buffer(pr->parent, + pr->off + off - pr->parent->off, len); + } + + list_for_each(p, &pr->buffers) { + struct blkid_bufinfo *x = + list_entry(p, struct blkid_bufinfo, bufs); + + if (x->off <= off && off + len <= x->off + x->len) { + DBG(DEBUG_LOWPROBE, + printf("\treuse buffer: off=%jd len=%jd pr=%p\n", + x->off, x->len, pr)); + bf = x; + break; + } + } + if (!bf) { + ssize_t ret; + + if (blkid_llseek(pr->fd, pr->off + off, SEEK_SET) < 0) + return NULL; + + /* allocate info and space for data by why call */ + bf = calloc(1, sizeof(struct blkid_bufinfo) + len); + if (!bf) + return NULL; + + bf->data = ((unsigned char *) bf) + sizeof(struct blkid_bufinfo); + bf->len = len; + bf->off = off; + INIT_LIST_HEAD(&bf->bufs); + + DBG(DEBUG_LOWPROBE, + printf("\tbuffer read: off=%jd len=%jd pr=%p\n", + off, len, pr)); + + ret = read(pr->fd, bf->data, len); + if (ret != (ssize_t) len) { + free(bf); + return NULL; + } + list_add_tail(&bf->bufs, &pr->buffers); + } + + return off ? bf->data + (off - bf->off) : bf->data; +} + + +static void blkid_probe_reset_buffer(blkid_probe pr) +{ + uint64_t read_ct = 0, len_ct = 0; + + if (!pr || list_empty(&pr->buffers)) + return; + + DBG(DEBUG_LOWPROBE, printf("reseting probing buffers pr=%p\n", pr)); + + while (!list_empty(&pr->buffers)) { + struct blkid_bufinfo *bf = list_entry(pr->buffers.next, + struct blkid_bufinfo, bufs); + read_ct++; + len_ct += bf->len; + list_del(&bf->bufs); + free(bf); + } + + DBG(DEBUG_LOWPROBE, + printf("buffers summary: %"PRIu64" bytes " + "by %"PRIu64" read() call(s)\n", + len_ct, read_ct)); + + INIT_LIST_HEAD(&pr->buffers); +} + +/* + * Small devices need a special care. + */ +int blkid_probe_is_tiny(blkid_probe pr) +{ + return pr && (pr->flags & BLKID_FL_TINY_DEV); +} + +/* + * CDROMs may fail when probed for RAID (last sector problem) + */ +int blkid_probe_is_cdrom(blkid_probe pr) +{ + return pr && (pr->flags & BLKID_FL_CDROM_DEV); +} + +/** + * blkid_probe_set_device: + * @pr: probe + * @fd: device file descriptor + * @off: begin of probing area + * @size: size of probing area (zero means whole device/file) + * + * Assigns the device to probe control struct, resets internal buffers and + * resets the current probing. + * + * Returns: -1 in case of failure, or 0 on success. + */ +int blkid_probe_set_device(blkid_probe pr, int fd, + blkid_loff_t off, blkid_loff_t size) +{ + struct stat sb; + + if (!pr) + return -1; + + blkid_reset_probe(pr); + blkid_probe_reset_buffer(pr); + + if ((pr->flags & BLKID_FL_PRIVATE_FD) && pr->fd >= 0) + close(pr->fd); + + pr->flags &= ~BLKID_FL_PRIVATE_FD; + pr->flags &= ~BLKID_FL_TINY_DEV; + pr->flags &= ~BLKID_FL_CDROM_DEV; + pr->prob_flags = 0; + pr->fd = fd; + pr->off = off; + pr->size = 0; + pr->devno = 0; + pr->disk_devno = 0; + pr->mode = 0; + pr->blkssz = 0; + pr->wipe_off = 0; + pr->wipe_size = 0; + pr->wipe_chain = NULL; + +#if defined(POSIX_FADV_RANDOM) && defined(HAVE_POSIX_FADVISE) + /* Disable read-ahead */ + posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM); +#endif + if (fstat(fd, &sb)) + goto err; + + if (!S_ISBLK(sb.st_mode) && !S_ISCHR(sb.st_mode) && !S_ISREG(sb.st_mode)) + goto err; + + pr->mode = sb.st_mode; + if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) + pr->devno = sb.st_rdev; + + if (size) + pr->size = size; + else { + if (S_ISBLK(sb.st_mode)) { + if (blkdev_get_size(fd, (unsigned long long *) &pr->size)) { + DBG(DEBUG_LOWPROBE, printf( + "failed to get device size\n")); + goto err; + } + } else if (S_ISCHR(sb.st_mode)) + pr->size = 1; /* UBI devices are char... */ + else if (S_ISREG(sb.st_mode)) + pr->size = sb.st_size; /* regular file */ + + if (pr->off > pr->size) + goto err; + + /* The probing area cannot be larger than whole device, pr->off + * is offset within the device */ + pr->size -= pr->off; + } + + if (pr->size <= 1440 * 1024 && !S_ISCHR(sb.st_mode)) + pr->flags |= BLKID_FL_TINY_DEV; + +#ifdef CDROM_GET_CAPABILITY + if (S_ISBLK(sb.st_mode) && ioctl(fd, CDROM_GET_CAPABILITY, NULL) >= 0) + pr->flags |= BLKID_FL_CDROM_DEV; +#endif + + DBG(DEBUG_LOWPROBE, printf("ready for low-probing, offset=%jd, size=%jd\n", + pr->off, pr->size)); + DBG(DEBUG_LOWPROBE, printf("whole-disk: %s, regfile: %s\n", + blkid_probe_is_wholedisk(pr) ?"YES" : "NO", + S_ISREG(pr->mode) ? "YES" : "NO")); + + return 0; +err: + DBG(DEBUG_LOWPROBE, + printf("failed to prepare a device for low-probing\n")); + return -1; + +} + +int blkid_probe_get_dimension(blkid_probe pr, + blkid_loff_t *off, blkid_loff_t *size) +{ + if (!pr) + return -1; + + *off = pr->off; + *size = pr->size; + return 0; +} + +int blkid_probe_set_dimension(blkid_probe pr, + blkid_loff_t off, blkid_loff_t size) +{ + if (!pr) + return -1; + + DBG(DEBUG_LOWPROBE, printf( + "changing probing area pr=%p: size=%llu, off=%llu " + "-to-> size=%llu, off=%llu\n", + pr, + (unsigned long long) pr->size, + (unsigned long long) pr->off, + (unsigned long long) size, + (unsigned long long) off)); + + pr->off = off; + pr->size = size; + pr->flags &= ~BLKID_FL_TINY_DEV; + + if (pr->size <= 1440 * 1024 && !S_ISCHR(pr->mode)) + pr->flags |= BLKID_FL_TINY_DEV; + + blkid_probe_reset_buffer(pr); + + return 0; +} + +int blkid_probe_get_idmag(blkid_probe pr, const struct blkid_idinfo *id, + blkid_loff_t *offset, const struct blkid_idmag **res) +{ + const struct blkid_idmag *mag = NULL; + blkid_loff_t off = 0; + + if (id) + mag = id->magics ? &id->magics[0] : NULL; + if (res) + *res = NULL; + + /* try to detect by magic string */ + while(mag && mag->magic) { + unsigned char *buf; + + off = (mag->kboff + (mag->sboff >> 10)) << 10; + buf = blkid_probe_get_buffer(pr, off, 1024); + + if (buf && !memcmp(mag->magic, + buf + (mag->sboff & 0x3ff), mag->len)) { + DBG(DEBUG_LOWPROBE, printf( + "\tmagic sboff=%u, kboff=%ld\n", + mag->sboff, mag->kboff)); + if (offset) + *offset = off + (mag->sboff & 0x3ff); + if (res) + *res = mag; + return 0; + } + mag++; + } + + if (id->magics && id->magics[0].magic) + /* magic string(s) defined, but not found */ + return 1; + + return 0; +} + +static inline void blkid_probe_start(blkid_probe pr) +{ + if (pr) { + pr->cur_chain = NULL; + pr->prob_flags = 0; + blkid_probe_set_wiper(pr, 0, 0); + } +} + +static inline void blkid_probe_end(blkid_probe pr) +{ + if (pr) { + pr->cur_chain = NULL; + pr->prob_flags = 0; + blkid_probe_set_wiper(pr, 0, 0); + } +} + +/** + * blkid_do_probe: + * @pr: prober + * + * Calls probing functions in all enabled chains. The superblocks chain is + * enabled by default. The blkid_do_probe() stores result from only one + * probing function. It's necessary to call this routine in a loop to get + * results from all probing functions in all chains. The probing is reseted + * by blkid_reset_probe() or by filter functions. + * + * This is string-based NAME=value interface only. + * + * + * basic case - use the first result only + * + * + * if (blkid_do_probe(pr) == 0) { + * int nvals = blkid_probe_numof_values(pr); + * for (n = 0; n < nvals; n++) { + * if (blkid_probe_get_value(pr, n, &name, &data, &len) == 0) + * printf("%s = %s\n", name, data); + * } + * } + * + * + * + * + * advanced case - probe for all signatures + * + * + * while (blkid_do_probe(pr) == 0) { + * int nvals = blkid_probe_numof_values(pr); + * ... + * } + * + * + * + * See also blkid_reset_probe(). + * + * Returns: 0 on success, 1 when probing is done and -1 in case of error. + */ +int blkid_do_probe(blkid_probe pr) +{ + int rc = 1; + + if (!pr) + return -1; + + do { + struct blkid_chain *chn = pr->cur_chain; + + if (!chn) { + blkid_probe_start(pr); + chn = pr->cur_chain = &pr->chains[0]; + } + /* we go to the next chain only when the previous probing + * result was nothing (rc == 1) and when the current chain is + * disabled or we are at end of the current chain (chain->idx + + * 1 == sizeof chain) or the current chain bailed out right at + * the start (chain->idx == -1) + */ + else if (rc == 1 && (chn->enabled == FALSE || + chn->idx + 1 == chn->driver->nidinfos || + chn->idx == -1)) { + + int idx = chn->driver->id + 1; + + if (idx < BLKID_NCHAINS) + chn = pr->cur_chain = &pr->chains[idx]; + else { + blkid_probe_end(pr); + return 1; /* all chains already probed */ + } + } + + chn->binary = FALSE; /* for sure... */ + + DBG(DEBUG_LOWPROBE, printf("chain probe %s %s (idx=%d)\n", + chn->driver->name, + chn->enabled? "ENABLED" : "DISABLED", + chn->idx)); + + if (!chn->enabled) + continue; + + /* rc: -1 = error, 0 = success, 1 = no result */ + rc = chn->driver->probe(pr, chn); + + } while (rc == 1); + + return rc; +} + +/** + * blkid_do_safeprobe: + * @pr: prober + * + * This function gathers probing results from all enabled chains and checks + * for ambivalent results (e.g. more filesystems on the device). + * + * This is string-based NAME=value interface only. + * + * Note about suberblocks chain -- the function does not check for filesystems + * when a RAID signature is detected. The function also does not check for + * collision between RAIDs. The first detected RAID is returned. The function + * checks for collision between partition table and RAID signature -- it's + * recommended to enable partitions chain together with superblocks chain. + * + * Returns: 0 on success, 1 if nothing is detected, -2 if ambivalen result is + * detected and -1 on case of error. + */ +int blkid_do_safeprobe(blkid_probe pr) +{ + int i, count = 0, rc = 0; + + if (!pr) + return -1; + + blkid_probe_start(pr); + + for (i = 0; i < BLKID_NCHAINS; i++) { + struct blkid_chain *chn; + + chn = pr->cur_chain = &pr->chains[i]; + chn->binary = FALSE; /* for sure... */ + + DBG(DEBUG_LOWPROBE, printf("chain safeprobe %s %s\n", + chn->driver->name, + chn->enabled? "ENABLED" : "DISABLED")); + + if (!chn->enabled) + continue; + + blkid_probe_chain_reset_position(chn); + + rc = chn->driver->safeprobe(pr, chn); + + blkid_probe_chain_reset_position(chn); + + /* rc: -2 ambivalent, -1 = error, 0 = success, 1 = no result */ + if (rc < 0) + goto done; /* error */ + if (rc == 0) + count++; /* success */ + } + +done: + blkid_probe_end(pr); + if (rc < 0) + return rc; + return count ? 0 : 1; +} + +/** + * blkid_do_fullprobe: + * @pr: prober + * + * This function gathers probing results from all enabled chains. Same as + * blkid_so_safeprobe() but does not check for collision between probing + * result. + * + * This is string-based NAME=value interface only. + * + * Returns: 0 on success, 1 if nothing is detected or -1 on case of error. + */ +int blkid_do_fullprobe(blkid_probe pr) +{ + int i, count = 0, rc = 0; + + if (!pr) + return -1; + + blkid_probe_start(pr); + + for (i = 0; i < BLKID_NCHAINS; i++) { + int rc; + struct blkid_chain *chn; + + chn = pr->cur_chain = &pr->chains[i]; + chn->binary = FALSE; /* for sure... */ + + DBG(DEBUG_LOWPROBE, printf("chain fullprobe %s: %s\n", + chn->driver->name, + chn->enabled? "ENABLED" : "DISABLED")); + + if (!chn->enabled) + continue; + + blkid_probe_chain_reset_position(chn); + + rc = chn->driver->probe(pr, chn); + + blkid_probe_chain_reset_position(chn); + + /* rc: -1 = error, 0 = success, 1 = no result */ + if (rc < 0) + goto done; /* error */ + if (rc == 0) + count++; /* success */ + } + +done: + blkid_probe_end(pr); + if (rc < 0) + return rc; + return count ? 0 : 1; +} + +/* same sa blkid_probe_get_buffer() but works with 512-sectors */ +unsigned char *blkid_probe_get_sector(blkid_probe pr, unsigned int sector) +{ + return pr ? blkid_probe_get_buffer(pr, + ((blkid_loff_t) sector) << 9, 0x200) : NULL; +} + +struct blkid_prval *blkid_probe_assign_value( + blkid_probe pr, const char *name) +{ + struct blkid_prval *v; + + if (!name) + return NULL; + if (pr->nvals >= BLKID_NVALS) + return NULL; + + v = &pr->vals[pr->nvals]; + v->name = name; + v->chain = pr->cur_chain; + pr->nvals++; + + DBG(DEBUG_LOWPROBE, + printf("assigning %s [%s]\n", name, v->chain->driver->name)); + return v; +} + +int blkid_probe_reset_last_value(blkid_probe pr) +{ + struct blkid_prval *v; + + if (pr == NULL || pr->nvals == 0) + return -1; + + v = &pr->vals[pr->nvals - 1]; + + DBG(DEBUG_LOWPROBE, + printf("un-assigning %s [%s]\n", v->name, v->chain->driver->name)); + + memset(v, 0, sizeof(struct blkid_prval)); + pr->nvals--; + + return 0; + +} + +int blkid_probe_set_value(blkid_probe pr, const char *name, + unsigned char *data, size_t len) +{ + struct blkid_prval *v; + + if (len > BLKID_PROBVAL_BUFSIZ) + len = BLKID_PROBVAL_BUFSIZ; + + v = blkid_probe_assign_value(pr, name); + if (!v) + return -1; + + memcpy(v->data, data, len); + v->len = len; + return 0; +} + +int blkid_probe_vsprintf_value(blkid_probe pr, const char *name, + const char *fmt, va_list ap) +{ + struct blkid_prval *v; + size_t len; + + v = blkid_probe_assign_value(pr, name); + if (!v) + return -1; + + len = vsnprintf((char *) v->data, sizeof(v->data), fmt, ap); + + if (len <= 0) { + blkid_probe_reset_last_value(pr); + return -1; + } + v->len = len + 1; + return 0; +} + +int blkid_probe_sprintf_value(blkid_probe pr, const char *name, + const char *fmt, ...) +{ + int rc; + va_list ap; + + va_start(ap, fmt); + rc = blkid_probe_vsprintf_value(pr, name, fmt, ap); + va_end(ap); + + return rc; +} + +/** + * blkid_probe_get_devno: + * @pr: probe + * + * Returns: block device number, or 0 for regilar files. + */ +dev_t blkid_probe_get_devno(blkid_probe pr) +{ + return pr->devno; +} + +/** + * blkid_probe_get_wholedisk_devno: + * @pr: probe + * + * Returns: device number of the wholedisk, or 0 for regilar files. + */ +dev_t blkid_probe_get_wholedisk_devno(blkid_probe pr) +{ + if (!pr->disk_devno) { + dev_t devno, disk_devno = 0; + + devno = blkid_probe_get_devno(pr); + if (!devno) + return 0; + + if (blkid_devno_to_wholedisk(devno, NULL, 0, &disk_devno) == 0) + pr->disk_devno = disk_devno; + } + return pr->disk_devno; +} + +/** + * blkid_probe_is_wholedisk: + * @pr: probe + * + * Returns: 1 if the device is whole-disk or 0. + */ +int blkid_probe_is_wholedisk(blkid_probe pr) +{ + dev_t devno, disk_devno; + + devno = blkid_probe_get_devno(pr); + if (!devno) + return 0; + + disk_devno = blkid_probe_get_wholedisk_devno(pr); + if (!disk_devno) + return 0; + + return devno == disk_devno; +} + +blkid_probe blkid_probe_get_wholedisk_probe(blkid_probe pr) +{ + dev_t disk; + + if (blkid_probe_is_wholedisk(pr)) + return NULL; /* this is not partition */ + + if (pr->parent) + /* this is cloned blkid_probe, use parent's stuff */ + return blkid_probe_get_wholedisk_probe(pr->parent); + + disk = blkid_probe_get_wholedisk_devno(pr); + + if (pr->disk_probe && pr->disk_probe->devno != disk) { + /* we have disk prober, but for another disk... close it */ + blkid_free_probe(pr->disk_probe); + pr->disk_probe = NULL; + } + + if (!pr->disk_probe) { + /* Open a new disk prober */ + char *disk_path = blkid_devno_to_devname(disk); + + if (!disk_path) + return NULL; + + DBG(DEBUG_LOWPROBE, printf("allocate a wholedisk probe\n")); + + pr->disk_probe = blkid_new_probe_from_filename(disk_path); + if (!pr->disk_probe) + return NULL; /* ENOMEM? */ + } + + return pr->disk_probe; +} + +/** + * blkid_probe_get_size: + * @pr: probe + * + * This function returns size of probing area as defined by blkid_probe_set_device(). + * If the size of the probing area is unrestricted then this function returns + * the real size of device. See also blkid_get_dev_size(). + * + * Returns: size in bytes or -1 in case of error. + */ +blkid_loff_t blkid_probe_get_size(blkid_probe pr) +{ + return pr ? pr->size : -1; +} + +/** + * blkid_probe_get_offset: + * @pr: probe + * + * This function returns offset of probing area as defined by blkid_probe_set_device(). + * + * Returns: offset in bytes or -1 in case of error. + */ +blkid_loff_t blkid_probe_get_offset(blkid_probe pr) +{ + return pr ? pr->off : -1; +} + +/** + * blkid_probe_get_fd: + * @pr: probe + * + * Returns: file descriptor for assigned device/file. + */ +int blkid_probe_get_fd(blkid_probe pr) +{ + return pr ? pr->fd : -1; +} + +/** + * blkid_probe_get_sectorsize: + * @pr: probe or NULL (for NULL returns 512) + * + * Returns: block device logical sector size (BLKSSZGET ioctl, default 512). + */ +unsigned int blkid_probe_get_sectorsize(blkid_probe pr) +{ + if (!pr) + return DEFAULT_SECTOR_SIZE; /*... and good luck! */ + + if (pr->blkssz) + return pr->blkssz; + + if (S_ISBLK(pr->mode) && + blkdev_get_sector_size(pr->fd, (int *) &pr->blkssz) == 0) + return pr->blkssz; + + pr->blkssz = DEFAULT_SECTOR_SIZE; + return pr->blkssz; +} + +/** + * blkid_probe_get_sectors: + * @pr: probe + * + * Returns: 512-byte sector count or -1 in case of error. + */ +blkid_loff_t blkid_probe_get_sectors(blkid_probe pr) +{ + return pr ? pr->size >> 9 : -1; +} + +/** + * blkid_probe_numof_values: + * @pr: probe + * + * Returns: number of values in probing result or -1 in case of error. + */ +int blkid_probe_numof_values(blkid_probe pr) +{ + if (!pr) + return -1; + return pr->nvals; +} + +/** + * blkid_probe_get_value: + * @pr: probe + * @num: wanted value in range 0..N, where N is blkid_probe_numof_values() - 1 + * @name: pointer to return value name or NULL + * @data: pointer to return value data or NULL + * @len: pointer to return value length or NULL + * + * Note, the @len returns length of the @data, including the terminating + * '\0' character. + * + * Returns: 0 on success, or -1 in case of error. + */ +int blkid_probe_get_value(blkid_probe pr, int num, const char **name, + const char **data, size_t *len) +{ + struct blkid_prval *v = __blkid_probe_get_value(pr, num); + + if (!v) + return -1; + if (name) + *name = v->name; + if (data) + *data = (char *) v->data; + if (len) + *len = v->len; + + DBG(DEBUG_LOWPROBE, printf("returning %s value\n", v->name)); + return 0; +} + +/** + * blkid_probe_lookup_value: + * @pr: probe + * @name: name of value + * @data: pointer to return value data or NULL + * @len: pointer to return value length or NULL + * + * Note, the @len returns length of the @data, including the terminating + * '\0' character. + * + * Returns: 0 on success, or -1 in case of error. + */ +int blkid_probe_lookup_value(blkid_probe pr, const char *name, + const char **data, size_t *len) +{ + struct blkid_prval *v = __blkid_probe_lookup_value(pr, name); + + if (!v) + return -1; + if (data) + *data = (char *) v->data; + if (len) + *len = v->len; + return 0; +} + +/** + * blkid_probe_has_value: + * @pr: probe + * @name: name of value + * + * Returns: 1 if value exist in probing result, otherwise 0. + */ +int blkid_probe_has_value(blkid_probe pr, const char *name) +{ + if (blkid_probe_lookup_value(pr, name, NULL, NULL) == 0) + return 1; + return 0; +} + +struct blkid_prval *__blkid_probe_get_value(blkid_probe pr, int num) +{ + if (pr == NULL || num < 0 || num >= pr->nvals) + return NULL; + + return &pr->vals[num]; +} + +struct blkid_prval *__blkid_probe_lookup_value(blkid_probe pr, const char *name) +{ + int i; + + if (pr == NULL || pr->nvals == 0 || name == NULL) + return NULL; + + for (i = 0; i < pr->nvals; i++) { + struct blkid_prval *v = &pr->vals[i]; + + if (v->name && strcmp(name, v->name) == 0) { + DBG(DEBUG_LOWPROBE, printf("returning %s value\n", v->name)); + return v; + } + } + return NULL; +} + + +/* converts DCE UUID (uuid[16]) to human readable string + * - the @len should be always 37 */ +void blkid_unparse_uuid(const unsigned char *uuid, char *str, size_t len) +{ +#ifdef HAVE_LIBUUID + uuid_unparse(uuid, str); +#else + snprintf(str, len, + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + uuid[0], uuid[1], uuid[2], uuid[3], + uuid[4], uuid[5], + uuid[6], uuid[7], + uuid[8], uuid[9], + uuid[10], uuid[11], uuid[12], uuid[13], uuid[14],uuid[15]); +#endif +} + + +/* Removes whitespace from the right-hand side of a string (trailing + * whitespace). + * + * Returns size of the new string (without \0). + */ +size_t blkid_rtrim_whitespace(unsigned char *str) +{ + size_t i = strlen((char *) str); + + while (i--) { + if (!isspace(str[i])) + break; + } + str[++i] = '\0'; + return i; +} + +/* + * Some mkfs-like utils wipe some parts (usually begin) of the device. + * For example LVM (pvcreate) or mkswap(8). This information could be used + * for later resolution to conflicts between superblocks. + * + * For example we found valid LVM superblock, LVM wipes 8KiB at the begin of + * the device. If we found another signature (for example MBR) this wiped area + * then the signature has been added later and LVM superblock should be ignore. + * + * Note that this heuristic is not 100% reliable, for example "pvcreate --zero + * n" allows to keep the begin of the device unmodified. It's probably better + * to use this heuristic for conflicts between superblocks and partition tables + * than for conflicts between filesystem superblocks -- existence of unwanted + * partition table is very unusual, because PT is pretty visible (parsed and + * interpreted by kernel). + */ +void blkid_probe_set_wiper(blkid_probe pr, blkid_loff_t off, blkid_loff_t size) +{ + struct blkid_chain *chn; + + if (!pr) + return; + + if (!size) { + DBG(DEBUG_LOWPROBE, printf("zeroize wiper\n")); + pr->wipe_size = pr->wipe_off = 0; + pr->wipe_chain = NULL; + return; + } + + chn = pr->cur_chain; + + if (!chn || !chn->driver || + chn->idx < 0 || chn->idx >= chn->driver->nidinfos) + return; + + pr->wipe_size = size; + pr->wipe_off = off; + pr->wipe_chain = chn; + + DBG(DEBUG_LOWPROBE, + printf("wiper set to %s::%s off=%jd size=%jd\n", + chn->driver->name, + chn->driver->idinfos[chn->idx]->name, + pr->wipe_off, pr->wipe_size)); + return; +} + +/* + * Returns 1 if the <@off,@size> area was wiped + */ +int blkid_probe_is_wiped(blkid_probe pr, struct blkid_chain **chn, + blkid_loff_t off, blkid_loff_t size) +{ + if (!pr || !size) + return 0; + + if (pr->wipe_off <= off && off + size <= pr->wipe_off + pr->wipe_size) { + if (chn) + *chn = pr->wipe_chain; + return 1; + } + return 0; +} + +void blkid_probe_use_wiper(blkid_probe pr, blkid_loff_t off, blkid_loff_t size) +{ + struct blkid_chain *chn = NULL; + + if (blkid_probe_is_wiped(pr, &chn, off, size) && chn) { + DBG(DEBUG_LOWPROBE, printf("wiped area detected -- ignore previous results\n")); + blkid_probe_set_wiper(pr, 0, 0); + blkid_probe_chain_reset_vals(pr, chn); + } +} + diff --git a/libblkid/src/read.c b/libblkid/src/read.c new file mode 100644 index 00000000..c404bb01 --- /dev/null +++ b/libblkid/src/read.c @@ -0,0 +1,498 @@ +/* + * read.c - read the blkid cache from disk, to avoid scanning all devices + * + * Copyright (C) 2001, 2003 Theodore Y. Ts'o + * Copyright (C) 2001 Andreas Dilger + * + * %Begin-Header% + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * %End-Header% + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#if HAVE_ERRNO_H +#include +#endif + +#include "blkidP.h" + +#if HAVE_STDLIB_H +# ifndef _XOPEN_SOURCE +# define _XOPEN_SOURCE 600 /* for inclusion of strtoull */ +# endif +# include +#endif + +#ifdef HAVE_STRTOULL +#define STRTOULL strtoull /* defined in stdlib.h if you try hard enough */ +#else +/* FIXME: need to support real strtoull here */ +#define STRTOULL strtoul +#endif + +#ifdef TEST_PROGRAM +#define blkid_debug_dump_dev(dev) (debug_dump_dev(dev)) +static void debug_dump_dev(blkid_dev dev); +#endif + +/* + * File format: + * + * ...]>device_name + * + * The following tags are required for each entry: + * unique (within this file) ID number of this device + * (time_t and suseconds_t) time this entry was last + * read from disk + * (detected) type of filesystem/data for this partition + * + * The following tags may be present, depending on the device contents + * (user supplied) label (volume name, etc) + * (generated) universally unique identifier (serial no) + */ + +static char *skip_over_blank(char *cp) +{ + while (*cp && isspace(*cp)) + cp++; + return cp; +} + +static char *skip_over_word(char *cp) +{ + char ch; + + while ((ch = *cp)) { + /* If we see a backslash, skip the next character */ + if (ch == '\\') { + cp++; + if (*cp == '\0') + break; + cp++; + continue; + } + if (isspace(ch) || ch == '<' || ch == '>') + break; + cp++; + } + return cp; +} + +static char *strip_line(char *line) +{ + char *p; + + line = skip_over_blank(line); + + p = line + strlen(line) - 1; + + while (*line) { + if (isspace(*p)) + *p-- = '\0'; + else + break; + } + + return line; +} + +#if 0 +static char *parse_word(char **buf) +{ + char *word, *next; + + word = *buf; + if (*word == '\0') + return NULL; + + word = skip_over_blank(word); + next = skip_over_word(word); + if (*next) { + char *end = next - 1; + if (*end == '"' || *end == '\'') + *end = '\0'; + *next++ = '\0'; + } + *buf = next; + + if (*word == '"' || *word == '\'') + word++; + return word; +} +#endif + +/* + * Start parsing a new line from the cache. + * + * line starts with " continue parsing line + * line starts with " skip line + * line starts with other, return -BLKID_ERR_CACHE -> error + */ +static int parse_start(char **cp) +{ + char *p; + + p = strip_line(*cp); + + /* Skip comment or blank lines. We can't just NUL the first '#' char, + * in case it is inside quotes, or escaped. + */ + if (*p == '\0' || *p == '#') + return 0; + + if (!strncmp(p, "", 9)) { + DBG(DEBUG_READ, printf("found device trailer %9s\n", *cp)); + *cp += 9; + return 0; + } + + return -BLKID_ERR_CACHE; +} + +/* + * Allocate a new device struct with device name filled in. Will handle + * finding the device on lines of the form: + * devname + * devnamebar + */ +static int parse_dev(blkid_cache cache, blkid_dev *dev, char **cp) +{ + char *start, *tmp, *end, *name; + int ret; + + if ((ret = parse_start(cp)) <= 0) + return ret; + + start = tmp = strchr(*cp, '>'); + if (!start) { + DBG(DEBUG_READ, + printf("blkid: short line parsing dev: %s\n", *cp)); + return -BLKID_ERR_CACHE; + } + start = skip_over_blank(start + 1); + end = skip_over_word(start); + + DBG(DEBUG_READ, printf("device should be %*s\n", + (int)(end - start), start)); + + if (**cp == '>') + *cp = end; + else + (*cp)++; + + *tmp = '\0'; + + if (!(tmp = strrchr(end, '<')) || parse_end(&tmp) < 0) { + DBG(DEBUG_READ, + printf("blkid: missing ending: %s\n", end)); + } else if (tmp) + *tmp = '\0'; + + if (end - start <= 1) { + DBG(DEBUG_READ, printf("blkid: empty device name: %s\n", *cp)); + return -BLKID_ERR_CACHE; + } + + name = blkid_strndup(start, end-start); + if (name == NULL) + return -BLKID_ERR_MEM; + + DBG(DEBUG_READ, printf("found dev %s\n", name)); + + if (!(*dev = blkid_get_dev(cache, name, BLKID_DEV_CREATE))) { + free(name); + return -BLKID_ERR_MEM; + } + + free(name); + return 1; +} + +/* + * Extract a tag of the form NAME="value" from the line. + */ +static int parse_token(char **name, char **value, char **cp) +{ + char *end; + + if (!name || !value || !cp) + return -BLKID_ERR_PARAM; + + if (!(*value = strchr(*cp, '='))) + return 0; + + **value = '\0'; + *name = strip_line(*cp); + *value = skip_over_blank(*value + 1); + + if (**value == '"') { + end = strchr(*value + 1, '"'); + if (!end) { + DBG(DEBUG_READ, + printf("unbalanced quotes at: %s\n", *value)); + *cp = *value; + return -BLKID_ERR_CACHE; + } + (*value)++; + *end = '\0'; + end++; + } else { + end = skip_over_word(*value); + if (*end) { + *end = '\0'; + end++; + } + } + *cp = end; + + return 1; +} + +/* + * Extract a tag of the form value from the line. + */ +/* +static int parse_xml(char **name, char **value, char **cp) +{ + char *end; + + if (!name || !value || !cp) + return -BLKID_ERR_PARAM; + + *name = strip_line(*cp); + + if ((*name)[0] != '<' || (*name)[1] == '/') + return 0; + + FIXME: finish this. +} +*/ + +/* + * Extract a tag from the line. + * + * Return 1 if a valid tag was found. + * Return 0 if no tag found. + * Return -ve error code. + */ +static int parse_tag(blkid_cache cache, blkid_dev dev, char **cp) +{ + char *name = NULL; + char *value = NULL; + int ret; + + if (!cache || !dev) + return -BLKID_ERR_PARAM; + + if ((ret = parse_token(&name, &value, cp)) <= 0 /* && + (ret = parse_xml(&name, &value, cp)) <= 0 */) + return ret; + + /* Some tags are stored directly in the device struct */ + if (!strcmp(name, "DEVNO")) + dev->bid_devno = STRTOULL(value, 0, 0); + else if (!strcmp(name, "PRI")) + dev->bid_pri = strtol(value, 0, 0); + else if (!strcmp(name, "TIME")) { + char *end = NULL; + dev->bid_time = STRTOULL(value, &end, 0); + if (end && *end == '.') + dev->bid_utime = STRTOULL(end + 1, 0, 0); + } else + ret = blkid_set_tag(dev, name, value, strlen(value)); + + DBG(DEBUG_READ, printf(" tag: %s=\"%s\"\n", name, value)); + + return ret < 0 ? ret : 1; +} + +/* + * Parse a single line of data, and return a newly allocated dev struct. + * Add the new device to the cache struct, if one was read. + * + * Lines are of the form /dev/foo + * + * Returns -ve value on error. + * Returns 0 otherwise. + * If a valid device was read, *dev_p is non-NULL, otherwise it is NULL + * (e.g. comment lines, unknown XML content, etc). + */ +static int blkid_parse_line(blkid_cache cache, blkid_dev *dev_p, char *cp) +{ + blkid_dev dev; + int ret; + + if (!cache || !dev_p) + return -BLKID_ERR_PARAM; + + *dev_p = NULL; + + DBG(DEBUG_READ, printf("line: %s\n", cp)); + + if ((ret = parse_dev(cache, dev_p, &cp)) <= 0) + return ret; + + dev = *dev_p; + + while ((ret = parse_tag(cache, dev, &cp)) > 0) { + ; + } + + if (dev->bid_type == NULL) { + DBG(DEBUG_READ, + printf("blkid: device %s has no TYPE\n",dev->bid_name)); + blkid_free_dev(dev); + } + + DBG(DEBUG_READ, blkid_debug_dump_dev(dev)); + + return ret; +} + +/* + * Parse the specified filename, and return the data in the supplied or + * a newly allocated cache struct. If the file doesn't exist, return a + * new empty cache struct. + */ +void blkid_read_cache(blkid_cache cache) +{ + FILE *file; + char buf[4096]; + int fd, lineno = 0; + struct stat st; + + if (!cache) + return; + + /* + * If the file doesn't exist, then we just return an empty + * struct so that the cache can be populated. + */ + if ((fd = open(cache->bic_filename, O_RDONLY)) < 0) + return; + if (fstat(fd, &st) < 0) + goto errout; + if ((st.st_mtime == cache->bic_ftime) || + (cache->bic_flags & BLKID_BIC_FL_CHANGED)) { + DBG(DEBUG_CACHE, printf("skipping re-read of %s\n", + cache->bic_filename)); + goto errout; + } + + DBG(DEBUG_CACHE, printf("reading cache file %s\n", + cache->bic_filename)); + + file = fdopen(fd, "r"); + if (!file) + goto errout; + + while (fgets(buf, sizeof(buf), file)) { + blkid_dev dev; + unsigned int end; + + lineno++; + if (buf[0] == 0) + continue; + end = strlen(buf) - 1; + /* Continue reading next line if it ends with a backslash */ + while (buf[end] == '\\' && end < sizeof(buf) - 2 && + fgets(buf + end, sizeof(buf) - end, file)) { + end = strlen(buf) - 1; + lineno++; + } + + if (blkid_parse_line(cache, &dev, buf) < 0) { + DBG(DEBUG_READ, + printf("blkid: bad format on line %d\n", lineno)); + continue; + } + } + fclose(file); + + /* + * Initially we do not need to write out the cache file. + */ + cache->bic_flags &= ~BLKID_BIC_FL_CHANGED; + cache->bic_ftime = st.st_mtime; + + return; +errout: + close(fd); + return; +} + +#ifdef TEST_PROGRAM +static void debug_dump_dev(blkid_dev dev) +{ + struct list_head *p; + + if (!dev) { + printf(" dev: NULL\n"); + return; + } + + printf(" dev: name = %s\n", dev->bid_name); + printf(" dev: DEVNO=\"0x%0llx\"\n", (long long)dev->bid_devno); + printf(" dev: TIME=\"%ld.%ld\"\n", (long)dev->bid_time, (long)dev->bid_utime); + printf(" dev: PRI=\"%d\"\n", dev->bid_pri); + printf(" dev: flags = 0x%08X\n", dev->bid_flags); + + list_for_each(p, &dev->bid_tags) { + blkid_tag tag = list_entry(p, struct blkid_struct_tag, bit_tags); + if (tag) + printf(" tag: %s=\"%s\"\n", tag->bit_name, + tag->bit_val); + else + printf(" tag: NULL\n"); + } + printf("\n"); +} + +int main(int argc, char**argv) +{ + blkid_cache cache = NULL; + int ret; + + blkid_init_debug(DEBUG_ALL); + if (argc > 2) { + fprintf(stderr, "Usage: %s [filename]\n" + "Test parsing of the cache (filename)\n", argv[0]); + exit(1); + } + if ((ret = blkid_get_cache(&cache, argv[1])) < 0) + fprintf(stderr, "error %d reading cache file %s\n", ret, + argv[1] ? argv[1] : BLKID_CACHE_FILE); + + blkid_put_cache(cache); + + return ret; +} +#endif diff --git a/libblkid/src/resolve.c b/libblkid/src/resolve.c new file mode 100644 index 00000000..bf13b864 --- /dev/null +++ b/libblkid/src/resolve.c @@ -0,0 +1,139 @@ +/* + * resolve.c - resolve names and tags into specific devices + * + * Copyright (C) 2001, 2003 Theodore Ts'o. + * Copyright (C) 2001 Andreas Dilger + * + * %Begin-Header% + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * %End-Header% + */ + +#include +#if HAVE_UNISTD_H +#include +#endif +#include +#include +#include +#include +#include +#include "blkidP.h" + +/* + * Find a tagname (e.g. LABEL or UUID) on a specific device. + */ +char *blkid_get_tag_value(blkid_cache cache, const char *tagname, + const char *devname) +{ + blkid_tag found; + blkid_dev dev; + blkid_cache c = cache; + char *ret = NULL; + + DBG(DEBUG_RESOLVE, printf("looking for %s on %s\n", tagname, devname)); + + if (!devname) + return NULL; + + if (!cache) { + if (blkid_get_cache(&c, NULL) < 0) + return NULL; + } + + if ((dev = blkid_get_dev(c, devname, BLKID_DEV_NORMAL)) && + (found = blkid_find_tag_dev(dev, tagname))) + ret = blkid_strdup(found->bit_val); + + if (!cache) + blkid_put_cache(c); + + return ret; +} + +/* + * Locate a device name from a token (NAME=value string), or (name, value) + * pair. In the case of a token, value is ignored. If the "token" is not + * of the form "NAME=value" and there is no value given, then it is assumed + * to be the actual devname and a copy is returned. + */ +char *blkid_get_devname(blkid_cache cache, const char *token, + const char *value) +{ + blkid_dev dev; + blkid_cache c = cache; + char *t = 0, *v = 0; + char *ret = NULL; + + if (!token) + return NULL; + + if (!cache) { + if (blkid_get_cache(&c, NULL) < 0) + return NULL; + } + + DBG(DEBUG_RESOLVE, + printf("looking for %s%s%s %s\n", token, value ? "=" : "", + value ? value : "", cache ? "in cache" : "from disk")); + + if (!value) { + if (!strchr(token, '=')) { + ret = blkid_strdup(token); + goto out; + } + blkid_parse_tag_string(token, &t, &v); + if (!t || !v) + goto out; + token = t; + value = v; + } + + dev = blkid_find_dev_with_tag(c, token, value); + if (!dev) + goto out; + + ret = blkid_strdup(blkid_dev_devname(dev)); + +out: + free(t); + free(v); + if (!cache) { + blkid_put_cache(c); + } + return (ret); +} + +#ifdef TEST_PROGRAM +int main(int argc, char **argv) +{ + char *value; + blkid_cache cache; + + blkid_init_debug(DEBUG_ALL); + if (argc != 2 && argc != 3) { + fprintf(stderr, "Usage:\t%s tagname=value\n" + "\t%s tagname devname\n" + "Find which device holds a given token or\n" + "Find what the value of a tag is in a device\n", + argv[0], argv[0]); + exit(1); + } + if (blkid_get_cache(&cache, "/dev/null") < 0) { + fprintf(stderr, "Couldn't get blkid cache\n"); + exit(1); + } + + if (argv[2]) { + value = blkid_get_tag_value(cache, argv[1], argv[2]); + printf("%s has tag %s=%s\n", argv[2], argv[1], + value ? value : ""); + } else { + value = blkid_get_devname(cache, argv[1], NULL); + printf("%s has tag %s\n", value ? value : "", argv[1]); + } + blkid_put_cache(cache); + return value ? 0 : 1; +} +#endif diff --git a/libblkid/src/save.c b/libblkid/src/save.c new file mode 100644 index 00000000..a71b0687 --- /dev/null +++ b/libblkid/src/save.c @@ -0,0 +1,196 @@ +/* + * save.c - write the cache struct to disk + * + * Copyright (C) 2001 by Andreas Dilger + * Copyright (C) 2003 Theodore Ts'o + * + * %Begin-Header% + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * %End-Header% + */ + +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_STAT_H +#include +#endif +#ifdef HAVE_ERRNO_H +#include +#endif +#include "blkidP.h" + +static int save_dev(blkid_dev dev, FILE *file) +{ + struct list_head *p; + + if (!dev || dev->bid_name[0] != '/') + return 0; + + DBG(DEBUG_SAVE, + printf("device %s, type %s\n", dev->bid_name, dev->bid_type ? + dev->bid_type : "(null)")); + + fprintf(file, "bid_devno, + (long) dev->bid_time, + (long) dev->bid_utime); + + if (dev->bid_pri) + fprintf(file, " PRI=\"%d\"", dev->bid_pri); + list_for_each(p, &dev->bid_tags) { + blkid_tag tag = list_entry(p, struct blkid_struct_tag, bit_tags); + fprintf(file, " %s=\"%s\"", tag->bit_name,tag->bit_val); + } + fprintf(file, ">%s\n", dev->bid_name); + + return 0; +} + +/* + * Write out the cache struct to the cache file on disk. + */ +int blkid_flush_cache(blkid_cache cache) +{ + struct list_head *p; + char *tmp = NULL; + const char *opened = NULL; + const char *filename; + FILE *file = NULL; + int fd, ret = 0; + struct stat st; + + if (!cache) + return -BLKID_ERR_PARAM; + + if (list_empty(&cache->bic_devs) || + !(cache->bic_flags & BLKID_BIC_FL_CHANGED)) { + DBG(DEBUG_SAVE, printf("skipping cache file write\n")); + return 0; + } + + filename = cache->bic_filename ? cache->bic_filename: BLKID_CACHE_FILE; + + /* If we can't write to the cache file, then don't even try */ + if (((ret = stat(filename, &st)) < 0 && errno != ENOENT) || + (ret == 0 && access(filename, W_OK) < 0)) { + DBG(DEBUG_SAVE, + printf("can't write to cache file %s\n", filename)); + return 0; + } + + /* + * Try and create a temporary file in the same directory so + * that in case of error we don't overwrite the cache file. + * If the cache file doesn't yet exist, it isn't a regular + * file (e.g. /dev/null or a socket), or we couldn't create + * a temporary file then we open it directly. + */ + if (ret == 0 && S_ISREG(st.st_mode)) { + tmp = malloc(strlen(filename) + 8); + if (tmp) { + sprintf(tmp, "%s-XXXXXX", filename); + fd = mkstemp(tmp); + if (fd >= 0) { + file = fdopen(fd, "w"); + opened = tmp; + } + fchmod(fd, 0644); + } + } + + if (!file) { + file = fopen(filename, "w"); + opened = filename; + } + + DBG(DEBUG_SAVE, + printf("writing cache file %s (really %s)\n", + filename, opened)); + + if (!file) { + ret = errno; + goto errout; + } + + list_for_each(p, &cache->bic_devs) { + blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs); + if (!dev->bid_type || (dev->bid_flags & BLKID_BID_FL_REMOVABLE)) + continue; + if ((ret = save_dev(dev, file)) < 0) + break; + } + + if (ret >= 0) { + cache->bic_flags &= ~BLKID_BIC_FL_CHANGED; + ret = 1; + } + + fclose(file); + if (opened != filename) { + if (ret < 0) { + unlink(opened); + DBG(DEBUG_SAVE, + printf("unlinked temp cache %s\n", opened)); + } else { + char *backup; + + backup = malloc(strlen(filename) + 5); + if (backup) { + sprintf(backup, "%s.old", filename); + unlink(backup); + if (link(filename, backup)) { + DBG(DEBUG_SAVE, + printf("can't link %s to %s\n", + filename, backup)); + } + free(backup); + } + rename(opened, filename); + DBG(DEBUG_SAVE, + printf("moved temp cache %s\n", opened)); + } + } + +errout: + free(tmp); + return ret; +} + +#ifdef TEST_PROGRAM +int main(int argc, char **argv) +{ + blkid_cache cache = NULL; + int ret; + + blkid_init_debug(DEBUG_ALL); + if (argc > 2) { + fprintf(stderr, "Usage: %s [filename]\n" + "Test loading/saving a cache (filename)\n", argv[0]); + exit(1); + } + + if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) { + fprintf(stderr, "%s: error creating cache (%d)\n", + argv[0], ret); + exit(1); + } + if ((ret = blkid_probe_all(cache)) < 0) { + fprintf(stderr, "error (%d) probing devices\n", ret); + exit(1); + } + cache->bic_filename = blkid_strdup(argv[1]); + + if ((ret = blkid_flush_cache(cache)) < 0) { + fprintf(stderr, "error (%d) saving cache\n", ret); + exit(1); + } + + blkid_put_cache(cache); + + return ret; +} +#endif diff --git a/libblkid/src/superblocks/Makefile.am b/libblkid/src/superblocks/Makefile.am new file mode 100644 index 00000000..1501fab1 --- /dev/null +++ b/libblkid/src/superblocks/Makefile.am @@ -0,0 +1,51 @@ +include $(top_srcdir)/config/include-Makefile.am + +AM_CPPFLAGS += -I$(ul_libblkid_incdir) -I$(ul_libblkid_srcdir) + +noinst_LTLIBRARIES = libblkid_superblocks.la +libblkid_superblocks_la_SOURCES = \ + superblocks.h \ + superblocks.c \ + cramfs.c \ + swap.c \ + adaptec_raid.c \ + ddf_raid.c \ + isw_raid.c \ + jmicron_raid.c \ + lsi_raid.c \ + nvidia_raid.c \ + promise_raid.c \ + silicon_raid.c \ + via_raid.c \ + linux_raid.c \ + jfs.c \ + xfs.c \ + ext.c \ + gfs.c \ + ocfs.c \ + reiserfs.c \ + romfs.c \ + ntfs.c \ + hfs.c \ + iso9660.c \ + udf.c \ + vfat.c \ + luks.c \ + highpoint_raid.c \ + vxfs.c \ + minix.c \ + ufs.c \ + hpfs.c \ + squashfs.c \ + netware.c \ + sysv.c \ + btrfs.c \ + lvm.c \ + zfs.c \ + ubifs.c \ + bfs.c \ + drbd.c \ + vmfs.c \ + befs.c \ + nilfs.c \ + exfat.c diff --git a/libblkid/src/superblocks/adaptec_raid.c b/libblkid/src/superblocks/adaptec_raid.c new file mode 100644 index 00000000..570e75e9 --- /dev/null +++ b/libblkid/src/superblocks/adaptec_raid.c @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2008 Karel Zak + * + * Inspired by libvolume_id by + * Kay Sievers + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include + +#include "superblocks.h" + +struct adaptec_metadata { + + 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]; + uint32_t smagic; + uint32_t raidtbl; + uint16_t raidline; + uint8_t res9[0xF6]; +} __attribute__((packed)); + +#define AD_SIGNATURE 0x4450544D /* "DPTM" */ +#define AD_MAGIC 0x37FC4D1E + +static int probe_adraid(blkid_probe pr, const struct blkid_idmag *mag) +{ + uint64_t off; + struct adaptec_metadata *ad; + + if (pr->size < 0x10000) + return -1; + + if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) + return -1; + + off = ((pr->size / 0x200)-1) * 0x200; + ad = (struct adaptec_metadata *) + blkid_probe_get_buffer(pr, + off, + sizeof(struct adaptec_metadata)); + if (!ad) + return -1; + if (ad->smagic != be32_to_cpu(AD_SIGNATURE)) + return -1; + if (ad->b0idcode != be32_to_cpu(AD_MAGIC)) + return -1; + if (blkid_probe_sprintf_version(pr, "%u", ad->resver) != 0) + return -1; + if (blkid_probe_set_magic(pr, off, sizeof(ad->b0idcode), + (unsigned char *) &ad->b0idcode)) + return -1; + return 0; +} + +const struct blkid_idinfo adraid_idinfo = { + .name = "adaptec_raid_member", + .usage = BLKID_USAGE_RAID, + .probefunc = probe_adraid, + .magics = BLKID_NONE_MAGIC +}; + + diff --git a/libblkid/src/superblocks/befs.c b/libblkid/src/superblocks/befs.c new file mode 100644 index 00000000..c78dc208 --- /dev/null +++ b/libblkid/src/superblocks/befs.c @@ -0,0 +1,470 @@ +/* + * Copyright (C) 2010 Jeroen Oortwijn + * + * Partly based on the Haiku BFS driver by + * Axel Dörfler + * + * Also inspired by the Linux BeFS driver by + * Will Dyson , et al. + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include + +#include "superblocks.h" + +#define B_OS_NAME_LENGTH 0x20 +#define SUPER_BLOCK_MAGIC1 0x42465331 /* BFS1 */ +#define SUPER_BLOCK_MAGIC2 0xdd121031 +#define SUPER_BLOCK_MAGIC3 0x15b6830e +#define SUPER_BLOCK_FS_ENDIAN 0x42494745 /* BIGE */ +#define INODE_MAGIC1 0x3bbe0ad9 +#define BPLUSTREE_MAGIC 0x69f6c2e8 +#define BPLUSTREE_NULL -1LL +#define NUM_DIRECT_BLOCKS 12 +#define B_UINT64_TYPE 0x554c4c47 /* ULLG */ +#define KEY_NAME "be:volume_id" +#define KEY_SIZE 8 + +#define FS16_TO_CPU(value, fs_is_le) (fs_is_le ? le16_to_cpu(value) \ + : be16_to_cpu(value)) +#define FS32_TO_CPU(value, fs_is_le) (fs_is_le ? le32_to_cpu(value) \ + : be32_to_cpu(value)) +#define FS64_TO_CPU(value, fs_is_le) (fs_is_le ? le64_to_cpu(value) \ + : be64_to_cpu(value)) + +typedef struct block_run { + int32_t allocation_group; + uint16_t start; + uint16_t len; +} __attribute__((packed)) block_run, inode_addr; + +struct befs_super_block { + char name[B_OS_NAME_LENGTH]; + int32_t magic1; + int32_t fs_byte_order; + uint32_t block_size; + uint32_t block_shift; + int64_t num_blocks; + int64_t used_blocks; + int32_t inode_size; + int32_t magic2; + int32_t blocks_per_ag; + int32_t ag_shift; + int32_t num_ags; + int32_t flags; + block_run log_blocks; + int64_t log_start; + int64_t log_end; + int32_t magic3; + inode_addr root_dir; + inode_addr indices; + int32_t pad[8]; +} __attribute__((packed)); + +typedef struct data_stream { + block_run direct[NUM_DIRECT_BLOCKS]; + int64_t max_direct_range; + block_run indirect; + int64_t max_indirect_range; + block_run double_indirect; + int64_t max_double_indirect_range; + int64_t size; +} __attribute__((packed)) data_stream; + +struct befs_inode { + int32_t magic1; + inode_addr inode_num; + int32_t uid; + int32_t gid; + int32_t mode; + int32_t flags; + int64_t create_time; + int64_t last_modified_time; + inode_addr parent; + inode_addr attributes; + uint32_t type; + int32_t inode_size; + uint32_t etc; + data_stream data; + int32_t pad[4]; + int32_t small_data[0]; +} __attribute__((packed)); + +struct small_data { + uint32_t type; + uint16_t name_size; + uint16_t data_size; + char name[0]; +} __attribute__((packed)); + +struct bplustree_header { + uint32_t magic; + uint32_t node_size; + uint32_t max_number_of_levels; + uint32_t data_type; + int64_t root_node_pointer; + int64_t free_node_pointer; + int64_t maximum_size; +} __attribute__((packed)); + +struct bplustree_node { + int64_t left_link; + int64_t right_link; + int64_t overflow_link; + uint16_t all_key_count; + uint16_t all_key_length; + char name[0]; +} __attribute__((packed)); + +unsigned char *get_block_run(blkid_probe pr, const struct befs_super_block *bs, + const struct block_run *br, int fs_le) +{ + return blkid_probe_get_buffer(pr, + ((blkid_loff_t) FS32_TO_CPU(br->allocation_group, fs_le) + << FS32_TO_CPU(bs->ag_shift, fs_le) + << FS32_TO_CPU(bs->block_shift, fs_le)) + + ((blkid_loff_t) FS16_TO_CPU(br->start, fs_le) + << FS32_TO_CPU(bs->block_shift, fs_le)), + (blkid_loff_t) FS16_TO_CPU(br->len, fs_le) + << FS32_TO_CPU(bs->block_shift, fs_le)); +} + +unsigned char *get_custom_block_run(blkid_probe pr, + const struct befs_super_block *bs, + const struct block_run *br, + int64_t offset, uint32_t length, int fs_le) +{ + if (offset + length > (int64_t) FS16_TO_CPU(br->len, fs_le) + << FS32_TO_CPU(bs->block_shift, fs_le)) + return NULL; + + return blkid_probe_get_buffer(pr, + ((blkid_loff_t) FS32_TO_CPU(br->allocation_group, fs_le) + << FS32_TO_CPU(bs->ag_shift, fs_le) + << FS32_TO_CPU(bs->block_shift, fs_le)) + + ((blkid_loff_t) FS16_TO_CPU(br->start, fs_le) + << FS32_TO_CPU(bs->block_shift, fs_le)) + + offset, + length); +} + +unsigned char *get_tree_node(blkid_probe pr, const struct befs_super_block *bs, + const struct data_stream *ds, + int64_t start, uint32_t length, int fs_le) +{ + if (start < FS64_TO_CPU(ds->max_direct_range, fs_le)) { + int64_t br_len; + int i; + + for (i = 0; i < NUM_DIRECT_BLOCKS; i++) { + br_len = (int64_t) FS16_TO_CPU(ds->direct[i].len, fs_le) + << FS32_TO_CPU(bs->block_shift, fs_le); + if (start < br_len) + return get_custom_block_run(pr, bs, + &ds->direct[i], + start, length, fs_le); + else + start -= br_len; + } + } else if (start < FS64_TO_CPU(ds->max_indirect_range, fs_le)) { + struct block_run *br; + int64_t max_br, br_len, i; + + start -= FS64_TO_CPU(ds->max_direct_range, fs_le); + max_br = ((int64_t) FS16_TO_CPU(ds->indirect.len, fs_le) + << FS32_TO_CPU(bs->block_shift, fs_le)) + / sizeof(struct block_run); + + br = (struct block_run *) get_block_run(pr, bs, &ds->indirect, + fs_le); + if (!br) + return NULL; + + for (i = 0; i < max_br; i++) { + br_len = (int64_t) FS16_TO_CPU(br[i].len, fs_le) + << FS32_TO_CPU(bs->block_shift, fs_le); + if (start < br_len) + return get_custom_block_run(pr, bs, &br[i], + start, length, fs_le); + else + start -= br_len; + } + } else if (start < FS64_TO_CPU(ds->max_double_indirect_range, fs_le)) { + struct block_run *br; + int64_t di_br_size, br_per_di_br, di_index, i_index; + + start -= FS64_TO_CPU(ds->max_indirect_range, fs_le); + di_br_size = (int64_t) FS16_TO_CPU(ds->double_indirect.len, + fs_le) << FS32_TO_CPU(bs->block_shift, fs_le); + br_per_di_br = di_br_size / sizeof(struct block_run); + di_index = start / (br_per_di_br * di_br_size); + i_index = (start % (br_per_di_br * di_br_size)) / di_br_size; + start = (start % (br_per_di_br * di_br_size)) % di_br_size; + + br = (struct block_run *) get_block_run(pr, bs, + &ds->double_indirect, fs_le); + if (!br) + return NULL; + + br = (struct block_run *) get_block_run(pr, bs, &br[di_index], + fs_le); + if (!br) + return NULL; + + return get_custom_block_run(pr, bs, &br[i_index], start, length, + fs_le); + } + return NULL; +} + +int32_t compare_keys(const char keys1[], uint16_t keylengths1[], int32_t index, + const char *key2, uint16_t keylength2, int fs_le) +{ + const char *key1; + uint16_t keylength1; + int32_t result; + + key1 = &keys1[index == 0 ? 0 : FS16_TO_CPU(keylengths1[index - 1], + fs_le)]; + keylength1 = FS16_TO_CPU(keylengths1[index], fs_le) + - (index == 0 ? 0 : FS16_TO_CPU(keylengths1[index - 1], + fs_le)); + + result = strncmp(key1, key2, min(keylength1, keylength2)); + + if (result == 0) + return keylength1 - keylength2; + + return result; +} + +int64_t get_key_value(blkid_probe pr, const struct befs_super_block *bs, + const struct befs_inode *bi, const char *key, int fs_le) +{ + struct bplustree_header *bh; + struct bplustree_node *bn; + uint16_t *keylengths; + int64_t *values; + int64_t node_pointer; + int32_t first, last, mid, cmp; + + bh = (struct bplustree_header *) get_tree_node(pr, bs, &bi->data, 0, + sizeof(struct bplustree_header), fs_le); + if (!bh) + return -1; + + if (FS32_TO_CPU(bh->magic, fs_le) != BPLUSTREE_MAGIC) + return -1; + + node_pointer = FS64_TO_CPU(bh->root_node_pointer, fs_le); + + do { + bn = (struct bplustree_node *) get_tree_node(pr, bs, &bi->data, + node_pointer, FS32_TO_CPU(bh->node_size, fs_le), fs_le); + if (!bn) + return -1; + + keylengths = (uint16_t *) ((uint8_t *) bn + + ((sizeof(struct bplustree_node) + + FS16_TO_CPU(bn->all_key_length, fs_le) + + sizeof(int64_t) - 1) + & ~(sizeof(int64_t) - 1))); + values = (int64_t *) ((uint8_t *) keylengths + + FS16_TO_CPU(bn->all_key_count, fs_le) + * sizeof(uint16_t)); + first = 0; + mid = 0; + last = FS16_TO_CPU(bn->all_key_count, fs_le) - 1; + + cmp = compare_keys(bn->name, keylengths, last, key, strlen(key), + fs_le); + if (cmp == 0) { + if (FS64_TO_CPU(bn->overflow_link, fs_le) + == BPLUSTREE_NULL) + return FS64_TO_CPU(values[last], fs_le); + else + node_pointer = FS64_TO_CPU(values[last], fs_le); + } else if (cmp < 0) + node_pointer = FS64_TO_CPU(bn->overflow_link, fs_le); + else { + while (first <= last) { + mid = (first + last) / 2; + + cmp = compare_keys(bn->name, keylengths, mid, + key, strlen(key), fs_le); + if (cmp == 0) { + if (FS64_TO_CPU(bn->overflow_link, + fs_le) == BPLUSTREE_NULL) + return FS64_TO_CPU(values[mid], + fs_le); + else + break; + } else if (cmp < 0) + first = mid + 1; + else + last = mid - 1; + } + if (cmp < 0) + node_pointer = FS64_TO_CPU(values[mid + 1], + fs_le); + else + node_pointer = FS64_TO_CPU(values[mid], fs_le); + } + } while (FS64_TO_CPU(bn->overflow_link, fs_le) != BPLUSTREE_NULL); + return 0; +} + +int get_uuid(blkid_probe pr, const struct befs_super_block *bs, + uint64_t * const uuid, int fs_le) +{ + struct befs_inode *bi; + struct small_data *sd; + + bi = (struct befs_inode *) get_block_run(pr, bs, &bs->root_dir, fs_le); + if (!bi) + return -1; + + if (FS32_TO_CPU(bi->magic1, fs_le) != INODE_MAGIC1) + return -1; + + sd = (struct small_data *) bi->small_data; + + do { + if (FS32_TO_CPU(sd->type, fs_le) == B_UINT64_TYPE + && FS16_TO_CPU(sd->name_size, fs_le) == strlen(KEY_NAME) + && FS16_TO_CPU(sd->data_size, fs_le) == KEY_SIZE + && strcmp(sd->name, KEY_NAME) == 0) { + *uuid = *(uint64_t *) ((uint8_t *) sd->name + + FS16_TO_CPU(sd->name_size, fs_le) + + 3); + break; + } else if (FS32_TO_CPU(sd->type, fs_le) == 0 + && FS16_TO_CPU(sd->name_size, fs_le) == 0 + && FS16_TO_CPU(sd->data_size, fs_le) == 0) + break; + + sd = (struct small_data *) ((uint8_t *) sd + + sizeof(struct small_data) + + FS16_TO_CPU(sd->name_size, fs_le) + 3 + + FS16_TO_CPU(sd->data_size, fs_le) + 1); + + } while ((intptr_t) sd < (intptr_t) bi + + FS32_TO_CPU(bi->inode_size, fs_le) + - sizeof(struct small_data)); + if (*uuid == 0 + && (FS32_TO_CPU(bi->attributes.allocation_group, fs_le) != 0 + || FS16_TO_CPU(bi->attributes.start, fs_le) != 0 + || FS16_TO_CPU(bi->attributes.len, fs_le) != 0)) { + int64_t value; + + bi = (struct befs_inode *) get_block_run(pr, bs, + &bi->attributes, fs_le); + if (!bi) + return -1; + + if (FS32_TO_CPU(bi->magic1, fs_le) != INODE_MAGIC1) + return -1; + + value = get_key_value(pr, bs, bi, KEY_NAME, fs_le); + + if (value < 0) + return value; + else if (value > 0) { + bi = (struct befs_inode *) blkid_probe_get_buffer(pr, + value << FS32_TO_CPU(bs->block_shift, fs_le), + FS32_TO_CPU(bs->block_size, fs_le)); + if (!bi) + return -1; + + if (FS32_TO_CPU(bi->magic1, fs_le) != INODE_MAGIC1) + return -1; + + if (FS32_TO_CPU(bi->type, fs_le) == B_UINT64_TYPE + && FS64_TO_CPU(bi->data.size, fs_le) == KEY_SIZE + && FS16_TO_CPU(bi->data.direct[0].len, fs_le) + == 1) { + uint64_t *attr_data; + + attr_data = (uint64_t *) get_block_run(pr, bs, + &bi->data.direct[0], fs_le); + if (!attr_data) + return -1; + + *uuid = *attr_data; + } + } + } + return 0; +} + +static int probe_befs(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct befs_super_block *bs; + const char *version = NULL; + uint64_t volume_id = 0; + int fs_le, ret; + + bs = (struct befs_super_block *) blkid_probe_get_buffer(pr, + mag->sboff - B_OS_NAME_LENGTH, + sizeof(struct befs_super_block)); + if (!bs) + return -1; + + if (le32_to_cpu(bs->magic1) == SUPER_BLOCK_MAGIC1 + && le32_to_cpu(bs->magic2) == SUPER_BLOCK_MAGIC2 + && le32_to_cpu(bs->magic3) == SUPER_BLOCK_MAGIC3 + && le32_to_cpu(bs->fs_byte_order) == SUPER_BLOCK_FS_ENDIAN) { + fs_le = 1; + version = "little-endian"; + } else if (be32_to_cpu(bs->magic1) == SUPER_BLOCK_MAGIC1 + && be32_to_cpu(bs->magic2) == SUPER_BLOCK_MAGIC2 + && be32_to_cpu(bs->magic3) == SUPER_BLOCK_MAGIC3 + && be32_to_cpu(bs->fs_byte_order) == SUPER_BLOCK_FS_ENDIAN) { + fs_le = 0; + version = "big-endian"; + } else + return -1; + + ret = get_uuid(pr, bs, &volume_id, fs_le); + + if (ret < 0) + return ret; + + /* + * all checks pass, set LABEL, VERSION and UUID + */ + if (strlen(bs->name)) + blkid_probe_set_label(pr, (unsigned char *) bs->name, + sizeof(bs->name)); + if (version) + blkid_probe_set_version(pr, version); + + if (volume_id) + blkid_probe_sprintf_uuid(pr, (unsigned char *) &volume_id, + sizeof(volume_id), "%016" PRIx64, + FS64_TO_CPU(volume_id, fs_le)); + return 0; +} + +const struct blkid_idinfo befs_idinfo = +{ + .name = "befs", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_befs, + .minsz = 1024 * 1440, + .magics = { + { .magic = "BFS1", .len = 4, .sboff = B_OS_NAME_LENGTH }, + { .magic = "1SFB", .len = 4, .sboff = B_OS_NAME_LENGTH }, + { .magic = "BFS1", .len = 4, .sboff = 0x200 + + B_OS_NAME_LENGTH }, + { .magic = "1SFB", .len = 4, .sboff = 0x200 + + B_OS_NAME_LENGTH }, + { NULL } + } +}; diff --git a/libblkid/src/superblocks/bfs.c b/libblkid/src/superblocks/bfs.c new file mode 100644 index 00000000..8a34c583 --- /dev/null +++ b/libblkid/src/superblocks/bfs.c @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2009 Red Hat, Inc. + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ + +#include "superblocks.h" + +/* + * BFS actually has two different labels in the superblock, each + * of them only 6 bytes long. Until we find out what their use + * we just ignore them. + */ +const struct blkid_idinfo bfs_idinfo = +{ + .name = "bfs", + .usage = BLKID_USAGE_FILESYSTEM, + .magics = { + { .magic = "\xce\xfa\xad\x1b", .len = 4 }, + { NULL } + } +}; diff --git a/libblkid/src/superblocks/btrfs.c b/libblkid/src/superblocks/btrfs.c new file mode 100644 index 00000000..51bbadc7 --- /dev/null +++ b/libblkid/src/superblocks/btrfs.c @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include + +#include "superblocks.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]; + } __attribute__ ((__packed__)) dev_item; + uint8_t label[256]; +} __attribute__ ((__packed__)); + +static int probe_btrfs(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct btrfs_super_block *bfs; + + bfs = blkid_probe_get_sb(pr, mag, struct btrfs_super_block); + if (!bfs) + return -1; + + if (*bfs->label) + blkid_probe_set_label(pr, + (unsigned char *) bfs->label, + sizeof(bfs->label)); + + blkid_probe_set_uuid(pr, bfs->fsid); + blkid_probe_set_uuid_as(pr, bfs->dev_item.uuid, "UUID_SUB"); + + return 0; +} + +const struct blkid_idinfo btrfs_idinfo = +{ + .name = "btrfs", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_btrfs, + .minsz = 256 * 1024 * 1024, + .magics = + { + { .magic = "_BHRfS_M", .len = 8, .kboff = 64, .sboff = 0x40 }, + { NULL } + } +}; + diff --git a/libblkid/src/superblocks/cramfs.c b/libblkid/src/superblocks/cramfs.c new file mode 100644 index 00000000..b58ed08c --- /dev/null +++ b/libblkid/src/superblocks/cramfs.c @@ -0,0 +1,62 @@ +/* + * Copyright (C) 1999 by Andries Brouwer + * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o + * Copyright (C) 2001 by Andreas Dilger + * Copyright (C) 2004 Kay Sievers + * Copyright (C) 2008 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ + +#include +#include +#include +#include +#include + +#include "superblocks.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; + } __attribute__((packed)) info; + uint8_t name[16]; +} __attribute__((packed)); + +static int probe_cramfs(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct cramfs_super *cs; + + cs = blkid_probe_get_sb(pr, mag, struct cramfs_super); + if (!cs) + return -1; + + blkid_probe_set_label(pr, cs->name, sizeof(cs->name)); + return 0; +} + +const struct blkid_idinfo cramfs_idinfo = +{ + .name = "cramfs", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_cramfs, + .magics = + { + { "\x45\x3d\xcd\x28", 4, 0, 0 }, + { "\x28\xcd\x3d\x45", 4, 0, 0 }, + { NULL } + } +}; + + diff --git a/libblkid/src/superblocks/ddf_raid.c b/libblkid/src/superblocks/ddf_raid.c new file mode 100644 index 00000000..c0ba3351 --- /dev/null +++ b/libblkid/src/superblocks/ddf_raid.c @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2008 Karel Zak + * + * Inspired by libvolume_id by + * Kay Sievers + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include + +#include "superblocks.h" + +/* http://www.snia.org/standards/home */ +#define DDF_GUID_LENGTH 24 +#define DDF_REV_LENGTH 8 +#define DDF_MAGIC 0xDE11DE11 + + +struct ddf_header { + uint32_t signature; + uint32_t crc; + uint8_t guid[DDF_GUID_LENGTH]; + char ddf_rev[8]; /* 01.02.00 */ + uint32_t seq; /* starts at '1' */ + uint32_t timestamp; + uint8_t openflag; + uint8_t foreignflag; + uint8_t enforcegroups; + uint8_t pad0; /* 0xff */ + uint8_t pad1[12]; /* 12 * 0xff */ + /* 64 bytes so far */ + uint8_t header_ext[32]; /* reserved: fill with 0xff */ + uint64_t primary_lba; + uint64_t secondary_lba; + uint8_t type; + uint8_t pad2[3]; /* 0xff */ + uint32_t workspace_len; /* sectors for vendor space - + * at least 32768(sectors) */ + uint64_t workspace_lba; + uint16_t max_pd_entries; /* one of 15, 63, 255, 1023, 4095 */ + uint16_t max_vd_entries; /* 2^(4,6,8,10,12)-1 : i.e. as above */ + uint16_t max_partitions; /* i.e. max num of configuration + record entries per disk */ + uint16_t config_record_len; /* 1 +ROUNDUP(max_primary_element_entries + *12/512) */ + uint16_t max_primary_element_entries; /* 16, 64, 256, 1024, or 4096 */ + uint8_t pad3[54]; /* 0xff */ + /* 192 bytes so far */ + uint32_t controller_section_offset; + uint32_t controller_section_length; + uint32_t phys_section_offset; + uint32_t phys_section_length; + uint32_t virt_section_offset; + uint32_t virt_section_length; + uint32_t config_section_offset; + uint32_t config_section_length; + uint32_t data_section_offset; + uint32_t data_section_length; + uint32_t bbm_section_offset; + uint32_t bbm_section_length; + uint32_t diag_space_offset; + uint32_t diag_space_length; + uint32_t vendor_offset; + uint32_t vendor_length; + /* 256 bytes so far */ + uint8_t pad4[256]; /* 0xff */ +} __attribute__((packed)); + +static int probe_ddf(blkid_probe pr, const struct blkid_idmag *mag) +{ + int hdrs[] = { 1, 257 }; + int i; + struct ddf_header *ddf = NULL; + char version[DDF_REV_LENGTH + 1]; + uint64_t off, lba; + + if (pr->size < 0x30000) + return -1; + + for (i = 0; i < ARRAY_SIZE(hdrs); i++) { + off = ((pr->size / 0x200) - hdrs[i]) * 0x200; + + ddf = (struct ddf_header *) blkid_probe_get_buffer(pr, + off, + sizeof(struct ddf_header)); + if (!ddf) + return -1; + + if (ddf->signature == cpu_to_be32(DDF_MAGIC) || + ddf->signature == cpu_to_le32(DDF_MAGIC)) + break; + ddf = NULL; + } + + if (!ddf) + return -1; + + lba = ddf->signature == cpu_to_be32(DDF_MAGIC) ? + be64_to_cpu(ddf->primary_lba) : + le64_to_cpu(ddf->primary_lba); + + if (lba > 0) { + /* check primary header */ + unsigned char *buf; + + buf = blkid_probe_get_buffer(pr, + lba << 9, sizeof(ddf->signature)); + if (!buf || memcmp(buf, &ddf->signature, 4)) + return -1; + } + + blkid_probe_strncpy_uuid(pr, ddf->guid, sizeof(ddf->guid)); + + memcpy(version, ddf->ddf_rev, sizeof(ddf->ddf_rev)); + *(version + sizeof(ddf->ddf_rev)) = '\0'; + + if (blkid_probe_set_version(pr, version) != 0) + return -1; + if (blkid_probe_set_magic(pr, off, + sizeof(ddf->signature), + (unsigned char *) &ddf->signature)) + return -1; + return 0; +} + +const struct blkid_idinfo ddfraid_idinfo = { + .name = "ddf_raid_member", + .usage = BLKID_USAGE_RAID, + .probefunc = probe_ddf, + .magics = BLKID_NONE_MAGIC +}; + + diff --git a/libblkid/src/superblocks/drbd.c b/libblkid/src/superblocks/drbd.c new file mode 100644 index 00000000..3490948d --- /dev/null +++ b/libblkid/src/superblocks/drbd.c @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2009 by Bastian Friedrich + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * + * defines, structs taken from drbd source; file names represent drbd source + * files. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "superblocks.h" + +/* + * drbd/linux/drbd.h + */ +#define DRBD_MAGIC 0x83740267 + +/* + * user/drbdmeta.c + * We only support v08 for now + */ +#define DRBD_MD_MAGIC_08 (DRBD_MAGIC+4) + +/* + * drbd/linux/drbd.h + */ +enum drbd_uuid_index { + UI_CURRENT, + UI_BITMAP, + UI_HISTORY_START, + UI_HISTORY_END, + UI_SIZE, /* nl-packet: number of dirty bits */ + UI_FLAGS, /* nl-packet: flags */ + UI_EXTENDED_SIZE /* Everything. */ +}; + +/* + * user/drbdmeta.c + * Minor modifications wrt. types + */ +struct md_on_disk_08 { + uint64_t la_sect; /* last agreed size. */ + uint64_t uuid[UI_SIZE]; /* UUIDs */ + uint64_t device_uuid; + uint64_t reserved_u64_1; + uint32_t flags; + uint32_t magic; + uint32_t md_size_sect; + int32_t al_offset; /* signed sector offset to this block */ + uint32_t al_nr_extents; /* important for restoring the AL */ + int32_t bm_offset; /* signed sector offset to the bitmap, from here */ + uint32_t bm_bytes_per_bit; + uint32_t reserved_u32[4]; + + char reserved[8 * 512 - (8*(UI_SIZE+3)+4*11)]; +}; + + +static int probe_drbd(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct md_on_disk_08 *md; + off_t off; + + off = pr->size - sizeof(*md); + + /* Small devices cannot be drbd (?) */ + if (pr->size < 0x10000) + return -1; + + md = (struct md_on_disk_08 *) + blkid_probe_get_buffer(pr, + off, + sizeof(struct md_on_disk_08)); + if (!md) + return -1; + + if (be32_to_cpu(md->magic) != DRBD_MD_MAGIC_08) + return -1; + + /* + * DRBD does not have "real" uuids; the following resembles DRBD's + * notion of uuids (64 bit, see struct above) + */ + blkid_probe_sprintf_uuid(pr, + (unsigned char *) &md->device_uuid, sizeof(md->device_uuid), + "%" PRIx64, be64_to_cpu(md->device_uuid)); + + blkid_probe_set_version(pr, "v08"); + + if (blkid_probe_set_magic(pr, + off + offsetof(struct md_on_disk_08, magic), + sizeof(md->magic), + (unsigned char *) &md->magic)) + return -1; + + return 0; +} + +const struct blkid_idinfo drbd_idinfo = +{ + .name = "drbd", + .usage = BLKID_USAGE_RAID, + .probefunc = probe_drbd, + .magics = BLKID_NONE_MAGIC +}; + diff --git a/libblkid/src/superblocks/exfat.c b/libblkid/src/superblocks/exfat.c new file mode 100644 index 00000000..bada3a83 --- /dev/null +++ b/libblkid/src/superblocks/exfat.c @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2010 Andrew Nayenko + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include "superblocks.h" + +struct exfat_super_block { + uint8_t jump[3]; + uint8_t oem_name[8]; + uint8_t __unused1[53]; + uint64_t block_start; + uint64_t block_count; + uint32_t fat_block_start; + uint32_t fat_block_count; + uint32_t cluster_block_start; + uint32_t cluster_count; + uint32_t rootdir_cluster; + uint8_t volume_serial[4]; + struct { + uint8_t minor; + uint8_t major; + } version; + uint16_t volume_state; + uint8_t block_bits; + uint8_t bpc_bits; + uint8_t fat_count; + uint8_t drive_no; + uint8_t allocated_percent; +} __attribute__((__packed__)); + +struct exfat_entry_label { + uint8_t type; + uint8_t length; + uint8_t name[30]; +} __attribute__((__packed__)); + +#define BLOCK_SIZE(sb) (1 << (sb)->block_bits) +#define CLUSTER_SIZE(sb) (BLOCK_SIZE(sb) << (sb)->bpc_bits) +#define EXFAT_FIRST_DATA_CLUSTER 2 +#define EXFAT_LAST_DATA_CLUSTER 0xffffff6 +#define EXFAT_ENTRY_SIZE 32 + +#define EXFAT_ENTRY_EOD 0x00 +#define EXFAT_ENTRY_LABEL 0x83 + +static blkid_loff_t block_to_offset(const struct exfat_super_block *sb, + blkid_loff_t block) +{ + return (blkid_loff_t) block << sb->block_bits; +} + +static blkid_loff_t cluster_to_block(const struct exfat_super_block *sb, + uint32_t cluster) +{ + return le32_to_cpu(sb->cluster_block_start) + + ((blkid_loff_t) (cluster - EXFAT_FIRST_DATA_CLUSTER) + << sb->bpc_bits); +} + +static blkid_loff_t cluster_to_offset(const struct exfat_super_block *sb, + uint32_t cluster) +{ + return block_to_offset(sb, cluster_to_block(sb, cluster)); +} + +static uint32_t next_cluster(blkid_probe pr, + const struct exfat_super_block *sb, uint32_t cluster) +{ + uint32_t *next; + blkid_loff_t fat_offset; + + fat_offset = block_to_offset(sb, le32_to_cpu(sb->fat_block_start)) + + (blkid_loff_t) cluster * sizeof(cluster); + next = (uint32_t *) blkid_probe_get_buffer(pr, fat_offset, + sizeof(uint32_t)); + if (!next) + return 0; + return le32_to_cpu(*next); +} + +static struct exfat_entry_label *find_label(blkid_probe pr, + const struct exfat_super_block *sb) +{ + uint32_t cluster = le32_to_cpu(sb->rootdir_cluster); + blkid_loff_t offset = cluster_to_offset(sb, cluster); + uint8_t *entry; + + for (;;) { + entry = (uint8_t *) blkid_probe_get_buffer(pr, offset, + EXFAT_ENTRY_SIZE); + if (!entry) + return NULL; + if (entry[0] == EXFAT_ENTRY_EOD) + return NULL; + if (entry[0] == EXFAT_ENTRY_LABEL) + return (struct exfat_entry_label *) entry; + offset += EXFAT_ENTRY_SIZE; + if (offset % CLUSTER_SIZE(sb) == 0) { + cluster = next_cluster(pr, sb, cluster); + if (cluster < EXFAT_FIRST_DATA_CLUSTER) + return NULL; + if (cluster > EXFAT_LAST_DATA_CLUSTER) + return NULL; + offset = cluster_to_offset(sb, cluster); + } + } +} + +static int probe_exfat(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct exfat_super_block *sb; + struct exfat_entry_label *label; + + sb = blkid_probe_get_sb(pr, mag, struct exfat_super_block); + if (!sb) + return -1; + + label = find_label(pr, sb); + if (label) + blkid_probe_set_utf8label(pr, label->name, + min(label->length * 2, 30), BLKID_ENC_UTF16LE); + + blkid_probe_sprintf_uuid(pr, sb->volume_serial, 4, + "%02hhX%02hhX-%02hhX%02hhX", + sb->volume_serial[3], sb->volume_serial[2], + sb->volume_serial[1], sb->volume_serial[0]); + + blkid_probe_sprintf_version(pr, "%hu.%hu", + sb->version.major, sb->version.minor); + + return 0; +} + +const struct blkid_idinfo exfat_idinfo = +{ + .name = "exfat", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_exfat, + .magics = + { + { .magic = "EXFAT ", .len = 8, .sboff = 3 }, + { NULL } + } +}; diff --git a/libblkid/src/superblocks/ext.c b/libblkid/src/superblocks/ext.c new file mode 100644 index 00000000..6dfe5283 --- /dev/null +++ b/libblkid/src/superblocks/ext.c @@ -0,0 +1,526 @@ +/* + * Copyright (C) 1999, 2001 by Andries Brouwer + * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o + * Copyright (C) 2008 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include +#include +#include +#ifdef __linux__ +#include +#endif +#include + +#include "linux_version.h" +#include "superblocks.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_dummy3[7]; + unsigned char s_magic[2]; + 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; + unsigned char s_uuid[16]; + char s_volume_name[16]; + char 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; + uint16_t s_raid_stride; + uint16_t s_mmp_interval; + uint64_t s_mmp_block; + uint32_t s_raid_stripe_width; + uint32_t s_reserved[163]; +} __attribute__((packed)); + +/* magic string */ +#define EXT_SB_MAGIC "\123\357" +/* supper block offset */ +#define EXT_SB_OFF 0x400 +/* supper block offset in kB */ +#define EXT_SB_KBOFF (EXT_SB_OFF >> 10) +/* magic string offset within super block */ +#define EXT_MAG_OFF 0x38 + + + +/* for s_flags */ +#define EXT2_FLAGS_TEST_FILESYS 0x0004 + +/* for s_feature_compat */ +#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004 + +/* for s_feature_ro_compat */ +#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 EXT4_FEATURE_RO_COMPAT_HUGE_FILE 0x0008 +#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010 +#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020 +#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040 + +/* for s_feature_incompat */ +#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002 +#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 +#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 +#define EXT2_FEATURE_INCOMPAT_META_BG 0x0010 +#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */ +#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 +#define EXT4_FEATURE_INCOMPAT_MMP 0x0100 +#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200 + +#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_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \ + EXT2_FEATURE_INCOMPAT_META_BG) +#define EXT2_FEATURE_INCOMPAT_UNSUPPORTED ~EXT2_FEATURE_INCOMPAT_SUPP +#define EXT2_FEATURE_RO_COMPAT_UNSUPPORTED ~EXT2_FEATURE_RO_COMPAT_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_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 EXT3_FEATURE_RO_COMPAT_UNSUPPORTED ~EXT3_FEATURE_RO_COMPAT_SUPP + +/* + * Check to see if a filesystem is in /proc/filesystems. + * Returns 1 if found, 0 if not + */ +static int fs_proc_check(const char *fs_name) +{ + FILE *f; + char buf[80], *cp, *t; + + f = fopen("/proc/filesystems", "r"); + if (!f) + return 0; + while (!feof(f)) { + if (!fgets(buf, sizeof(buf), f)) + break; + cp = buf; + if (!isspace(*cp)) { + while (*cp && !isspace(*cp)) + cp++; + } + while (*cp && isspace(*cp)) + cp++; + if ((t = strchr(cp, '\n')) != NULL) + *t = 0; + if ((t = strchr(cp, '\t')) != NULL) + *t = 0; + if ((t = strchr(cp, ' ')) != NULL) + *t = 0; + if (!strcmp(fs_name, cp)) { + fclose(f); + return 1; + } + } + fclose(f); + return (0); +} + +/* + * Check to see if a filesystem is available as a module + * Returns 1 if found, 0 if not + */ +static int check_for_modules(const char *fs_name) +{ +#ifdef __linux__ + struct utsname uts; + FILE *f; + char buf[1024], *cp; + int namesz; + + if (uname(&uts)) + return 0; + snprintf(buf, sizeof(buf), "/lib/modules/%s/modules.dep", uts.release); + + f = fopen(buf, "r"); + if (!f) + return 0; + + namesz = strlen(fs_name); + + while (!feof(f)) { + if (!fgets(buf, sizeof(buf), f)) + break; + if ((cp = strchr(buf, ':')) != NULL) + *cp = 0; + else + continue; + if ((cp = strrchr(buf, '/')) == NULL) + continue; + cp++; + + if (!strncmp(cp, fs_name, namesz) && + (!strcmp(cp + namesz, ".ko") || + !strcmp(cp + namesz, ".ko.gz"))) { + fclose(f); + return 1; + } + } + fclose(f); +#endif /* __linux__ */ + return 0; +} + +/* + * Starting in 2.6.29, ext4 can be used to support filesystems + * without a journal. + */ +#define EXT4_SUPPORTS_EXT2 KERNEL_VERSION(2, 6, 29) + +static int system_supports_ext2(void) +{ + static time_t last_check = 0; + static int ret = -1; + time_t now = time(0); + + if (ret != -1 || (now - last_check) < 5) + return ret; + last_check = now; + ret = (fs_proc_check("ext2") || check_for_modules("ext2")); + return ret; +} + +static int system_supports_ext4(void) +{ + static time_t last_check = 0; + static int ret = -1; + time_t now = time(0); + + if (ret != -1 || (now - last_check) < 5) + return ret; + last_check = now; + ret = (fs_proc_check("ext4") || check_for_modules("ext4")); + return ret; +} + +static int system_supports_ext4dev(void) +{ + static time_t last_check = 0; + static int ret = -1; + time_t now = time(0); + + if (ret != -1 || (now - last_check) < 5) + return ret; + last_check = now; + ret = (fs_proc_check("ext4dev") || check_for_modules("ext4dev")); + return ret; +} +/* + * reads superblock and returns: + * fc = feature_compat + * fi = feature_incompat + * frc = feature_ro_compat + */ +static struct ext2_super_block *ext_get_super( + blkid_probe pr, uint32_t *fc, uint32_t *fi, uint32_t *frc) +{ + struct ext2_super_block *es; + + es = (struct ext2_super_block *) + blkid_probe_get_buffer(pr, EXT_SB_OFF, 0x200); + if (!es) + return NULL; + if (fc) + *fc = le32_to_cpu(es->s_feature_compat); + if (fi) + *fi = le32_to_cpu(es->s_feature_incompat); + if (frc) + *frc = le32_to_cpu(es->s_feature_ro_compat); + + return es; +} + +static void ext_get_info(blkid_probe pr, int ver, struct ext2_super_block *es) +{ + struct blkid_chain *chn = blkid_probe_get_chain(pr); + + DBG(DEBUG_PROBE, printf("ext2_sb.compat = %08X:%08X:%08X\n", + le32_to_cpu(es->s_feature_compat), + le32_to_cpu(es->s_feature_incompat), + le32_to_cpu(es->s_feature_ro_compat))); + + if (strlen(es->s_volume_name)) + blkid_probe_set_label(pr, (unsigned char *) es->s_volume_name, + sizeof(es->s_volume_name)); + blkid_probe_set_uuid(pr, es->s_uuid); + + if (le32_to_cpu(es->s_feature_compat) & EXT3_FEATURE_COMPAT_HAS_JOURNAL) + blkid_probe_set_uuid_as(pr, es->s_journal_uuid, "EXT_JOURNAL"); + + if (ver != 2 && (chn->flags & BLKID_SUBLKS_SECTYPE) && + ((le32_to_cpu(es->s_feature_incompat) & EXT2_FEATURE_INCOMPAT_UNSUPPORTED) == 0)) + blkid_probe_set_value(pr, "SEC_TYPE", + (unsigned char *) "ext2", + sizeof("ext2")); + + blkid_probe_sprintf_version(pr, "%u.%u", + le32_to_cpu(es->s_rev_level), + le16_to_cpu(es->s_minor_rev_level)); +} + + +static int probe_jbd(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct ext2_super_block *es; + uint32_t fi; + + es = ext_get_super(pr, NULL, &fi, NULL); + if (!es) + return -BLKID_ERR_PARAM; + if (!(fi & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) + return -BLKID_ERR_PARAM; + + ext_get_info(pr, 2, es); + return 0; +} + +static int probe_ext2(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct ext2_super_block *es; + uint32_t fc, frc, fi; + + es = ext_get_super(pr, &fc, &fi, &frc); + if (!es) + return -BLKID_ERR_PARAM; + + /* Distinguish between ext3 and ext2 */ + if (fc & EXT3_FEATURE_COMPAT_HAS_JOURNAL) + return -BLKID_ERR_PARAM; + + /* Any features which ext2 doesn't understand */ + if ((frc & EXT2_FEATURE_RO_COMPAT_UNSUPPORTED) || + (fi & EXT2_FEATURE_INCOMPAT_UNSUPPORTED)) + return -BLKID_ERR_PARAM; + + /* + * If ext2 is not present, but ext4 or ext4dev are, then + * disclaim we are ext2 + */ + if (!system_supports_ext2() && + (system_supports_ext4() || system_supports_ext4dev()) && + get_linux_version() >= EXT4_SUPPORTS_EXT2) + return -BLKID_ERR_PARAM; + + ext_get_info(pr, 2, es); + return 0; +} + +static int probe_ext3(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct ext2_super_block *es; + uint32_t fc, frc, fi; + + es = ext_get_super(pr, &fc, &fi, &frc); + if (!es) + return -BLKID_ERR_PARAM; + + /* ext3 requires journal */ + if (!(fc & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) + return -BLKID_ERR_PARAM; + + /* Any features which ext3 doesn't understand */ + if ((frc & EXT3_FEATURE_RO_COMPAT_UNSUPPORTED) || + (fi & EXT3_FEATURE_INCOMPAT_UNSUPPORTED)) + return -BLKID_ERR_PARAM; + + ext_get_info(pr, 3, es); + return 0; +} + + +static int probe_ext4dev(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct ext2_super_block *es; + uint32_t fc, frc, fi; + + es = ext_get_super(pr, &fc, &fi, &frc); + if (!es) + return -BLKID_ERR_PARAM; + + /* Distinguish from jbd */ + if (fi & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) + return -BLKID_ERR_PARAM; + + /* + * If the filesystem does not have a journal and ext2 and ext4 + * is not present, then force this to be detected as an + * ext4dev filesystem. + */ + if (!(fc & EXT3_FEATURE_COMPAT_HAS_JOURNAL) && + !system_supports_ext2() && !system_supports_ext4() && + system_supports_ext4dev() && + get_linux_version() >= EXT4_SUPPORTS_EXT2) + goto force_ext4dev; + + /* + * If the filesystem is marked as OK for use by in-development + * filesystem code, but ext4dev is not supported, and ext4 is, + * then don't call ourselves ext4dev, since we should be + * detected as ext4 in that case. + * + * If the filesystem is marked as in use by production + * filesystem, then it can only be used by ext4 and NOT by + * ext4dev, so always disclaim we are ext4dev in that case. + */ + if (le32_to_cpu(es->s_flags) & EXT2_FLAGS_TEST_FILESYS) { + if (!system_supports_ext4dev() && system_supports_ext4()) + return -BLKID_ERR_PARAM; + } else + return -BLKID_ERR_PARAM; + +force_ext4dev: + ext_get_info(pr, 4, es); + return 0; +} + +static int probe_ext4(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct ext2_super_block *es; + uint32_t fc, frc, fi; + + es = ext_get_super(pr, &fc, &fi, &frc); + if (!es) + return -1; + + /* Distinguish from jbd */ + if (fi & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) + return -BLKID_ERR_PARAM; + + /* + * If the filesystem does not have a journal and ext2 is not + * present, then force this to be detected as an ext2 + * filesystem. + */ + if (!(fc & EXT3_FEATURE_COMPAT_HAS_JOURNAL) && + !system_supports_ext2() && system_supports_ext4() && + get_linux_version() >= EXT4_SUPPORTS_EXT2) + goto force_ext4; + + /* Ext4 has at least one feature which ext3 doesn't understand */ + if (!(frc & EXT3_FEATURE_RO_COMPAT_UNSUPPORTED) && + !(fi & EXT3_FEATURE_INCOMPAT_UNSUPPORTED)) + return -BLKID_ERR_PARAM; + +force_ext4: + /* + * If the filesystem is a OK for use by in-development + * filesystem code, and ext4dev is supported or ext4 is not + * supported, then don't call ourselves ext4, so we can redo + * the detection and mark the filesystem as ext4dev. + * + * If the filesystem is marked as in use by production + * filesystem, then it can only be used by ext4 and NOT by + * ext4dev. + */ + if (le32_to_cpu(es->s_flags) & EXT2_FLAGS_TEST_FILESYS) { + if (system_supports_ext4dev() || !system_supports_ext4()) + return -BLKID_ERR_PARAM; + } + + ext_get_info(pr, 4, es); + return 0; +} + +#define BLKID_EXT_MAGICS \ + { \ + { \ + .magic = EXT_SB_MAGIC, \ + .len = sizeof(EXT_SB_MAGIC) - 1, \ + .kboff = EXT_SB_KBOFF, \ + .sboff = EXT_MAG_OFF \ + }, \ + { NULL } \ + } + +const struct blkid_idinfo jbd_idinfo = +{ + .name = "jbd", + .usage = BLKID_USAGE_OTHER, + .probefunc = probe_jbd, + .magics = BLKID_EXT_MAGICS +}; + +const struct blkid_idinfo ext2_idinfo = +{ + .name = "ext2", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_ext2, + .magics = BLKID_EXT_MAGICS +}; + +const struct blkid_idinfo ext3_idinfo = +{ + .name = "ext3", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_ext3, + .magics = BLKID_EXT_MAGICS +}; + +const struct blkid_idinfo ext4_idinfo = +{ + .name = "ext4", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_ext4, + .magics = BLKID_EXT_MAGICS +}; + +const struct blkid_idinfo ext4dev_idinfo = +{ + .name = "ext4dev", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_ext4dev, + .magics = BLKID_EXT_MAGICS +}; + diff --git a/libblkid/src/superblocks/gfs.c b/libblkid/src/superblocks/gfs.c new file mode 100644 index 00000000..b2c01630 --- /dev/null +++ b/libblkid/src/superblocks/gfs.c @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2008 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include + +#include "superblocks.h" + +/* Common gfs/gfs2 constants: */ +#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 */ +} __attribute__((packed)); + +static int probe_gfs(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct gfs2_sb *sbd; + + sbd = blkid_probe_get_sb(pr, mag, struct gfs2_sb); + if (!sbd) + return -1; + + if (be32_to_cpu(sbd->sb_fs_format) == GFS_FORMAT_FS && + be32_to_cpu(sbd->sb_multihost_format) == GFS_FORMAT_MULTI) + { + if (*sbd->sb_locktable) + blkid_probe_set_label(pr, + (unsigned char *) sbd->sb_locktable, + sizeof(sbd->sb_locktable)); + + blkid_probe_set_uuid(pr, sbd->sb_uuid); + return 0; + } + + return -1; +} + +static int probe_gfs2(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct gfs2_sb *sbd; + + sbd = blkid_probe_get_sb(pr, mag, struct gfs2_sb); + if (!sbd) + return -1; + + if (be32_to_cpu(sbd->sb_fs_format) == GFS2_FORMAT_FS && + be32_to_cpu(sbd->sb_multihost_format) == GFS2_FORMAT_MULTI) + { + if (*sbd->sb_locktable) + blkid_probe_set_label(pr, + (unsigned char *) sbd->sb_locktable, + sizeof(sbd->sb_locktable)); + blkid_probe_set_uuid(pr, sbd->sb_uuid); + blkid_probe_set_version(pr, "1"); + return 0; + } + return -1; +} + +const struct blkid_idinfo gfs_idinfo = +{ + .name = "gfs", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_gfs, + .minsz = 32 * 1024 * 1024, /* minimal size of GFS journal */ + .magics = + { + { .magic = "\x01\x16\x19\x70", .len = 4, .kboff = 64 }, + { NULL } + } +}; + +const struct blkid_idinfo gfs2_idinfo = +{ + .name = "gfs2", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_gfs2, + .minsz = 32 * 1024 * 1024, /* minimal size of GFS journal */ + .magics = + { + { .magic = "\x01\x16\x19\x70", .len = 4, .kboff = 64 }, + { NULL } + } +}; + diff --git a/libblkid/src/superblocks/hfs.c b/libblkid/src/superblocks/hfs.c new file mode 100644 index 00000000..e043994e --- /dev/null +++ b/libblkid/src/superblocks/hfs.c @@ -0,0 +1,321 @@ +/* + * Copyright (C) 2004-2008 Kay Sievers + * Copyright (C) 2008 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include + +#include "superblocks.h" +#include "md5.h" + +/* HFS / HFS+ */ +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]; +} __attribute__((packed)); + +struct hfs_mdb { + uint8_t signature[2]; + uint32_t cr_date; + uint32_t ls_Mod; + uint16_t atrb; + uint16_t nm_fls; + uint16_t vbm_st; + uint16_t alloc_ptr; + uint16_t nm_al_blks; + uint32_t al_blk_size; + uint32_t clp_size; + uint16_t al_bl_st; + uint32_t nxt_cnid; + uint16_t free_bks; + uint8_t label_len; + uint8_t label[27]; + uint32_t vol_bkup; + uint16_t vol_seq_num; + uint32_t wr_cnt; + uint32_t xt_clump_size; + uint32_t ct_clump_size; + uint16_t num_root_dirs; + uint32_t file_count; + uint32_t dir_count; + struct hfs_finder_info finder_info; + uint8_t embed_sig[2]; + uint16_t embed_startblock; + uint16_t embed_blockcount; +} __attribute__((packed)); + + +#define HFS_NODE_LEAF 0xff +#define HFSPLUS_POR_CNID 1 + +struct hfsplus_bnode_descriptor { + uint32_t next; + uint32_t prev; + uint8_t type; + uint8_t height; + uint16_t num_recs; + uint16_t reserved; +} __attribute__((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; +} __attribute__((packed)); + +struct hfsplus_catalog_key { + uint16_t key_len; + uint32_t parent_id; + uint16_t unicode_len; + uint8_t unicode[255 * 2]; +} __attribute__((packed)); + +struct hfsplus_extent { + uint32_t start_block; + uint32_t block_count; +} __attribute__((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]; +} __attribute__((packed)); + +struct hfsplus_vol_header { + uint8_t signature[2]; + uint16_t version; + uint32_t attributes; + uint32_t last_mount_vers; + uint32_t reserved; + uint32_t create_date; + uint32_t modify_date; + uint32_t backup_date; + uint32_t checked_date; + uint32_t file_count; + uint32_t folder_count; + uint32_t blocksize; + uint32_t total_blocks; + uint32_t free_blocks; + uint32_t next_alloc; + uint32_t rsrc_clump_sz; + uint32_t data_clump_sz; + uint32_t next_cnid; + uint32_t write_count; + uint64_t encodings_bmp; + struct hfs_finder_info finder_info; + struct hfsplus_fork alloc_file; + struct hfsplus_fork ext_file; + struct hfsplus_fork cat_file; + struct hfsplus_fork attr_file; + struct hfsplus_fork start_file; +} __attribute__((packed)); + +#define HFSPLUS_SECTOR_SIZE 512 + +static int hfs_set_uuid(blkid_probe pr, unsigned char const *hfs_info, size_t len) +{ + static unsigned char const hash_init[16] = { + 0xb3, 0xe2, 0x0f, 0x39, 0xf2, 0x92, 0x11, 0xd6, + 0x97, 0xa4, 0x00, 0x30, 0x65, 0x43, 0xec, 0xac + }; + unsigned char uuid[16]; + struct MD5Context md5c; + + if (memcmp(hfs_info, "\0\0\0\0\0\0\0\0", len) == 0) + return -1; + MD5Init(&md5c); + MD5Update(&md5c, hash_init, 16); + MD5Update(&md5c, hfs_info, len); + MD5Final(uuid, &md5c); + uuid[6] = 0x30 | (uuid[6] & 0x0f); + uuid[8] = 0x80 | (uuid[8] & 0x3f); + return blkid_probe_set_uuid(pr, uuid); +} + +static int probe_hfs(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct hfs_mdb *hfs; + + hfs = blkid_probe_get_sb(pr, mag, struct hfs_mdb); + if (!hfs) + return -1; + + if ((memcmp(hfs->embed_sig, "H+", 2) == 0) || + (memcmp(hfs->embed_sig, "HX", 2) == 0)) + return 1; /* Not hfs, but an embedded HFS+ */ + + hfs_set_uuid(pr, hfs->finder_info.id, sizeof(hfs->finder_info.id)); + + blkid_probe_set_label(pr, hfs->label, hfs->label_len); + return 0; +} + +static int probe_hfsplus(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT]; + struct hfsplus_bnode_descriptor *descr; + struct hfsplus_bheader_record *bnode; + struct hfsplus_catalog_key *key; + struct hfsplus_vol_header *hfsplus; + struct hfs_mdb *sbd; + unsigned int alloc_block_size; + unsigned int alloc_first_block; + unsigned int embed_first_block; + unsigned int off = 0; + unsigned int blocksize; + unsigned int cat_block; + unsigned int ext_block_start; + unsigned int ext_block_count; + unsigned int record_count; + unsigned int leaf_node_head; + unsigned int leaf_node_count; + unsigned int leaf_node_size; + unsigned int leaf_block; + int ext; + uint64_t leaf_off; + unsigned char *buf; + + sbd = blkid_probe_get_sb(pr, mag, struct hfs_mdb); + if (!sbd) + return -1; + + /* Check for a HFS+ volume embedded in a HFS volume */ + if (memcmp(sbd->signature, "BD", 2) == 0) { + if ((memcmp(sbd->embed_sig, "H+", 2) != 0) && + (memcmp(sbd->embed_sig, "HX", 2) != 0)) + /* This must be an HFS volume, so fail */ + return 1; + + alloc_block_size = be32_to_cpu(sbd->al_blk_size); + alloc_first_block = be16_to_cpu(sbd->al_bl_st); + embed_first_block = be16_to_cpu(sbd->embed_startblock); + off = (alloc_first_block * 512) + + (embed_first_block * alloc_block_size); + + buf = blkid_probe_get_buffer(pr, + off + (mag->kboff * 1024), + sizeof(struct hfsplus_vol_header)); + hfsplus = (struct hfsplus_vol_header *) buf; + + } else + hfsplus = blkid_probe_get_sb(pr, mag, + struct hfsplus_vol_header); + + if (!hfsplus) + return -1; + + if ((memcmp(hfsplus->signature, "H+", 2) != 0) && + (memcmp(hfsplus->signature, "HX", 2) != 0)) + return 1; + + hfs_set_uuid(pr, hfsplus->finder_info.id, sizeof(hfsplus->finder_info.id)); + + blocksize = be32_to_cpu(hfsplus->blocksize); + if (blocksize < HFSPLUS_SECTOR_SIZE) + return -1; + + memcpy(extents, hfsplus->cat_file.extents, sizeof(extents)); + cat_block = be32_to_cpu(extents[0].start_block); + + buf = blkid_probe_get_buffer(pr, + off + ((blkid_loff_t) cat_block * blocksize), 0x2000); + if (!buf) + return 0; + + bnode = (struct hfsplus_bheader_record *) + &buf[sizeof(struct hfsplus_bnode_descriptor)]; + + leaf_node_head = be32_to_cpu(bnode->leaf_head); + leaf_node_size = be16_to_cpu(bnode->node_size); + leaf_node_count = be32_to_cpu(bnode->leaf_count); + if (leaf_node_count == 0) + return 0; + + 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); + if (ext_block_count == 0) + return 0; + + /* this is our extent */ + if (leaf_block < ext_block_count) + break; + + leaf_block -= ext_block_count; + } + if (ext == HFSPLUS_EXTENT_COUNT) + return 0; + + leaf_off = (ext_block_start + leaf_block) * blocksize; + + buf = blkid_probe_get_buffer(pr, + (blkid_loff_t) off + leaf_off, + leaf_node_size); + if (!buf) + return 0; + + descr = (struct hfsplus_bnode_descriptor *) buf; + record_count = be16_to_cpu(descr->num_recs); + if (record_count == 0) + return 0; + + if (descr->type != HFS_NODE_LEAF) + return 0; + + key = (struct hfsplus_catalog_key *) + &buf[sizeof(struct hfsplus_bnode_descriptor)]; + + if (be32_to_cpu(key->parent_id) != HFSPLUS_POR_CNID) + return 0; + + blkid_probe_set_utf8label(pr, key->unicode, + be16_to_cpu(key->unicode_len) * 2, + BLKID_ENC_UTF16BE); + return 0; +} + +const struct blkid_idinfo hfs_idinfo = +{ + .name = "hfs", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_hfs, + .flags = BLKID_IDINFO_TOLERANT, + .magics = + { + { .magic = "BD", .len = 2, .kboff = 1 }, + { NULL } + } +}; + +const struct blkid_idinfo hfsplus_idinfo = +{ + .name = "hfsplus", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_hfsplus, + .magics = + { + { .magic = "BD", .len = 2, .kboff = 1 }, + { .magic = "H+", .len = 2, .kboff = 1 }, + { .magic = "HX", .len = 2, .kboff = 1 }, + { NULL } + } +}; diff --git a/libblkid/src/superblocks/highpoint_raid.c b/libblkid/src/superblocks/highpoint_raid.c new file mode 100644 index 00000000..25e3114b --- /dev/null +++ b/libblkid/src/superblocks/highpoint_raid.c @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2008 Karel Zak + * + * Inspired by libvolume_id by + * Kay Sievers + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include + +#include "superblocks.h" + +struct hpt45x_metadata { + uint32_t magic; +}; + +#define HPT45X_MAGIC_OK 0x5a7816f3 +#define HPT45X_MAGIC_BAD 0x5a7816fd + +static int probe_highpoint45x(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct hpt45x_metadata *hpt; + uint64_t off; + uint32_t magic; + + if (pr->size < 0x10000) + return -1; + if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) + return -1; + + off = ((pr->size / 0x200) - 11) * 0x200; + hpt = (struct hpt45x_metadata *) + blkid_probe_get_buffer(pr, + off, + sizeof(struct hpt45x_metadata)); + if (!hpt) + return -1; + magic = le32_to_cpu(hpt->magic); + if (magic != HPT45X_MAGIC_OK && magic != HPT45X_MAGIC_BAD) + return -1; + if (blkid_probe_set_magic(pr, off, sizeof(hpt->magic), + (unsigned char *) &hpt->magic)) + return -1; + return 0; +} + +static int probe_highpoint37x(blkid_probe pr, const struct blkid_idmag *mag) +{ + if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) + return -1; + return 0; +} + + +const struct blkid_idinfo highpoint45x_idinfo = { + .name = "hpt45x_raid_member", + .usage = BLKID_USAGE_RAID, + .probefunc = probe_highpoint45x, + .magics = BLKID_NONE_MAGIC +}; + +const struct blkid_idinfo highpoint37x_idinfo = { + .name = "hpt37x_raid_member", + .usage = BLKID_USAGE_RAID, + .probefunc = probe_highpoint37x, + .magics = { + /* + * Superblok offset: 4608 bytes (9 sectors) + * Magic string offset within superblock: 32 bytes + * + * kboff = (4608 + 32) / 1024 + * sboff = (4608 + 32) % kboff + */ + { .magic = "\xf0\x16\x78\x5a", .len = 4, .kboff = 4, .sboff = 544 }, + { .magic = "\xfd\x16\x78\x5a", .len = 4, .kboff = 4, .sboff = 544 }, + { NULL } + } +}; + + diff --git a/libblkid/src/superblocks/hpfs.c b/libblkid/src/superblocks/hpfs.c new file mode 100644 index 00000000..f9b851a4 --- /dev/null +++ b/libblkid/src/superblocks/hpfs.c @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2008 Karel Zak + * + * Inspired by libvolume_id by + * Kay Sievers + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include + +#include "superblocks.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]; +} __attribute__((packed)); + +struct hpfs_super_block +{ + uint8_t magic[4]; + uint8_t magic1[4]; + uint8_t version; +} __attribute__((packed)); + +struct hpfs_spare_super +{ + uint8_t magic[4]; + uint8_t magic1[4]; +} __attribute__((packed)); + + +#define HPFS_SB_OFFSET 0x2000 +#define HPFS_SBSPARE_OFFSET 0x2200 + +static int probe_hpfs(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct hpfs_super_block *hs; + struct hpfs_spare_super *hss; + struct hpfs_boot_block *hbb; + uint8_t version; + + /* super block */ + hs = blkid_probe_get_sb(pr, mag, struct hpfs_super_block); + if (!hs) + return -1; + version = hs->version; + + /* spare super block */ + hss = (struct hpfs_spare_super *) + blkid_probe_get_buffer(pr, + HPFS_SBSPARE_OFFSET, + sizeof(struct hpfs_spare_super)); + if (!hss) + return -1; + if (memcmp(hss->magic, "\x49\x18\x91\xf9", 4) != 0) + return -1; + + /* boot block (with UUID and LABEL) */ + hbb = (struct hpfs_boot_block *) + blkid_probe_get_buffer(pr, + 0, + sizeof(struct hpfs_boot_block)); + if (!hbb) + return -1; + if (memcmp(hbb->magic, "\x55\xaa", 2) == 0 && + memcmp(hbb->sig_hpfs, "HPFS", 4) == 0 && + hbb->sig_28h == 0x28) { + blkid_probe_set_label(pr, hbb->vol_label, sizeof(hbb->vol_label)); + blkid_probe_sprintf_uuid(pr, + hbb->vol_serno, sizeof(hbb->vol_serno), + "%02X%02X-%02X%02X", + hbb->vol_serno[3], hbb->vol_serno[2], + hbb->vol_serno[1], hbb->vol_serno[0]); + } + blkid_probe_sprintf_version(pr, "%u", version); + + return 0; +} + +const struct blkid_idinfo hpfs_idinfo = +{ + .name = "hpfs", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_hpfs, + .magics = + { + { + .magic = "\x49\xe8\x95\xf9", + .len = 4, + .kboff = (HPFS_SB_OFFSET >> 10) + }, + { NULL } + } +}; + + diff --git a/libblkid/src/superblocks/iso9660.c b/libblkid/src/superblocks/iso9660.c new file mode 100644 index 00000000..9f3ce2e6 --- /dev/null +++ b/libblkid/src/superblocks/iso9660.c @@ -0,0 +1,153 @@ +/* + * Copyright (C) 1999 by Andries Brouwer + * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o + * Copyright (C) 2001 by Andreas Dilger + * Copyright (C) 2004 Kay Sievers + * Copyright (C) 2008 Karel Zak + * + * Inspired also by libvolume_id by + * Kay Sievers + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include + +#include "superblocks.h" + +/* PVD - Primary volume descriptor */ +struct iso_volume_descriptor { + unsigned char vd_type; + unsigned char vd_id[5]; + unsigned char vd_version; + unsigned char flags; + unsigned char system_id[32]; + unsigned char volume_id[32]; + unsigned char unused[8]; + unsigned char space_size[8]; + unsigned char escape_sequences[8]; +} __attribute__((packed)); + +#define ISO_SUPERBLOCK_OFFSET 0x8000 +#define ISO_SECTOR_SIZE 0x800 +#define ISO_VD_OFFSET (ISO_SUPERBLOCK_OFFSET + ISO_SECTOR_SIZE) +#define ISO_VD_SUPPLEMENTARY 0x2 +#define ISO_VD_END 0xff +#define ISO_VD_MAX 16 + +struct high_sierra_volume_descriptor { + unsigned char foo[8]; + unsigned char type; + unsigned char id[5]; + unsigned char version; + unsigned char unused1; + unsigned char system_id[32]; + unsigned char volume_id[32]; +} __attribute__((packed)); + +/* returns 1 if the begin of @ascii is equal to @utf16 string. + */ +static int ascii_eq_utf16be(unsigned char *ascii, + unsigned char *utf16, size_t len) +{ + int a, u; + + for (a = 0, u = 0; u < len; a++, u += 2) { + if (utf16[u] != 0x0 || ascii[a] != utf16[u + 1]) + return 0; + } + return 1; +} + +/* old High Sierra format */ +static int probe_iso9660_hsfs(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct high_sierra_volume_descriptor *iso; + + iso = blkid_probe_get_sb(pr, mag, struct high_sierra_volume_descriptor); + if (!iso) + return -1; + + blkid_probe_set_version(pr, "High Sierra"); + blkid_probe_set_label(pr, iso->volume_id, sizeof(iso->volume_id)); + return 0; +} + +/* iso9660 [+ Microsoft Joliet Extension] */ +static int probe_iso9660(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct iso_volume_descriptor *iso; + unsigned char label[32]; + int i; + int off; + + if (strcmp(mag->magic, "CDROM") == 0) + return probe_iso9660_hsfs(pr, mag); + + iso = blkid_probe_get_sb(pr, mag, struct iso_volume_descriptor); + if (!iso) + return -1; + + memcpy(label, iso->volume_id, sizeof(label)); + + /* Joliet Extension */ + off = ISO_VD_OFFSET; + for (i = 0; i < ISO_VD_MAX; i++) { + iso = (struct iso_volume_descriptor *) + blkid_probe_get_buffer(pr, + off, + sizeof(struct iso_volume_descriptor)); + + if (iso == NULL || iso->vd_type == ISO_VD_END) + break; + if (iso->vd_type != ISO_VD_SUPPLEMENTARY) + continue; + + if (memcmp(iso->escape_sequences, "%/@", 3) == 0 || + memcmp(iso->escape_sequences, "%/C", 3) == 0 || + memcmp(iso->escape_sequences, "%/E", 3) == 0) { + + blkid_probe_set_version(pr, "Joliet Extension"); + + /* Is the Joliet (UTF16BE) label equal to the label in + * the PVD? If yes, use PVD label. The Jolied version + * of the label could be trimed (because UTF16..). + */ + if (ascii_eq_utf16be(label, iso->volume_id, 32)) + break; + + blkid_probe_set_utf8label(pr, + iso->volume_id, + sizeof(iso->volume_id), + BLKID_ENC_UTF16BE); + goto has_label; + } + off += ISO_SECTOR_SIZE; + } + + /* Joliet not found, let use standard iso label */ + blkid_probe_set_label(pr, label, sizeof(label)); + +has_label: + return 0; +} + + +const struct blkid_idinfo iso9660_idinfo = +{ + .name = "iso9660", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_iso9660, + .flags = BLKID_IDINFO_TOLERANT, + .magics = + { + { .magic = "CD001", .len = 5, .kboff = 32, .sboff = 1 }, + { .magic = "CDROM", .len = 5, .kboff = 32, .sboff = 9 }, + { NULL } + } +}; + diff --git a/libblkid/src/superblocks/isw_raid.c b/libblkid/src/superblocks/isw_raid.c new file mode 100644 index 00000000..ac6251d7 --- /dev/null +++ b/libblkid/src/superblocks/isw_raid.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2008 Karel Zak + * + * Inspired by libvolume_id by + * Kay Sievers + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include + +#include "superblocks.h" + +struct isw_metadata { + uint8_t sig[32]; + uint32_t check_sum; + uint32_t mpb_size; + uint32_t family_num; + uint32_t generation_num; +}; + +#define ISW_SIGNATURE "Intel Raid ISM Cfg Sig. " + + +static int probe_iswraid(blkid_probe pr, const struct blkid_idmag *mag) +{ + uint64_t off; + struct isw_metadata *isw; + + if (pr->size < 0x10000) + return -1; + if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) + return -1; + + off = ((pr->size / 0x200) - 2) * 0x200; + isw = (struct isw_metadata *) + blkid_probe_get_buffer(pr, + off, + sizeof(struct isw_metadata)); + if (!isw) + return -1; + if (memcmp(isw->sig, ISW_SIGNATURE, sizeof(ISW_SIGNATURE)-1) != 0) + return -1; + if (blkid_probe_sprintf_version(pr, "%6s", + &isw->sig[sizeof(ISW_SIGNATURE)-1]) != 0) + return -1; + if (blkid_probe_set_magic(pr, off, sizeof(isw->sig), + (unsigned char *) isw->sig)) + return -1; + return 0; +} + +const struct blkid_idinfo iswraid_idinfo = { + .name = "isw_raid_member", + .usage = BLKID_USAGE_RAID, + .probefunc = probe_iswraid, + .magics = BLKID_NONE_MAGIC +}; + + diff --git a/libblkid/src/superblocks/jfs.c b/libblkid/src/superblocks/jfs.c new file mode 100644 index 00000000..9a49c674 --- /dev/null +++ b/libblkid/src/superblocks/jfs.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 1999 by Andries Brouwer + * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o + * Copyright (C) 2001 by Andreas Dilger + * Copyright (C) 2004 Kay Sievers + * Copyright (C) 2008 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include +#include +#include + +#include "superblocks.h" + +struct jfs_super_block { + unsigned char js_magic[4]; + uint32_t js_version; + uint64_t js_size; + uint32_t js_bsize; /* 4: aggregate block size in bytes */ + uint16_t js_l2bsize; /* 2: log2 of s_bsize */ + uint16_t js_l2bfactor; /* 2: log2(s_bsize/hardware block size) */ + uint32_t js_pbsize; /* 4: hardware/LVM block size in bytes */ + uint16_t js_l2pbsize; /* 2: log2 of s_pbsize */ + uint16_t js_pad; /* 2: padding necessary for alignment */ + uint32_t js_dummy2[26]; + unsigned char js_uuid[16]; + unsigned char js_label[16]; + unsigned char js_loguuid[16]; +}; + +static int probe_jfs(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct jfs_super_block *js; + + js = blkid_probe_get_sb(pr, mag, struct jfs_super_block); + if (!js) + return -1; + if (le32_to_cpu(js->js_bsize) != (1 << le16_to_cpu(js->js_l2bsize))) + return 1; + if (le32_to_cpu(js->js_pbsize) != (1 << le16_to_cpu(js->js_l2pbsize))) + return 1; + if ((le16_to_cpu(js->js_l2bsize) - le16_to_cpu(js->js_l2pbsize)) != + le16_to_cpu(js->js_l2bfactor)) + return 1; + + if (strlen((char *) js->js_label)) + blkid_probe_set_label(pr, js->js_label, sizeof(js->js_label)); + blkid_probe_set_uuid(pr, js->js_uuid); + return 0; +} + + +const struct blkid_idinfo jfs_idinfo = +{ + .name = "jfs", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_jfs, + .minsz = 16 * 1024 * 1024, + .magics = + { + { .magic = "JFS1", .len = 4, .kboff = 32 }, + { NULL } + } +}; + diff --git a/libblkid/src/superblocks/jmicron_raid.c b/libblkid/src/superblocks/jmicron_raid.c new file mode 100644 index 00000000..d35b17f8 --- /dev/null +++ b/libblkid/src/superblocks/jmicron_raid.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2008 Karel Zak + * + * Inspired by libvolume_id by + * Kay Sievers + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ + +#include +#include +#include +#include +#include + +#include "superblocks.h" + +struct jm_metadata { + int8_t signature[2]; + uint8_t minor_version; + uint8_t major_version; + uint16_t checksum; +}; + +#define JM_SIGNATURE "JM" + +static int probe_jmraid(blkid_probe pr, const struct blkid_idmag *mag) +{ + uint64_t off; + struct jm_metadata *jm; + + if (pr->size < 0x10000) + return -1; + if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) + return -1; + + off = ((pr->size / 0x200) - 1) * 0x200; + jm = (struct jm_metadata *) + blkid_probe_get_buffer(pr, + off, + sizeof(struct jm_metadata)); + if (!jm) + return -1; + if (memcmp(jm->signature, JM_SIGNATURE, sizeof(JM_SIGNATURE) - 1) != 0) + return -1; + if (blkid_probe_sprintf_version(pr, "%u.%u", + jm->major_version, jm->minor_version) != 0) + return -1; + if (blkid_probe_set_magic(pr, off, sizeof(jm->signature), + (unsigned char *) jm->signature)) + return -1; + return 0; +} + +const struct blkid_idinfo jmraid_idinfo = { + .name = "jmicron_raid_member", + .usage = BLKID_USAGE_RAID, + .probefunc = probe_jmraid, + .magics = BLKID_NONE_MAGIC +}; + + diff --git a/libblkid/src/superblocks/linux_raid.c b/libblkid/src/superblocks/linux_raid.c new file mode 100644 index 00000000..e74f57de --- /dev/null +++ b/libblkid/src/superblocks/linux_raid.c @@ -0,0 +1,257 @@ +/* + * Copyright (C) 2008 Karel Zak + * + * Inspired by libvolume_id by + * Kay Sievers + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include + +#include "superblocks.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; +}; + +/* + * Version-1, little-endian. + */ +struct mdp1_super_block { + /* constant array information - 128 bytes */ + uint32_t magic; /* MD_SB_MAGIC: 0xa92b4efc - little endian */ + uint32_t major_version; /* 1 */ + uint32_t feature_map; /* 0 for now */ + uint32_t pad0; /* always set to 0 when writing */ + + uint8_t set_uuid[16]; /* user-space generated. */ + unsigned char set_name[32]; /* set and interpreted by user-space */ + + uint64_t ctime; /* lo 40 bits are seconds, top 24 are microseconds or 0*/ + uint32_t level; /* -4 (multipath), -1 (linear), 0,1,4,5 */ + uint32_t layout; /* only for raid5 currently */ + uint64_t size; /* used size of component devices, in 512byte sectors */ + + uint32_t chunksize; /* in 512byte sectors */ + uint32_t raid_disks; + uint32_t bitmap_offset; /* sectors after start of superblock that bitmap starts + * NOTE: signed, so bitmap can be before superblock + * only meaningful of feature_map[0] is set. + */ + + /* These are only valid with feature bit '4' */ + uint32_t new_level; /* new level we are reshaping to */ + uint64_t reshape_position; /* next address in array-space for reshape */ + uint32_t delta_disks; /* change in number of raid_disks */ + uint32_t new_layout; /* new layout */ + uint32_t new_chunk; /* new chunk size (bytes) */ + uint8_t pad1[128-124]; /* set to 0 when written */ + + /* constant this-device information - 64 bytes */ + uint64_t data_offset; /* sector start of data, often 0 */ + uint64_t data_size; /* sectors in this device that can be used for data */ + uint64_t super_offset; /* sector start of this superblock */ + uint64_t recovery_offset;/* sectors before this offset (from data_offset) have been recovered */ + uint32_t dev_number; /* permanent identifier of this device - not role in raid */ + uint32_t cnt_corrected_read; /* number of read errors that were corrected by re-writing */ + uint8_t device_uuid[16]; /* user-space setable, ignored by kernel */ + uint8_t devflags; /* per-device flags. Only one defined...*/ + uint8_t pad2[64-57]; /* set to 0 when writing */ + + /* array state information - 64 bytes */ + uint64_t utime; /* 40 bits second, 24 btes microseconds */ + uint64_t events; /* incremented when superblock updated */ + uint64_t resync_offset; /* data before this offset (from data_offset) known to be in sync */ + uint32_t sb_csum; /* checksum upto dev_roles[max_dev] */ + uint32_t max_dev; /* size of dev_roles[] array to consider */ + uint8_t pad3[64-32]; /* set to 0 when writing */ + + /* device state information. Indexed by dev_number. + * 2 bytes per device + * Note there are no per-device state flags. State information is rolled + * into the 'roles' value. If a device is spare or faulty, then it doesn't + * have a meaningful role. + */ + uint16_t dev_roles[0]; /* role in array, or 0xffff for a spare, or 0xfffe for faulty */ +}; + + +#define MD_RESERVED_BYTES 0x10000 +#define MD_SB_MAGIC 0xa92b4efc + +static int probe_raid0(blkid_probe pr, blkid_loff_t off) +{ + struct mdp0_super_block *mdp0; + union { + uint32_t ints[4]; + uint8_t bytes[16]; + } uuid; + uint32_t ma, mi, pa; + uint64_t size; + + if (pr->size < MD_RESERVED_BYTES) + return -1; + mdp0 = (struct mdp0_super_block *) + blkid_probe_get_buffer(pr, + off, + sizeof(struct mdp0_super_block)); + if (!mdp0) + return -1; + + memset(uuid.ints, 0, sizeof(uuid.ints)); + + if (le32_to_cpu(mdp0->md_magic) == MD_SB_MAGIC) { + uuid.ints[0] = swab32(mdp0->set_uuid0); + if (le32_to_cpu(mdp0->minor_version) >= 90) { + uuid.ints[1] = swab32(mdp0->set_uuid1); + uuid.ints[2] = swab32(mdp0->set_uuid2); + uuid.ints[3] = swab32(mdp0->set_uuid3); + } + ma = le32_to_cpu(mdp0->major_version); + mi = le32_to_cpu(mdp0->minor_version); + pa = le32_to_cpu(mdp0->patch_version); + size = le32_to_cpu(mdp0->size); + + } 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; + } + ma = be32_to_cpu(mdp0->major_version); + mi = be32_to_cpu(mdp0->minor_version); + pa = be32_to_cpu(mdp0->patch_version); + size = be32_to_cpu(mdp0->size); + } else + return 1; + + size <<= 10; /* convert KiB to bytes */ + + if (pr->size < size + MD_RESERVED_BYTES) + /* device is too small */ + return 1; + + if (off < size) + /* no space before superblock */ + return 1; + + /* + * Check for collisions between RAID and partition table + * + * For example the superblock is at the end of the last partition, it's + * the same possition as at the end of the disk... + */ + if ((S_ISREG(pr->mode) || blkid_probe_is_wholedisk(pr)) && + blkid_probe_is_covered_by_pt(pr, + off - size, /* min. start */ + size + MD_RESERVED_BYTES)) { /* min. length */ + + /* ignore this superblock, it's within any partition and + * we are working with whole-disk now */ + return 1; + } + + if (blkid_probe_sprintf_version(pr, "%u.%u.%u", ma, mi, pa) != 0) + return -1; + if (blkid_probe_set_uuid(pr, (unsigned char *) uuid.bytes) != 0) + return -1; + if (blkid_probe_set_magic(pr, off, sizeof(mdp0->md_magic), + (unsigned char *) &mdp0->md_magic)) + return -1; + return 0; +} + +static int probe_raid1(blkid_probe pr, off_t off) +{ + struct mdp1_super_block *mdp1; + + mdp1 = (struct mdp1_super_block *) + blkid_probe_get_buffer(pr, + off, + sizeof(struct mdp1_super_block)); + if (!mdp1) + return -1; + if (le32_to_cpu(mdp1->magic) != MD_SB_MAGIC) + return -1; + if (le32_to_cpu(mdp1->major_version) != 1) + return -1; + if (le64_to_cpu(mdp1->super_offset) != off >> 9) + return -1; + if (blkid_probe_set_uuid(pr, (unsigned char *) mdp1->set_uuid) != 0) + return -1; + if (blkid_probe_set_uuid_as(pr, + (unsigned char *) mdp1->device_uuid, "UUID_SUB") != 0) + return -1; + if (blkid_probe_set_label(pr, mdp1->set_name, + sizeof(mdp1->set_name)) != 0) + return -1; + if (blkid_probe_set_magic(pr, off, sizeof(mdp1->magic), + (unsigned char *) &mdp1->magic)) + return -1; + return 0; +} + +int probe_raid(blkid_probe pr, const struct blkid_idmag *mag) +{ + const char *ver = NULL; + + if (pr->size > MD_RESERVED_BYTES) { + /* version 0 at the end of the device */ + uint64_t sboff = (pr->size & ~(MD_RESERVED_BYTES - 1)) + - MD_RESERVED_BYTES; + if (probe_raid0(pr, sboff) == 0) + return 0; + + /* version 1.0 at the end of the device */ + sboff = (pr->size & ~(0x1000 - 1)) - 0x2000; + if (probe_raid1(pr, sboff) == 0) + ver = "1.0"; + } + + if (!ver) { + /* version 1.1 at the start of the device */ + if (probe_raid1(pr, 0) == 0) + ver = "1.1"; + + /* version 1.2 at 4k offset from the start */ + else if (probe_raid1(pr, 0x1000) == 0) + ver = "1.2"; + } + + if (ver) { + blkid_probe_set_version(pr, ver); + return 0; + } + return -1; +} + + +const struct blkid_idinfo linuxraid_idinfo = { + .name = "linux_raid_member", + .usage = BLKID_USAGE_RAID, + .probefunc = probe_raid, + .magics = BLKID_NONE_MAGIC +}; + + diff --git a/libblkid/src/superblocks/lsi_raid.c b/libblkid/src/superblocks/lsi_raid.c new file mode 100644 index 00000000..5217a009 --- /dev/null +++ b/libblkid/src/superblocks/lsi_raid.c @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2008 Karel Zak + * + * Inspired by libvolume_id by + * Kay Sievers + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ + +#include +#include +#include +#include +#include + +#include "superblocks.h" + +struct lsi_metadata { + uint8_t sig[6]; +}; + + +#define LSI_SIGNATURE "$XIDE$" + +static int probe_lsiraid(blkid_probe pr, const struct blkid_idmag *mag) +{ + uint64_t off; + struct lsi_metadata *lsi; + + if (pr->size < 0x10000) + return -1; + if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) + return -1; + + off = ((pr->size / 0x200) - 1) * 0x200; + lsi = (struct lsi_metadata *) + blkid_probe_get_buffer(pr, + off, + sizeof(struct lsi_metadata)); + if (!lsi) + return -1; + + if (memcmp(lsi->sig, LSI_SIGNATURE, sizeof(LSI_SIGNATURE)-1) != 0) + return -1; + if (blkid_probe_set_magic(pr, off, sizeof(lsi->sig), + (unsigned char *) lsi->sig)) + return -1; + return 0; +} + +const struct blkid_idinfo lsiraid_idinfo = { + .name = "lsi_mega_raid_member", + .usage = BLKID_USAGE_RAID, + .probefunc = probe_lsiraid, + .magics = BLKID_NONE_MAGIC +}; + + diff --git a/libblkid/src/superblocks/luks.c b/libblkid/src/superblocks/luks.c new file mode 100644 index 00000000..f716e31c --- /dev/null +++ b/libblkid/src/superblocks/luks.c @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2008 Karel Zak + * + * Inspired by libvolume_id by + * Kay Sievers + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include +#include +#include + +#include "superblocks.h" + +#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_MAGIC_L 6 +#define UUID_STRING_L 40 + +struct luks_phdr { + uint8_t magic[LUKS_MAGIC_L]; + uint16_t version; + uint8_t cipherName[LUKS_CIPHERNAME_L]; + uint8_t cipherMode[LUKS_CIPHERMODE_L]; + uint8_t hashSpec[LUKS_HASHSPEC_L]; + uint32_t payloadOffset; + uint32_t keyBytes; + uint8_t mkDigest[LUKS_DIGESTSIZE]; + uint8_t mkDigestSalt[LUKS_SALTSIZE]; + uint32_t mkDigestIterations; + uint8_t uuid[UUID_STRING_L]; +} __attribute__((packed)); + +static int probe_luks(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct luks_phdr *header; + + header = blkid_probe_get_sb(pr, mag, struct luks_phdr); + if (header == NULL) + return -1; + + blkid_probe_strncpy_uuid(pr, (unsigned char *) header->uuid, + sizeof(header->uuid)); + blkid_probe_sprintf_version(pr, "%u", be16_to_cpu(header->version)); + return 0; +} + +const struct blkid_idinfo luks_idinfo = +{ + .name = "crypto_LUKS", + .usage = BLKID_USAGE_CRYPTO, + .probefunc = probe_luks, + .magics = + { + { .magic = "LUKS\xba\xbe", .len = 6 }, + { NULL } + } +}; diff --git a/libblkid/src/superblocks/lvm.c b/libblkid/src/superblocks/lvm.c new file mode 100644 index 00000000..3a9807c8 --- /dev/null +++ b/libblkid/src/superblocks/lvm.c @@ -0,0 +1,182 @@ +/* + * Copyright (C) 1999 by Andries Brouwer + * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o + * Copyright (C) 2001 by Andreas Dilger + * Copyright (C) 2004 Kay Sievers + * Copyright (C) 2008 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include + +#include "superblocks.h" + +#define LVM1_ID_LEN 128 +#define LVM2_ID_LEN 32 + +struct lvm2_pv_label_header { + /* label_header */ + uint8_t id[8]; /* LABELONE */ + uint64_t sector_xl; /* Sector number of this label */ + uint32_t crc_xl; /* From next field to end of sector */ + uint32_t offset_xl; /* Offset from start of struct to contents */ + uint8_t type[8]; /* LVM2 001 */ + /* pv_header */ + uint8_t pv_uuid[LVM2_ID_LEN]; +} __attribute__ ((packed)); + +struct lvm1_pv_label_header { + uint8_t id[2]; /* HM */ + uint16_t version; /* version 1 or 2 */ + uint32_t _notused[10]; /* lvm1 internals */ + uint8_t pv_uuid[LVM1_ID_LEN]; +} __attribute__ ((packed)); + +#define LVM2_LABEL_SIZE 512 +static unsigned int lvm2_calc_crc(const void *buf, unsigned int size) +{ + static const unsigned int crctab[] = { + 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, + 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, + 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, + 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c + }; + unsigned int i, crc = 0xf597a6cf; + const uint8_t *data = (const uint8_t *) buf; + + for (i = 0; i < size; i++) { + crc ^= *data++; + crc = (crc >> 4) ^ crctab[crc & 0xf]; + crc = (crc >> 4) ^ crctab[crc & 0xf]; + } + return crc; +} + +/* Length of real UUID is always LVM2_ID_LEN */ +static void format_lvm_uuid(char *dst_uuid, char *src_uuid) +{ + unsigned int i, b; + + for (i = 0, b = 1; i < LVM2_ID_LEN; i++, b <<= 1) { + if (b & 0x4444440) + *dst_uuid++ = '-'; + *dst_uuid++ = *src_uuid++; + } + *dst_uuid = '\0'; +} + +static int probe_lvm2(blkid_probe pr, const struct blkid_idmag *mag) +{ + int sector = mag->kboff << 1; + struct lvm2_pv_label_header *label; + char uuid[LVM2_ID_LEN + 7]; + unsigned char *buf; + + buf = blkid_probe_get_buffer(pr, + mag->kboff << 10, + 512 + sizeof(struct lvm2_pv_label_header)); + if (!buf) + return -1; + + /* buf is at 0k or 1k offset; find label inside */ + if (memcmp(buf, "LABELONE", 8) == 0) { + label = (struct lvm2_pv_label_header *) buf; + } else if (memcmp(buf + 512, "LABELONE", 8) == 0) { + label = (struct lvm2_pv_label_header *)(buf + 512); + sector++; + } else { + return 1; + } + + if (le64_to_cpu(label->sector_xl) != (unsigned) sector) + return 1; + + if (lvm2_calc_crc(&label->offset_xl, LVM2_LABEL_SIZE - + ((char *) &label->offset_xl - (char *) label)) != + le32_to_cpu(label->crc_xl)) { + DBG(DEBUG_PROBE, + printf("LVM2: label checksum incorrect at sector %d\n", + sector)); + return 1; + } + + format_lvm_uuid(uuid, (char *) label->pv_uuid); + blkid_probe_sprintf_uuid(pr, label->pv_uuid, sizeof(label->pv_uuid), + "%s", uuid); + + /* the mag->magic is the same string as label->type, + * but zero terminated */ + blkid_probe_set_version(pr, mag->magic); + + /* LVM (pvcreate) wipes begin of the device -- let's remember this + * to resolve conflicts bettween LVM and partition tables, ... + */ + blkid_probe_set_wiper(pr, 0, 8 * 1024); + + return 0; +} + +static int probe_lvm1(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct lvm1_pv_label_header *label; + char uuid[LVM2_ID_LEN + 7]; + unsigned int version; + + label = blkid_probe_get_sb(pr, mag, struct lvm1_pv_label_header); + if (!label) + return -1; + + version = le16_to_cpu(label->version); + if (version != 1 && version != 2) + return 1; + + format_lvm_uuid(uuid, (char *) label->pv_uuid); + blkid_probe_sprintf_uuid(pr, label->pv_uuid, sizeof(label->pv_uuid), + "%s", uuid); + + return 0; +} + +/* NOTE: the original libblkid uses "lvm2pv" as a name */ +const struct blkid_idinfo lvm2_idinfo = +{ + .name = "LVM2_member", + .usage = BLKID_USAGE_RAID, + .probefunc = probe_lvm2, + .magics = + { + { .magic = "LVM2 001", .len = 8, .sboff = 0x218 }, + { .magic = "LVM2 001", .len = 8, .sboff = 0x018 }, + { .magic = "LVM2 001", .len = 8, .kboff = 1, .sboff = 0x018 }, + { .magic = "LVM2 001", .len = 8, .kboff = 1, .sboff = 0x218 }, + { NULL } + } +}; + +const struct blkid_idinfo lvm1_idinfo = +{ + .name = "LVM1_member", + .usage = BLKID_USAGE_RAID, + .probefunc = probe_lvm1, + .magics = + { + { .magic = "HM", .len = 2 }, + { NULL } + } +}; + +const struct blkid_idinfo snapcow_idinfo = +{ + .name = "DM_snapshot_cow", + .usage = BLKID_USAGE_OTHER, + .magics = + { + { .magic = "SnAp", .len = 4 }, + { NULL } + } +}; diff --git a/libblkid/src/superblocks/minix.c b/libblkid/src/superblocks/minix.c new file mode 100644 index 00000000..3290c275 --- /dev/null +++ b/libblkid/src/superblocks/minix.c @@ -0,0 +1,125 @@ +/* + * Copyright (C) 1999 by Andries Brouwer + * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o + * Copyright (C) 2001 by Andreas Dilger + * Copyright (C) 2004 Kay Sievers + * Copyright (C) 2008 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ + +#include +#include "superblocks.h" + +struct minix_super_block { + uint16_t s_ninodes; + uint16_t s_nzones; + uint16_t s_imap_blocks; + uint16_t s_zmap_blocks; + uint16_t s_firstdatazone; + uint16_t s_log_zone_size; + uint32_t s_max_size; + uint16_t s_magic; + uint16_t s_state; + uint32_t s_zones; +}; + +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; +}; + +#define MINIX_BLOCK_SIZE_BITS 10 +#define MINIX_BLOCK_SIZE (1 << MINIX_BLOCK_SIZE_BITS) + +static int probe_minix(blkid_probe pr, const struct blkid_idmag *mag) +{ + unsigned char *ext; + int version; + + /* for more details see magic strings below */ + switch(mag->magic[1]) { + case '\023': + version = 1; + break; + case '\044': + version = 2; + break; + case '\115': + version = 3; + break; + default: + return -1; + break; + } + + if (version <= 2) { + struct minix_super_block *sb; + uint32_t zones; + + sb = blkid_probe_get_sb(pr, mag, struct minix_super_block); + if (!sb || sb->s_imap_blocks == 0 || sb->s_zmap_blocks == 0) + return -1; + + zones = version == 2 ? sb->s_zones : sb->s_nzones; + + /* sanity checks to be sure that the FS is really minix */ + if (sb->s_imap_blocks * MINIX_BLOCK_SIZE * 8 < sb->s_ninodes + 1) + return -1; + if (sb->s_zmap_blocks * MINIX_BLOCK_SIZE * 8 < zones - sb->s_firstdatazone + 1) + return -1; + + } else if (version == 3) { + struct minix3_super_block *sb; + + sb = blkid_probe_get_sb(pr, mag, struct minix3_super_block); + if (!sb || sb->s_imap_blocks == 0 || sb->s_zmap_blocks == 0) + return -1; + + } + + /* unfortunately, some parts of ext3 is sometimes possible to + * interpreted as minix superblock. So check for extN magic + * string. (For extN magic string and offsets see ext.c.) + */ + ext = blkid_probe_get_buffer(pr, 0x400 + 0x38, 2); + if (ext && memcmp(ext, "\123\357", 2) == 0) + return -1; + + blkid_probe_sprintf_version(pr, "%d", version); + return 0; +} + +const struct blkid_idinfo minix_idinfo = +{ + .name = "minix", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_minix, + .magics = + { + /* version 1 */ + { .magic = "\177\023", .len = 2, .kboff = 1, .sboff = 0x10 }, + { .magic = "\217\023", .len = 2, .kboff = 1, .sboff = 0x10 }, + + /* version 2 */ + { .magic = "\150\044", .len = 2, .kboff = 1, .sboff = 0x10 }, + { .magic = "\170\044", .len = 2, .kboff = 1, .sboff = 0x10 }, + + /* version 3 */ + { .magic = "\132\115", .len = 2, .kboff = 1, .sboff = 0x18 }, + { NULL } + } +}; + diff --git a/libblkid/src/superblocks/netware.c b/libblkid/src/superblocks/netware.c new file mode 100644 index 00000000..7ef21625 --- /dev/null +++ b/libblkid/src/superblocks/netware.c @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2008 Karel Zak + * + * Inspired by libvolume_id by + * Kay Sievers + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include + +#include "superblocks.h" + +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)]; +} __attribute__((__packed__)); + +static int probe_netware(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct netware_super_block *nw; + + nw = blkid_probe_get_sb(pr, mag, struct netware_super_block); + if (!nw) + return -1; + + blkid_probe_set_uuid(pr, nw->SBH_PoolID); + + blkid_probe_sprintf_version(pr, "%u.%02u", + le16_to_cpu(nw->SBH_VersionMediaMajor), + le16_to_cpu(nw->SBH_VersionMediaMinor)); + + return 0; +} + +const struct blkid_idinfo netware_idinfo = +{ + .name = "nss", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_netware, + .magics = + { + { .magic = "SPB5", .len = 4, .kboff = 4 }, + { NULL } + } +}; + + diff --git a/libblkid/src/superblocks/nilfs.c b/libblkid/src/superblocks/nilfs.c new file mode 100644 index 00000000..1f8f3a69 --- /dev/null +++ b/libblkid/src/superblocks/nilfs.c @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2010 by Jiro SEKIBA + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License + */ +#include +#include + +#include "superblocks.h" +#include "crc32.h" + +struct nilfs_super_block { + uint32_t s_rev_level; + uint16_t s_minor_rev_level; + uint16_t s_magic; + + uint16_t s_bytes; + + uint16_t s_flags; + uint32_t s_crc_seed; + uint32_t s_sum; + + uint32_t s_log_block_size; + + uint64_t s_nsegments; + uint64_t s_dev_size; + uint64_t s_first_data_block; + uint32_t s_blocks_per_segment; + uint32_t s_r_segments_percentage; + + uint64_t s_last_cno; + uint64_t s_last_pseg; + uint64_t s_last_seq; + uint64_t s_free_blocks_count; + + uint64_t s_ctime; + + uint64_t s_mtime; + uint64_t s_wtime; + uint16_t s_mnt_count; + uint16_t s_max_mnt_count; + uint16_t s_state; + uint16_t s_errors; + uint64_t s_lastcheck; + + uint32_t s_checkinterval; + uint32_t s_creator_os; + uint16_t s_def_resuid; + uint16_t s_def_resgid; + uint32_t s_first_ino; + + uint16_t s_inode_size; + uint16_t s_dat_entry_size; + uint16_t s_checkpoint_size; + uint16_t s_segment_usage_size; + + uint8_t s_uuid[16]; + char s_volume_name[80]; + + uint32_t s_c_interval; + uint32_t s_c_block_max; + uint32_t s_reserved[192]; +}; + +/* nilfs2 magic string */ +#define NILFS_SB_MAGIC "\x34\x34" +/* nilfs2 super block offset */ +#define NILFS_SB_OFF 0x400 +/* nilfs2 super block offset in kB */ +#define NILFS_SB_KBOFF (NILFS_SB_OFF >> 10) +/* nilfs2 magic string offset within super block */ +#define NILFS_MAG_OFF 6 + +static int probe_nilfs2(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct nilfs_super_block *sb; + static unsigned char sum[4]; + const int sumoff = offsetof(struct nilfs_super_block, s_sum); + size_t bytes; + uint32_t crc; + + sb = blkid_probe_get_sb(pr, mag, struct nilfs_super_block); + if (!sb) + return -1; + + bytes = le16_to_cpu(sb->s_bytes); + crc = crc32(le32_to_cpu(sb->s_crc_seed), (unsigned char *)sb, sumoff); + crc = crc32(crc, sum, 4); + crc = crc32(crc, (unsigned char *)sb + sumoff + 4, bytes - sumoff - 4); + + if (crc != le32_to_cpu(sb->s_sum)) + return -1; + + if (strlen(sb->s_volume_name)) + blkid_probe_set_label(pr, (unsigned char *) sb->s_volume_name, + sizeof(sb->s_volume_name)); + + blkid_probe_set_uuid(pr, sb->s_uuid); + blkid_probe_sprintf_version(pr, "%u", le32_to_cpu(sb->s_rev_level)); + + return 0; +} + +const struct blkid_idinfo nilfs2_idinfo = +{ + .name = "nilfs2", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_nilfs2, + .magics = + { + { + .magic = NILFS_SB_MAGIC, + .len = 2, + .kboff = NILFS_SB_KBOFF, + .sboff = NILFS_MAG_OFF + }, + { NULL } + } +}; diff --git a/libblkid/src/superblocks/ntfs.c b/libblkid/src/superblocks/ntfs.c new file mode 100644 index 00000000..98f3fb2f --- /dev/null +++ b/libblkid/src/superblocks/ntfs.c @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2004 Kay Sievers + * Copyright (C) 2008 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include + +#include "superblocks.h" + +struct ntfs_super_block { + uint8_t jump[3]; + uint8_t oem_id[8]; + uint8_t bios_parameter_block[25]; + 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]; + uint64_t volume_serial; + uint16_t checksum; +} __attribute__((packed)); + +struct master_file_table_record { + uint32_t magic; + 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; +} __attribute__((__packed__)); + +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; +} __attribute__((__packed__)); + +#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 + +static int probe_ntfs(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct ntfs_super_block *ns; + struct master_file_table_record *mft; + struct file_attribute *attr; + int bytes_per_sector, sectors_per_cluster; + int mft_record_size, attr_off, attr_len; + unsigned int attr_type, val_len; + int val_off; + uint64_t nr_clusters; + blkid_loff_t off; + unsigned char *buf_mft, *val; + + ns = blkid_probe_get_sb(pr, mag, struct ntfs_super_block); + if (!ns) + return -1; + + bytes_per_sector = ns->bios_parameter_block[0] + + (ns->bios_parameter_block[1] << 8); + sectors_per_cluster = ns->bios_parameter_block[2]; + + if ((bytes_per_sector < 512) || (sectors_per_cluster == 0)) + return 1; + + if (ns->cluster_per_mft_record < 0) + mft_record_size = 1 << (0 - ns->cluster_per_mft_record); + else + mft_record_size = ns->cluster_per_mft_record * + sectors_per_cluster * bytes_per_sector; + nr_clusters = le64_to_cpu(ns->number_of_sectors) / sectors_per_cluster; + + if ((le64_to_cpu(ns->mft_cluster_location) > nr_clusters) || + (le64_to_cpu(ns->mft_mirror_cluster_location) > nr_clusters)) + return 1; + + off = le64_to_cpu(ns->mft_mirror_cluster_location) * + bytes_per_sector * sectors_per_cluster; + + buf_mft = blkid_probe_get_buffer(pr, off, mft_record_size); + if (!buf_mft) + return 1; + + if (memcmp(buf_mft, "FILE", 4)) + return 1; + + off = le64_to_cpu(ns->mft_cluster_location) * bytes_per_sector * + sectors_per_cluster; + + buf_mft = blkid_probe_get_buffer(pr, off, mft_record_size); + if (!buf_mft) + return 1; + + if (memcmp(buf_mft, "FILE", 4)) + return 1; + + off += MFT_RECORD_VOLUME * mft_record_size; + + buf_mft = blkid_probe_get_buffer(pr, off, mft_record_size); + if (!buf_mft) + return 1; + + if (memcmp(buf_mft, "FILE", 4)) + return 1; + + mft = (struct master_file_table_record *) buf_mft; + + attr_off = le16_to_cpu(mft->attrs_offset); + + while (1) { + attr = (struct file_attribute *) (buf_mft + attr_off); + attr_len = le32_to_cpu(attr->len); + attr_type = le32_to_cpu(attr->type); + val_off = le16_to_cpu(attr->value_offset); + val_len = le32_to_cpu(attr->value_len); + + attr_off += attr_len; + + if ((attr_off > mft_record_size) || + (attr_len == 0)) + break; + + if (attr_type == MFT_RECORD_ATTR_END) + break; + + if (attr_type == MFT_RECORD_ATTR_VOLUME_NAME) { + val = ((uint8_t *) attr) + val_off; + blkid_probe_set_utf8label(pr, val, val_len, BLKID_ENC_UTF16LE); + } + } + + blkid_probe_sprintf_uuid(pr, + (unsigned char *) &ns->volume_serial, + sizeof(ns->volume_serial), + "%016" PRIX64, le64_to_cpu(ns->volume_serial)); + return 0; +} + + +const struct blkid_idinfo ntfs_idinfo = +{ + .name = "ntfs", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_ntfs, + .magics = + { + { .magic = "NTFS ", .len = 8, .sboff = 3 }, + { NULL } + } +}; + diff --git a/libblkid/src/superblocks/nvidia_raid.c b/libblkid/src/superblocks/nvidia_raid.c new file mode 100644 index 00000000..c3db949a --- /dev/null +++ b/libblkid/src/superblocks/nvidia_raid.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2008 Karel Zak + * Copyright (C) 2005 Kay Sievers + * + * Inspired by libvolume_id by + * Kay Sievers + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include + +#include "superblocks.h" + +struct nv_metadata { + uint8_t vendor[8]; + uint32_t size; + uint32_t chksum; + uint16_t version; +} __attribute__((packed)); + +#define NVIDIA_SIGNATURE "NVIDIA" + +static int probe_nvraid(blkid_probe pr, const struct blkid_idmag *mag) +{ + uint64_t off; + struct nv_metadata *nv; + + if (pr->size < 0x10000) + return -1; + if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) + return -1; + + off = ((pr->size / 0x200) - 2) * 0x200; + nv = (struct nv_metadata *) + blkid_probe_get_buffer(pr, + off, + sizeof(struct nv_metadata)); + if (!nv) + return -1; + + if (memcmp(nv->vendor, NVIDIA_SIGNATURE, sizeof(NVIDIA_SIGNATURE)-1) != 0) + return -1; + if (blkid_probe_sprintf_version(pr, "%u", le16_to_cpu(nv->version)) != 0) + return -1; + if (blkid_probe_set_magic(pr, off, sizeof(nv->vendor), + (unsigned char *) nv->vendor)) + return -1; + return 0; +} + +const struct blkid_idinfo nvraid_idinfo = { + .name = "nvidia_raid_member", + .usage = BLKID_USAGE_RAID, + .probefunc = probe_nvraid, + .magics = BLKID_NONE_MAGIC +}; + + diff --git a/libblkid/src/superblocks/ocfs.c b/libblkid/src/superblocks/ocfs.c new file mode 100644 index 00000000..9dbf41b1 --- /dev/null +++ b/libblkid/src/superblocks/ocfs.c @@ -0,0 +1,213 @@ +/* + * Copyright (C) 1999, 2001 by Andries Brouwer + * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o + * Copyright (C) 2008 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include + +#include "superblocks.h" + +struct ocfs_volume_header { + unsigned char minor_version[4]; + unsigned char major_version[4]; + unsigned char signature[128]; + char mount[128]; + unsigned char mount_len[2]; +} __attribute__((packed)); + +struct ocfs_volume_label { + unsigned char disk_lock[48]; + char label[64]; + unsigned char label_len[2]; + unsigned char vol_id[16]; + unsigned char vol_id_len[2]; +} __attribute__((packed)); + +#define ocfsmajor(o) ( (uint32_t) o.major_version[0] \ + + (((uint32_t) o.major_version[1]) << 8) \ + + (((uint32_t) o.major_version[2]) << 16) \ + + (((uint32_t) o.major_version[3]) << 24)) + +#define ocfsminor(o) ( (uint32_t) o.minor_version[0] \ + + (((uint32_t) o.minor_version[1]) << 8) \ + + (((uint32_t) o.minor_version[2]) << 16) \ + + (((uint32_t) o.minor_version[3]) << 24)) + +#define ocfslabellen(o) ((uint32_t)o.label_len[0] + (((uint32_t) o.label_len[1]) << 8)) +#define ocfsmountlen(o) ((uint32_t)o.mount_len[0] + (((uint32_t) o.mount_len[1]) << 8)) + +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]; +} __attribute__((packed)); + +struct oracle_asm_disk_label { + char dummy[32]; + char dl_tag[8]; + char dl_id[24]; +} __attribute__((packed)); + +static int probe_ocfs(blkid_probe pr, const struct blkid_idmag *mag) +{ + unsigned char *buf; + struct ocfs_volume_header ovh; + struct ocfs_volume_label ovl; + uint32_t maj, min; + + /* header */ + buf = blkid_probe_get_buffer(pr, mag->kboff << 10, + sizeof(struct ocfs_volume_header)); + if (!buf) + return -1; + memcpy(&ovh, buf, sizeof(ovh)); + + /* label */ + buf = blkid_probe_get_buffer(pr, (mag->kboff << 10) + 512, + sizeof(struct ocfs_volume_label)); + if (!buf) + return -1; + memcpy(&ovl, buf, sizeof(ovl)); + + maj = ocfsmajor(ovh); + min = ocfsminor(ovh); + + if (maj == 1) + blkid_probe_set_value(pr, "SEC_TYPE", + (unsigned char *) "ocfs1", sizeof("ocfs1")); + else if (maj >= 9) + blkid_probe_set_value(pr, "SEC_TYPE", + (unsigned char *) "ntocfs", sizeof("ntocfs")); + + blkid_probe_set_label(pr, (unsigned char *) ovl.label, + ocfslabellen(ovl)); + blkid_probe_set_value(pr, "MOUNT", (unsigned char *) ovh.mount, + ocfsmountlen(ovh)); + blkid_probe_set_uuid(pr, ovl.vol_id); + blkid_probe_sprintf_version(pr, "%u.%u", maj, min); + return 0; +} + +static int probe_ocfs2(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct ocfs2_super_block *osb; + + osb = blkid_probe_get_sb(pr, mag, struct ocfs2_super_block); + if (!osb) + return -1; + + blkid_probe_set_label(pr, (unsigned char *) osb->s_label, sizeof(osb->s_label)); + blkid_probe_set_uuid(pr, osb->s_uuid); + + blkid_probe_sprintf_version(pr, "%u.%u", + le16_to_cpu(osb->s_major_rev_level), + le16_to_cpu(osb->s_minor_rev_level)); + + return 0; +} + +static int probe_oracleasm(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct oracle_asm_disk_label *dl; + + dl = blkid_probe_get_sb(pr, mag, struct oracle_asm_disk_label); + if (!dl) + return -1; + + blkid_probe_set_label(pr, (unsigned char *) dl->dl_id, sizeof(dl->dl_id)); + return 0; +} + + +const struct blkid_idinfo ocfs_idinfo = +{ + .name = "ocfs", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_ocfs, + .minsz = 108 * 1024 * 1024, + .magics = + { + { .magic = "OracleCFS", .len = 9, .kboff = 8 }, + { NULL } + } +}; + +const struct blkid_idinfo ocfs2_idinfo = +{ + .name = "ocfs2", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_ocfs2, + .minsz = 108 * 1024 * 1024, + .magics = + { + { .magic = "OCFSV2", .len = 6, .kboff = 1 }, + { .magic = "OCFSV2", .len = 6, .kboff = 2 }, + { .magic = "OCFSV2", .len = 6, .kboff = 4 }, + { .magic = "OCFSV2", .len = 6, .kboff = 8 }, + { NULL } + } +}; + +/* Oracle ASM (Automatic Storage Management) */ +const struct blkid_idinfo oracleasm_idinfo = +{ + .name = "oracleasm", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_oracleasm, + .magics = + { + { .magic = "ORCLDISK", .len = 8, .sboff = 32 }, + { NULL } + } +}; + diff --git a/libblkid/src/superblocks/promise_raid.c b/libblkid/src/superblocks/promise_raid.c new file mode 100644 index 00000000..0e91d3c2 --- /dev/null +++ b/libblkid/src/superblocks/promise_raid.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2008 Karel Zak + * + * Inspired by libvolume_id by + * Kay Sievers + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include +#include +#include + +#include "superblocks.h" + +struct promise_metadata { + uint8_t sig[24]; +}; + +#define PDC_CONFIG_OFF 0x1200 +#define PDC_SIGNATURE "Promise Technology, Inc." + +static int probe_pdcraid(blkid_probe pr, const struct blkid_idmag *mag) +{ + unsigned int i; + static unsigned int sectors[] = { + 63, 255, 256, 16, 399, 0 + }; + + if (pr->size < 0x40000) + return -1; + if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) + return -1; + + for (i = 0; sectors[i] != 0; i++) { + uint64_t off; + struct promise_metadata *pdc; + + off = ((pr->size / 0x200) - sectors[i]) * 0x200; + pdc = (struct promise_metadata *) + blkid_probe_get_buffer(pr, + off, + sizeof(struct promise_metadata)); + if (!pdc) + return -1; + + if (memcmp(pdc->sig, PDC_SIGNATURE, + sizeof(PDC_SIGNATURE) - 1) == 0) { + + if (blkid_probe_set_magic(pr, off, sizeof(pdc->sig), + (unsigned char *) pdc->sig)) + return -1; + return 0; + } + } + return -1; +} + +const struct blkid_idinfo pdcraid_idinfo = { + .name = "promise_fasttrack_raid_member", + .usage = BLKID_USAGE_RAID, + .probefunc = probe_pdcraid, + .magics = BLKID_NONE_MAGIC +}; + + diff --git a/libblkid/src/superblocks/reiserfs.c b/libblkid/src/superblocks/reiserfs.c new file mode 100644 index 00000000..921f5237 --- /dev/null +++ b/libblkid/src/superblocks/reiserfs.c @@ -0,0 +1,128 @@ +/* + * Copyright (C) 1999, 2001 by Andries Brouwer + * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o + * Copyright (C) 2008 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include + +#include "superblocks.h" + +struct reiserfs_super_block { + uint32_t rs_blocks_count; + uint32_t rs_free_blocks; + uint32_t rs_root_block; + uint32_t rs_journal_block; + uint32_t rs_journal_dev; + uint32_t rs_orig_journal_size; + uint32_t rs_dummy2[5]; + uint16_t rs_blocksize; + uint16_t rs_dummy3[3]; + unsigned char rs_magic[12]; + uint32_t rs_dummy4[5]; + unsigned char rs_uuid[16]; + char rs_label[16]; +} __attribute__((packed)); + +struct reiser4_super_block { + unsigned char rs4_magic[16]; + uint16_t rs4_dummy[2]; + unsigned char rs4_uuid[16]; + unsigned char rs4_label[16]; + uint64_t rs4_dummy2; +} __attribute__((packed)); + +static int probe_reiser(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct reiserfs_super_block *rs; + unsigned int blocksize; + + rs = blkid_probe_get_sb(pr, mag, struct reiserfs_super_block); + if (!rs) + return -1; + + blocksize = le16_to_cpu(rs->rs_blocksize); + + /* The blocksize must be at least 1k */ + if ((blocksize >> 10) == 0) + return -BLKID_ERR_PARAM; + + /* If the superblock is inside the journal, we have the wrong one */ + if (mag->kboff / (blocksize >> 10) > le32_to_cpu(rs->rs_journal_block)) + return -BLKID_ERR_BIG; + + /* LABEL/UUID are only valid for later versions of Reiserfs v3.6. */ + if (mag->magic[6] == '2' || mag->magic[6] == '3') { + if (*rs->rs_label) + blkid_probe_set_label(pr, + (unsigned char *) rs->rs_label, + sizeof(rs->rs_label)); + blkid_probe_set_uuid(pr, rs->rs_uuid); + } + + if (mag->magic[6] == '3') + blkid_probe_set_version(pr, "JR"); + else if (mag->magic[6] == '2') + blkid_probe_set_version(pr, "3.6"); + else + blkid_probe_set_version(pr, "3.5"); + + return 0; +} + +static int probe_reiser4(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct reiser4_super_block *rs4; + + rs4 = blkid_probe_get_sb(pr, mag, struct reiser4_super_block); + if (!rs4) + return -1; + + if (*rs4->rs4_label) + blkid_probe_set_label(pr, rs4->rs4_label, sizeof(rs4->rs4_label)); + blkid_probe_set_uuid(pr, rs4->rs4_uuid); + blkid_probe_set_version(pr, "4"); + + return 0; +} + + +const struct blkid_idinfo reiser_idinfo = +{ + .name = "reiserfs", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_reiser, + .minsz = 4096 * 512, /* not sure, this is minimal size of journal */ + .magics = + { + { .magic = "ReIsErFs", .len = 8, .kboff = 8, .sboff = 0x34 }, + { .magic = "ReIsEr2Fs", .len = 9, .kboff = 64, .sboff = 0x34 }, + { .magic = "ReIsEr3Fs", .len = 9, .kboff = 64, .sboff = 0x34 }, + { .magic = "ReIsErFs", .len = 8, .kboff = 64, .sboff = 0x34 }, + { .magic = "ReIsErFs", .len = 8, .kboff = 8, .sboff = 20 }, + { NULL } + } +}; + +const struct blkid_idinfo reiser4_idinfo = +{ + .name = "reiser4", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_reiser4, + .minsz = 4096 * 512, /* not sure, this is minimal size of journal */ + .magics = + { + { .magic = "ReIsEr4", .len = 7, .kboff = 64 }, + { NULL } + } +}; + + + + diff --git a/libblkid/src/superblocks/romfs.c b/libblkid/src/superblocks/romfs.c new file mode 100644 index 00000000..91ef996f --- /dev/null +++ b/libblkid/src/superblocks/romfs.c @@ -0,0 +1,51 @@ +/* + * Copyright (C) 1999, 2001 by Andries Brouwer + * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o + * Copyright (C) 2008 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "superblocks.h" + +struct romfs_super_block { + unsigned char ros_magic[8]; + uint32_t ros_dummy1[2]; + unsigned char ros_volume[16]; +} __attribute__((packed)); + +static int probe_romfs(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct romfs_super_block *ros; + + ros = blkid_probe_get_sb(pr, mag, struct romfs_super_block); + if (!ros) + return -1; + + if (strlen((char *) ros->ros_volume)) + blkid_probe_set_label(pr, ros->ros_volume, + sizeof(ros->ros_volume)); + return 0; +} + +const struct blkid_idinfo romfs_idinfo = +{ + .name = "romfs", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_romfs, + .magics = + { + { .magic = "-rom1fs-", .len = 8 }, + { NULL } + } +}; + diff --git a/libblkid/src/superblocks/silicon_raid.c b/libblkid/src/superblocks/silicon_raid.c new file mode 100644 index 00000000..b72b7276 --- /dev/null +++ b/libblkid/src/superblocks/silicon_raid.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2008 Karel Zak + * Copyright (C) 2005 Kay Sievers + * + * Inspired by libvolume_id by + * Kay Sievers + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "superblocks.h" + +struct silicon_metadata { + 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; +} __attribute__((packed)); + +#define SILICON_MAGIC 0x2F000000 + + +static int probe_silraid(blkid_probe pr, const struct blkid_idmag *mag) +{ + uint64_t off; + struct silicon_metadata *sil; + + if (pr->size < 0x10000) + return -1; + if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) + return -1; + + off = ((pr->size / 0x200) - 1) * 0x200; + + sil = (struct silicon_metadata *) + blkid_probe_get_buffer(pr, off, + sizeof(struct silicon_metadata)); + if (!sil) + return -1; + + if (le32_to_cpu(sil->magic) != SILICON_MAGIC) + return -1; + + if (blkid_probe_sprintf_version(pr, "%u.%u", + le16_to_cpu(sil->major_ver), + le16_to_cpu(sil->minor_ver)) != 0) + return -1; + if (blkid_probe_set_magic(pr, + off + offsetof(struct silicon_metadata, magic), + sizeof(sil->magic), + (unsigned char *) &sil->magic)) + return -1; + return 0; +} + +const struct blkid_idinfo silraid_idinfo = { + .name = "silicon_medley_raid_member", + .usage = BLKID_USAGE_RAID, + .probefunc = probe_silraid, + .magics = BLKID_NONE_MAGIC +}; + + diff --git a/libblkid/src/superblocks/squashfs.c b/libblkid/src/superblocks/squashfs.c new file mode 100644 index 00000000..45f10291 --- /dev/null +++ b/libblkid/src/superblocks/squashfs.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2008 Karel Zak + * + * Inspired by libvolume_id by + * Kay Sievers + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include + +#include "bitops.h" /* swab16() */ +#include "superblocks.h" + +struct sqsh_super_block { + 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; +} __attribute__((packed)); + +static int probe_squashfs(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct sqsh_super_block *sq; + + sq = blkid_probe_get_sb(pr, mag, struct sqsh_super_block); + if (!sq) + return -1; + + if (strcmp(mag->magic, "sqsh") == 0 || + strcmp(mag->magic, "qshs") == 0) + blkid_probe_sprintf_version(pr, "%u.%u", + sq->s_major, + sq->s_minor); + else + blkid_probe_sprintf_version(pr, "%u.%u", + swab16(sq->s_major), + swab16(sq->s_minor)); + return 0; +} + +const struct blkid_idinfo squashfs_idinfo = +{ + .name = "squashfs", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_squashfs, + .magics = + { + { .magic = "sqsh", .len = 4 }, + { .magic = "hsqs", .len = 4 }, /* swap */ + + /* LZMA version */ + { .magic = "qshs", .len = 4 }, + { .magic = "shsq", .len = 4 }, /* swap */ + { NULL } + } +}; + + diff --git a/libblkid/src/superblocks/superblocks.c b/libblkid/src/superblocks/superblocks.c new file mode 100644 index 00000000..56a45433 --- /dev/null +++ b/libblkid/src/superblocks/superblocks.c @@ -0,0 +1,754 @@ +/* + * superblocks.c - reads information from filesystem and raid superblocks + * + * Copyright (C) 2008-2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "superblocks.h" + +/** + * SECTION:superblocks + * @title: Superblocks probing + * @short_description: filesystems and raids superblocks probing. + * + * The library API has been originaly designed for superblocks probing only. + * This is reason why some *deprecated* superblock specific functions don't use + * '_superblocks_' namespace in the function name. Please, don't use these + * functions in new code. + * + * The 'superblocks' probers support NAME=value (tags) interface only. The + * superblocks probing is enabled by default (and controled by + * blkid_probe_enable_superblocks()). + * + * Currently supported tags: + * + * @TYPE: filesystem type + * + * @SEC_TYPE: secondary filesystem type + * + * @LABEL: filesystem label + * + * @LABEL_RAW: raw label from FS superblock + * + * @UUID: filesystem UUID (lower case) + * + * @UUID_SUB: subvolume uuid (e.g. btrfs) + * + * @UUID_RAW: raw UUID from FS superblock + * + * @EXT_JOURNAL: external journal UUID + * + * @USAGE: usage string: "raid", "filesystem", ... + * + * @VERSION: filesystem version + * + * @MOUNT: cluster mount name (?) -- ocfs only + * + * @SBMAGIC: super block magic string + * + * @SBMAGIC_OFFSET: offset of SBMAGIC + * + * @FSSIZE: size of filessystem [not-implemented yet] + */ + +static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn); +static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn); + +static int blkid_probe_set_usage(blkid_probe pr, int usage); + + +/* + * Superblocks chains probing functions + */ +static const struct blkid_idinfo *idinfos[] = +{ + /* RAIDs */ + &linuxraid_idinfo, + &ddfraid_idinfo, + &iswraid_idinfo, + &lsiraid_idinfo, + &viaraid_idinfo, + &silraid_idinfo, + &nvraid_idinfo, + &pdcraid_idinfo, + &highpoint45x_idinfo, + &highpoint37x_idinfo, + &adraid_idinfo, + &jmraid_idinfo, + + &drbd_idinfo, + &lvm2_idinfo, + &lvm1_idinfo, + &snapcow_idinfo, + &luks_idinfo, + &vmfs_volume_idinfo, + + /* Filesystems */ + &vfat_idinfo, + &swsuspend_idinfo, + &swap_idinfo, + &xfs_idinfo, + &ext4dev_idinfo, + &ext4_idinfo, + &ext3_idinfo, + &ext2_idinfo, + &jbd_idinfo, + &reiser_idinfo, + &reiser4_idinfo, + &jfs_idinfo, + &udf_idinfo, + &iso9660_idinfo, + &zfs_idinfo, + &hfsplus_idinfo, + &hfs_idinfo, + &ufs_idinfo, + &hpfs_idinfo, + &sysv_idinfo, + &xenix_idinfo, + &ntfs_idinfo, + &cramfs_idinfo, + &romfs_idinfo, + &minix_idinfo, + &gfs_idinfo, + &gfs2_idinfo, + &ocfs_idinfo, + &ocfs2_idinfo, + &oracleasm_idinfo, + &vxfs_idinfo, + &squashfs_idinfo, + &netware_idinfo, + &btrfs_idinfo, + &ubifs_idinfo, + &bfs_idinfo, + &vmfs_fs_idinfo, + &befs_idinfo, + &nilfs2_idinfo, + &exfat_idinfo +}; + +/* + * Driver definition + */ +const struct blkid_chaindrv superblocks_drv = { + .id = BLKID_CHAIN_SUBLKS, + .name = "superblocks", + .dflt_enabled = TRUE, + .dflt_flags = BLKID_SUBLKS_DEFAULT, + .idinfos = idinfos, + .nidinfos = ARRAY_SIZE(idinfos), + .has_fltr = TRUE, + .probe = superblocks_probe, + .safeprobe = superblocks_safeprobe, +}; + +/** + * blkid_probe_enable_superblocks: + * @pr: probe + * @enable: TRUE/FALSE + * + * Enables/disables the superblocks probing for non-binary interface. + * + * Returns: 0 on success, or -1 in case of error. + */ +int blkid_probe_enable_superblocks(blkid_probe pr, int enable) +{ + if (!pr) + return -1; + pr->chains[BLKID_CHAIN_SUBLKS].enabled = enable; + return 0; +} + +/** + * blkid_probe_set_superblocks_flags: + * @pr: prober + * @flags: BLKID_SUBLKS_* flags + * + * Sets probing flags to the superblocks prober. This function is optional, the + * default are BLKID_SUBLKS_DEFAULTS flags. + * + * Returns: 0 on success, or -1 in case of error. + */ +int blkid_probe_set_superblocks_flags(blkid_probe pr, int flags) +{ + if (!pr) + return -1; + + pr->chains[BLKID_CHAIN_SUBLKS].flags = flags; + return 0; +} + +/** + * blkid_probe_reset_superblocks_filter: + * @pr: prober + * + * Resets superblocks probing filter + * + * Returns: 0 on success, or -1 in case of error. + */ +int blkid_probe_reset_superblocks_filter(blkid_probe pr) +{ + return __blkid_probe_reset_filter(pr, BLKID_CHAIN_SUBLKS); +} + +/** + * blkid_probe_invert_superblocks_filter: + * @pr: prober + * + * Inverts superblocks probing filter + * + * Returns: 0 on success, or -1 in case of error. + */ +int blkid_probe_invert_superblocks_filter(blkid_probe pr) +{ + return __blkid_probe_invert_filter(pr, BLKID_CHAIN_SUBLKS); +} + +/** + * blkid_probe_filter_superblocks_type: + * @pr: prober + * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag + * @names: NULL terminated array of probing function names (e.g. "vfat"). + * + * BLKID_FLTR_NOTIN - probe for all items which are NOT IN @names + * BLKID_FLTR_ONLYIN - probe for items which are IN @names + * + * Returns: 0 on success, or -1 in case of error. + */ +int blkid_probe_filter_superblocks_type(blkid_probe pr, int flag, char *names[]) +{ + return __blkid_probe_filter_types(pr, BLKID_CHAIN_SUBLKS, flag, names); +} + +/** + * blkid_probe_filter_superblocks_usage: + * @pr: prober + * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag + * @usage: BLKID_USAGE_* flags + * + * BLKID_FLTR_NOTIN - probe for all items which are NOT IN @usage + * BLKID_FLTR_ONLYIN - probe for items which are IN @usage + * + * Returns: 0 on success, or -1 in case of error. + */ +int blkid_probe_filter_superblocks_usage(blkid_probe pr, int flag, int usage) +{ + unsigned long *fltr; + struct blkid_chain *chn; + int i; + + if (!pr) + return -1; + + fltr = blkid_probe_get_filter(pr, BLKID_CHAIN_SUBLKS, TRUE); + if (!fltr) + return -1; + + chn = &pr->chains[BLKID_CHAIN_SUBLKS]; + + for (i = 0; i < chn->driver->nidinfos; i++) { + const struct blkid_idinfo *id = chn->driver->idinfos[i]; + + if (id->usage & usage) { + if (flag & BLKID_FLTR_NOTIN) + blkid_bmp_set_item(chn->fltr, i); + } else if (flag & BLKID_FLTR_ONLYIN) + blkid_bmp_set_item(chn->fltr, i); + } + DBG(DEBUG_LOWPROBE, printf("a new probing usage-filter initialized\n")); + return 0; +} + +/** + * blkid_known_fstype: + * @fstype: filesystem name + * + * Returns: 1 for known filesytems, or 0 for unknown filesystem. + */ +int blkid_known_fstype(const char *fstype) +{ + int i; + + if (!fstype) + return 0; + + for (i = 0; i < ARRAY_SIZE(idinfos); i++) { + const struct blkid_idinfo *id = idinfos[i]; + if (strcmp(id->name, fstype) == 0) + return 1; + } + return 0; +} + +/* + * The blkid_do_probe() backend. + */ +static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn) +{ + int i = 0; + + if (!pr || chn->idx < -1) + return -1; + blkid_probe_chain_reset_vals(pr, chn); + + DBG(DEBUG_LOWPROBE, + printf("--> starting probing loop [SUBLKS idx=%d]\n", + chn->idx)); + + if (pr->size <= 0 || (pr->size <= 1024 && !S_ISCHR(pr->mode))) + /* Ignore very very small block devices or regular files (e.g. + * extended partitions). Note that size of the UBI char devices + * is 1 byte */ + goto nothing; + + i = chn->idx + 1; + + for ( ; i < ARRAY_SIZE(idinfos); i++) { + const struct blkid_idinfo *id; + const struct blkid_idmag *mag = NULL; + blkid_loff_t off = 0; + + chn->idx = i; + + if (chn->fltr && blkid_bmp_get_item(chn->fltr, i)) + continue; + + id = idinfos[i]; + + if (id->minsz && id->minsz > pr->size) + continue; /* the device is too small */ + + mag = id->magics ? &id->magics[0] : NULL; + + /* don't probe for RAIDs, swap or journal on CD/DVDs */ + if ((id->usage & (BLKID_USAGE_RAID | BLKID_USAGE_OTHER)) && + blkid_probe_is_cdrom(pr)) + continue; + + /* don't probe for RAIDs on floppies */ + if ((id->usage & BLKID_USAGE_RAID) && blkid_probe_is_tiny(pr)) + continue; + + DBG(DEBUG_LOWPROBE, printf("[%d] %s:\n", i, id->name)); + + if (blkid_probe_get_idmag(pr, id, &off, &mag)) + continue; + + /* final check by probing function */ + if (id->probefunc) { + DBG(DEBUG_LOWPROBE, printf("\tcall probefunc()\n")); + if (id->probefunc(pr, mag) != 0) { + blkid_probe_chain_reset_vals(pr, chn); + continue; + } + } + + /* all cheks passed */ + if (chn->flags & BLKID_SUBLKS_TYPE) + blkid_probe_set_value(pr, "TYPE", + (unsigned char *) id->name, + strlen(id->name) + 1); + + blkid_probe_set_usage(pr, id->usage); + + if (mag) + blkid_probe_set_magic(pr, off, mag->len, + (unsigned char *) mag->magic); + + DBG(DEBUG_LOWPROBE, + printf("<-- leaving probing loop (type=%s) [SUBLKS idx=%d]\n", + id->name, chn->idx)); + return 0; + } + +nothing: + DBG(DEBUG_LOWPROBE, + printf("<-- leaving probing loop (failed) [SUBLKS idx=%d]\n", + chn->idx)); + return 1; +} + +/* + * This is the same function as blkid_do_probe(), but returns only one result + * (cannot be used in while()) and checks for ambivalen results (more + * filesystems on the device) -- in such case returns -2. + * + * The function does not check for filesystems when a RAID or crypto signature + * is detected. The function also does not check for collision between RAIDs + * and crypto devices. The first detected RAID or crypto device is returned. + * + * The function does not probe for ambivalent results on very small devices + * (e.g. floppies), on small devices the first detected filesystem is returned. + */ +static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn) +{ + struct blkid_prval vals[BLKID_NVALS_SUBLKS]; + int nvals = BLKID_NVALS_SUBLKS; + int idx = -1; + int count = 0; + int intol = 0; + int rc; + + while ((rc = superblocks_probe(pr, chn)) == 0) { + + if (blkid_probe_is_tiny(pr) && !count) + /* floppy or so -- returns the first result. */ + return 0; + + count++; + + if (idinfos[chn->idx]->usage & (BLKID_USAGE_RAID | BLKID_USAGE_CRYPTO)) + break; + + if (!(idinfos[chn->idx]->flags & BLKID_IDINFO_TOLERANT)) + intol++; + + if (count == 1) { + /* save the first result */ + nvals = blkid_probe_chain_copy_vals(pr, chn, vals, nvals); + idx = chn->idx; + } + } + + if (rc < 0) + return rc; /* error */ + + if (count > 1 && intol) { + DBG(DEBUG_LOWPROBE, + printf("ERROR: superblocks chain: " + "ambivalent result detected (%d filesystems)!\n", + count)); + return -2; /* error, ambivalent result (more FS) */ + } + if (!count) + return 1; /* nothing detected */ + + if (idx != -1) { + /* restore the first result */ + blkid_probe_chain_reset_vals(pr, chn); + blkid_probe_append_vals(pr, vals, nvals); + chn->idx = idx; + } + + /* + * The RAID device could be partitioned. The problem are RAID1 devices + * where the partition table is visible from underlaying devices. We + * have to ignore such partition tables. + */ + if (chn->idx >= 0 && idinfos[chn->idx]->usage & BLKID_USAGE_RAID) + pr->prob_flags |= BLKID_PROBE_FL_IGNORE_PT; + + return 0; +} + +int blkid_probe_set_magic(blkid_probe pr, blkid_loff_t offset, + size_t len, unsigned char *magic) +{ + int rc = 0; + struct blkid_chain *chn = blkid_probe_get_chain(pr); + + if (magic && len && (chn->flags & BLKID_SUBLKS_MAGIC)) { + rc = blkid_probe_set_value(pr, "SBMAGIC", magic, len); + if (!rc) + rc = blkid_probe_sprintf_value(pr, "SBMAGIC_OFFSET", + "%llu", offset); + } + return rc; +} + +int blkid_probe_set_version(blkid_probe pr, const char *version) +{ + struct blkid_chain *chn = blkid_probe_get_chain(pr); + + if (chn->flags & BLKID_SUBLKS_VERSION) + return blkid_probe_set_value(pr, "VERSION", + (unsigned char *) version, strlen(version) + 1); + return 0; +} + +int blkid_probe_sprintf_version(blkid_probe pr, const char *fmt, ...) +{ + struct blkid_chain *chn = blkid_probe_get_chain(pr); + int rc = 0; + + if (chn->flags & BLKID_SUBLKS_VERSION) { + va_list ap; + + va_start(ap, fmt); + rc = blkid_probe_vsprintf_value(pr, "VERSION", fmt, ap); + va_end(ap); + } + return rc; +} + +static int blkid_probe_set_usage(blkid_probe pr, int usage) +{ + struct blkid_chain *chn = blkid_probe_get_chain(pr); + char *u = NULL; + + if (!(chn->flags & BLKID_SUBLKS_USAGE)) + return 0; + + if (usage & BLKID_USAGE_FILESYSTEM) + u = "filesystem"; + else if (usage & BLKID_USAGE_RAID) + u = "raid"; + else if (usage & BLKID_USAGE_CRYPTO) + u = "crypto"; + else if (usage & BLKID_USAGE_OTHER) + u = "other"; + else + u = "unknown"; + + return blkid_probe_set_value(pr, "USAGE", (unsigned char *) u, strlen(u) + 1); +} + +int blkid_probe_set_label(blkid_probe pr, unsigned char *label, size_t len) +{ + struct blkid_chain *chn = blkid_probe_get_chain(pr); + struct blkid_prval *v; + if (len > BLKID_PROBVAL_BUFSIZ) + len = BLKID_PROBVAL_BUFSIZ; + + if ((chn->flags & BLKID_SUBLKS_LABELRAW) && + blkid_probe_set_value(pr, "LABEL_RAW", label, len) < 0) + return -1; + if (!(chn->flags & BLKID_SUBLKS_LABEL)) + return 0; + v = blkid_probe_assign_value(pr, "LABEL"); + if (!v) + return -1; + + if (len == BLKID_PROBVAL_BUFSIZ) + len--; /* make a space for \0 */ + + memcpy(v->data, label, len); + v->data[len] = '\0'; + + v->len = blkid_rtrim_whitespace(v->data) + 1; + if (v->len == 1) + blkid_probe_reset_last_value(pr); + return 0; +} + +int blkid_probe_set_utf8label(blkid_probe pr, unsigned char *label, + size_t len, int enc) +{ + struct blkid_chain *chn = blkid_probe_get_chain(pr); + struct blkid_prval *v; + + if ((chn->flags & BLKID_SUBLKS_LABELRAW) && + blkid_probe_set_value(pr, "LABEL_RAW", label, len) < 0) + return -1; + if (!(chn->flags & BLKID_SUBLKS_LABEL)) + return 0; + v = blkid_probe_assign_value(pr, "LABEL"); + if (!v) + return -1; + + blkid_encode_to_utf8(enc, v->data, sizeof(v->data), label, len); + v->len = blkid_rtrim_whitespace(v->data) + 1; + if (v->len == 1) + blkid_probe_reset_last_value(pr); + return 0; +} + +/* like uuid_is_null() from libuuid, but works with arbitrary size of UUID */ +static int uuid_is_empty(const unsigned char *buf, size_t len) +{ + int i; + + for (i = 0; i < len; i++) + if (buf[i]) + return 0; + return 1; +} + +int blkid_probe_sprintf_uuid(blkid_probe pr, unsigned char *uuid, + size_t len, const char *fmt, ...) +{ + struct blkid_chain *chn = blkid_probe_get_chain(pr); + int rc = -1; + va_list ap; + + if (len > BLKID_PROBVAL_BUFSIZ) + len = BLKID_PROBVAL_BUFSIZ; + + if (uuid_is_empty(uuid, len)) + return 0; + + if ((chn->flags & BLKID_SUBLKS_UUIDRAW) && + blkid_probe_set_value(pr, "UUID_RAW", uuid, len) < 0) + return -1; + if (!(chn->flags & BLKID_SUBLKS_UUID)) + return 0; + + va_start(ap, fmt); + rc = blkid_probe_vsprintf_value(pr, "UUID", fmt, ap); + va_end(ap); + + /* convert to lower case (..be paranoid) */ + if (!rc) { + int i; + struct blkid_prval *v = __blkid_probe_get_value(pr, + blkid_probe_numof_values(pr)); + if (v) { + for (i = 0; i < v->len; i++) + if (v->data[i] >= 'A' && v->data[i] <= 'F') + v->data[i] = (v->data[i] - 'A') + 'a'; + } + } + return rc; +} + +/* function to set UUIDs that are in suberblocks stored as strings */ +int blkid_probe_strncpy_uuid(blkid_probe pr, unsigned char *str, size_t len) +{ + struct blkid_chain *chn = blkid_probe_get_chain(pr); + struct blkid_prval *v; + + if (str == NULL || *str == '\0') + return -1; + if (!len) + len = strlen((char *) str); + if (len > BLKID_PROBVAL_BUFSIZ) + len = BLKID_PROBVAL_BUFSIZ; + + if ((chn->flags & BLKID_SUBLKS_UUIDRAW) && + blkid_probe_set_value(pr, "UUID_RAW", str, len) < 0) + return -1; + if (!(chn->flags & BLKID_SUBLKS_UUID)) + return 0; + + v = blkid_probe_assign_value(pr, "UUID"); + if (v) { + if (len == BLKID_PROBVAL_BUFSIZ) + len--; /* make a space for \0 */ + + memcpy((char *) v->data, str, len); + v->data[len] = '\0'; + v->len = len + 1; + return 0; + } + return -1; +} + +/* default _set_uuid function to set DCE UUIDs */ +int blkid_probe_set_uuid_as(blkid_probe pr, unsigned char *uuid, const char *name) +{ + struct blkid_chain *chn = blkid_probe_get_chain(pr); + struct blkid_prval *v; + + if (uuid_is_empty(uuid, 16)) + return 0; + + if (!name) { + if ((chn->flags & BLKID_SUBLKS_UUIDRAW) && + blkid_probe_set_value(pr, "UUID_RAW", uuid, 16) < 0) + return -1; + if (!(chn->flags & BLKID_SUBLKS_UUID)) + return 0; + + v = blkid_probe_assign_value(pr, "UUID"); + } else + v = blkid_probe_assign_value(pr, name); + + blkid_unparse_uuid(uuid, (char *) v->data, sizeof(v->data)); + v->len = 37; + + return 0; +} + +int blkid_probe_set_uuid(blkid_probe pr, unsigned char *uuid) +{ + return blkid_probe_set_uuid_as(pr, uuid, NULL); +} + +/* + * DEPRECATED FUNCTIONS + */ + +/** + * blkid_probe_set_request: + * @pr: probe + * @flags: BLKID_PROBREQ_* (deprecated) or BLKID_SUBLKS_* flags + * + * Returns: 0 on success, or -1 in case of error. + * + * Deprecated: Use blkid_probe_set_superblocks_flags(). + */ +int blkid_probe_set_request(blkid_probe pr, int flags) +{ + return blkid_probe_set_superblocks_flags(pr, flags); +} + +/** + * blkid_probe_reset_filter: + * @pr: prober + * + * Returns: 0 on success, or -1 in case of error. + * + * Deprecated: Use blkid_probe_reset_superblocks_filter(). + */ +int blkid_probe_reset_filter(blkid_probe pr) +{ + return __blkid_probe_reset_filter(pr, BLKID_CHAIN_SUBLKS); +} + +/** + * blkid_probe_invert_filter: + * @pr: prober + * + * Returns: 0 on success, or -1 in case of error. + * + * Deprecated: Use blkid_probe_invert_superblocks_filter(). + */ +int blkid_probe_invert_filter(blkid_probe pr) +{ + return __blkid_probe_invert_filter(pr, BLKID_CHAIN_SUBLKS); +} + +/** + * blkid_probe_filter_types + * @pr: prober + * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag + * @names: NULL terminated array of probing function names (e.g. "vfat"). + * + * Returns: 0 on success, or -1 in case of error. + * + * Deprecated: Use blkid_probe_filter_superblocks_types(). + */ +int blkid_probe_filter_types(blkid_probe pr, int flag, char *names[]) +{ + return __blkid_probe_filter_types(pr, BLKID_CHAIN_SUBLKS, flag, names); +} + +/** + * blkid_probe_filter_usage + * @pr: prober + * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag + * @usage: BLKID_USAGE_* flags + * + * Returns: 0 on success, or -1 in case of error. + * + * Deprecated: Use blkid_probe_filter_superblocks_usage(). + */ +int blkid_probe_filter_usage(blkid_probe pr, int flag, int usage) +{ + return blkid_probe_filter_superblocks_usage(pr, flag, usage); +} + diff --git a/libblkid/src/superblocks/superblocks.h b/libblkid/src/superblocks/superblocks.h new file mode 100644 index 00000000..a79d7cb6 --- /dev/null +++ b/libblkid/src/superblocks/superblocks.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2008-2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#ifndef _BLKID_SUPERBLOCKS_H +#define _BLKID_SUPERBLOCKS_H + +#include "blkidP.h" + +extern const struct blkid_idinfo cramfs_idinfo; +extern const struct blkid_idinfo swap_idinfo; +extern const struct blkid_idinfo swsuspend_idinfo; +extern const struct blkid_idinfo adraid_idinfo; +extern const struct blkid_idinfo ddfraid_idinfo; +extern const struct blkid_idinfo iswraid_idinfo; +extern const struct blkid_idinfo jmraid_idinfo; +extern const struct blkid_idinfo lsiraid_idinfo; +extern const struct blkid_idinfo nvraid_idinfo; +extern const struct blkid_idinfo pdcraid_idinfo; +extern const struct blkid_idinfo silraid_idinfo; +extern const struct blkid_idinfo viaraid_idinfo; +extern const struct blkid_idinfo linuxraid_idinfo; +extern const struct blkid_idinfo ext4dev_idinfo; +extern const struct blkid_idinfo ext4_idinfo; +extern const struct blkid_idinfo ext3_idinfo; +extern const struct blkid_idinfo ext2_idinfo; +extern const struct blkid_idinfo jbd_idinfo; +extern const struct blkid_idinfo jfs_idinfo; +extern const struct blkid_idinfo xfs_idinfo; +extern const struct blkid_idinfo gfs_idinfo; +extern const struct blkid_idinfo gfs2_idinfo; +extern const struct blkid_idinfo romfs_idinfo; +extern const struct blkid_idinfo ocfs_idinfo; +extern const struct blkid_idinfo ocfs2_idinfo; +extern const struct blkid_idinfo oracleasm_idinfo; +extern const struct blkid_idinfo reiser_idinfo; +extern const struct blkid_idinfo reiser4_idinfo; +extern const struct blkid_idinfo hfs_idinfo; +extern const struct blkid_idinfo hfsplus_idinfo; +extern const struct blkid_idinfo ntfs_idinfo; +extern const struct blkid_idinfo iso9660_idinfo; +extern const struct blkid_idinfo udf_idinfo; +extern const struct blkid_idinfo vxfs_idinfo; +extern const struct blkid_idinfo minix_idinfo; +extern const struct blkid_idinfo vfat_idinfo; +extern const struct blkid_idinfo ufs_idinfo; +extern const struct blkid_idinfo hpfs_idinfo; +extern const struct blkid_idinfo lvm2_idinfo; +extern const struct blkid_idinfo lvm1_idinfo; +extern const struct blkid_idinfo snapcow_idinfo; +extern const struct blkid_idinfo luks_idinfo; +extern const struct blkid_idinfo highpoint37x_idinfo; +extern const struct blkid_idinfo highpoint45x_idinfo; +extern const struct blkid_idinfo squashfs_idinfo; +extern const struct blkid_idinfo netware_idinfo; +extern const struct blkid_idinfo sysv_idinfo; +extern const struct blkid_idinfo xenix_idinfo; +extern const struct blkid_idinfo btrfs_idinfo; +extern const struct blkid_idinfo ubifs_idinfo; +extern const struct blkid_idinfo zfs_idinfo; +extern const struct blkid_idinfo bfs_idinfo; +extern const struct blkid_idinfo vmfs_volume_idinfo; +extern const struct blkid_idinfo vmfs_fs_idinfo; +extern const struct blkid_idinfo drbd_idinfo; +extern const struct blkid_idinfo befs_idinfo; +extern const struct blkid_idinfo nilfs2_idinfo; +extern const struct blkid_idinfo exfat_idinfo; + +/* + * superblock functions + */ +extern int blkid_probe_set_magic(blkid_probe pr, blkid_loff_t offset, + size_t len, unsigned char *magic); +extern int blkid_probe_set_version(blkid_probe pr, const char *version); +extern int blkid_probe_sprintf_version(blkid_probe pr, const char *fmt, ...) + __attribute__ ((format (printf, 2, 3))); + +extern int blkid_probe_set_label(blkid_probe pr, unsigned char *label, size_t len); +extern int blkid_probe_set_utf8label(blkid_probe pr, unsigned char *label, + size_t len, int enc); +extern int blkid_probe_sprintf_uuid(blkid_probe pr, unsigned char *uuid, + size_t len, const char *fmt, ...) + __attribute__ ((format (printf, 4, 5))); +extern int blkid_probe_strncpy_uuid(blkid_probe pr, unsigned char *str, size_t len); + +extern int blkid_probe_set_uuid(blkid_probe pr, unsigned char *uuid); +extern int blkid_probe_set_uuid_as(blkid_probe pr, unsigned char *uuid, const char *name); + + +#endif /* _BLKID_SUPERBLOCKS_H */ diff --git a/libblkid/src/superblocks/swap.c b/libblkid/src/superblocks/swap.c new file mode 100644 index 00000000..325a8faf --- /dev/null +++ b/libblkid/src/superblocks/swap.c @@ -0,0 +1,171 @@ +/* + * Copyright (C) 1999 by Andries Brouwer + * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o + * Copyright (C) 2001 by Andreas Dilger + * Copyright (C) 2004 Kay Sievers + * Copyright (C) 2008 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include +#include +#include + +#include "superblocks.h" + +/* linux-2.6/include/linux/swap.h */ +struct swap_header_v1_2 { + /* char bootbits[1024]; */ /* Space for disklabel etc. */ + uint32_t version; + uint32_t lastpage; + uint32_t nr_badpages; + unsigned char uuid[16]; + unsigned char volume[16]; + uint32_t padding[117]; + uint32_t badpages[1]; +} __attribute__((packed)); + +#define PAGESIZE_MIN 0xff6 /* 4086 (arm, i386, ...) */ +#define PAGESIZE_MAX 0xfff6 /* 65526 (ia64) */ + +#define TOI_MAGIC_STRING "\xed\xc3\x02\xe9\x98\x56\xe5\x0c" +#define TOI_MAGIC_STRLEN (sizeof(TOI_MAGIC_STRING) - 1) + +static int swap_set_info(blkid_probe pr, const char *version) +{ + struct swap_header_v1_2 *hdr; + + /* Swap header always located at offset of 1024 bytes */ + hdr = (struct swap_header_v1_2 *) blkid_probe_get_buffer(pr, 1024, + sizeof(struct swap_header_v1_2)); + if (!hdr) + return -1; + + /* SWAPSPACE2 - check for wrong version or zeroed pagecount */ + if (strcmp(version, "2") == 0 && + (hdr->version != 1 || hdr->lastpage == 0)) + return -1; + + /* arbitrary sanity check.. is there any garbage down there? */ + if (hdr->padding[32] == 0 && hdr->padding[33] == 0) { + if (hdr->volume[0] && blkid_probe_set_label(pr, hdr->volume, + sizeof(hdr->volume)) < 0) + return -1; + if (hdr->uuid[0] && blkid_probe_set_uuid(pr, hdr->uuid) < 0) + return -1; + } + + blkid_probe_set_version(pr, version); + return 0; +} + +static int probe_swap(blkid_probe pr, const struct blkid_idmag *mag) +{ + unsigned char *buf; + + if (!mag) + return -1; + + /* TuxOnIce keeps valid swap header at the end of the 1st page */ + buf = blkid_probe_get_buffer(pr, 0, TOI_MAGIC_STRLEN); + if (!buf) + return -1; + + if (memcmp(buf, TOI_MAGIC_STRING, TOI_MAGIC_STRLEN) == 0) + return 1; /* Ignore swap signature, it's TuxOnIce */ + + if (!memcmp(mag->magic, "SWAP-SPACE", mag->len)) { + /* swap v0 doesn't support LABEL or UUID */ + blkid_probe_set_version(pr, "1"); + return 0; + + } else if (!memcmp(mag->magic, "SWAPSPACE2", mag->len)) + return swap_set_info(pr, "2"); + + return -1; +} + +static int probe_swsuspend(blkid_probe pr, const struct blkid_idmag *mag) +{ + if (!mag) + return -1; + if (!memcmp(mag->magic, "S1SUSPEND", mag->len)) + return swap_set_info(pr, "s1suspend"); + if (!memcmp(mag->magic, "S2SUSPEND", mag->len)) + return swap_set_info(pr, "s2suspend"); + if (!memcmp(mag->magic, "ULSUSPEND", mag->len)) + return swap_set_info(pr, "ulsuspend"); + if (!memcmp(mag->magic, TOI_MAGIC_STRING, mag->len)) + return swap_set_info(pr, "tuxonice"); + if (!memcmp(mag->magic, "LINHIB0001", mag->len)) + return swap_set_info(pr, "linhib0001"); + + return -1; /* no signature detected */ +} + +const struct blkid_idinfo swap_idinfo = +{ + .name = "swap", + .usage = BLKID_USAGE_OTHER, + .probefunc = probe_swap, + .minsz = 10 * 4096, /* 10 pages */ + .magics = + { + { "SWAP-SPACE", 10, 0, 0xff6 }, + { "SWAPSPACE2", 10, 0, 0xff6 }, + { "SWAP-SPACE", 10, 0, 0x1ff6 }, + { "SWAPSPACE2", 10, 0, 0x1ff6 }, + { "SWAP-SPACE", 10, 0, 0x3ff6 }, + { "SWAPSPACE2", 10, 0, 0x3ff6 }, + { "SWAP-SPACE", 10, 0, 0x7ff6 }, + { "SWAPSPACE2", 10, 0, 0x7ff6 }, + { "SWAP-SPACE", 10, 0, 0xfff6 }, + { "SWAPSPACE2", 10, 0, 0xfff6 }, + { NULL } + } +}; + + +const struct blkid_idinfo swsuspend_idinfo = +{ + .name = "swsuspend", + .usage = BLKID_USAGE_OTHER, + .probefunc = probe_swsuspend, + .minsz = 10 * 4096, /* 10 pages */ + .magics = + { + { TOI_MAGIC_STRING, TOI_MAGIC_STRLEN, 0, 0 }, + { "S1SUSPEND", 9, 0, 0xff6 }, + { "S2SUSPEND", 9, 0, 0xff6 }, + { "ULSUSPEND", 9, 0, 0xff6 }, + { "LINHIB0001",10,0, 0xff6 }, + + { "S1SUSPEND", 9, 0, 0x1ff6 }, + { "S2SUSPEND", 9, 0, 0x1ff6 }, + { "ULSUSPEND", 9, 0, 0x1ff6 }, + { "LINHIB0001",10,0, 0x1ff6 }, + + { "S1SUSPEND", 9, 0, 0x3ff6 }, + { "S2SUSPEND", 9, 0, 0x3ff6 }, + { "ULSUSPEND", 9, 0, 0x3ff6 }, + { "LINHIB0001",10,0, 0x3ff6 }, + + { "S1SUSPEND", 9, 0, 0x7ff6 }, + { "S2SUSPEND", 9, 0, 0x7ff6 }, + { "ULSUSPEND", 9, 0, 0x7ff6 }, + { "LINHIB0001",10,0, 0x7ff6 }, + + { "S1SUSPEND", 9, 0, 0xfff6 }, + { "S2SUSPEND", 9, 0, 0xfff6 }, + { "ULSUSPEND", 9, 0, 0xfff6 }, + { "LINHIB0001",10,0, 0xfff6 }, + + { NULL } + } +}; + diff --git a/libblkid/src/superblocks/sysv.c b/libblkid/src/superblocks/sysv.c new file mode 100644 index 00000000..00c8c978 --- /dev/null +++ b/libblkid/src/superblocks/sysv.c @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2008 Karel Zak + * + * This is written from sratch according to Linux kernel fs/sysv/super.c file. + * It seems that sysv probing code in libvolume_id and also in the original + * blkid is useless. + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include + +#include "superblocks.h" + +#define XENIX_NICINOD 100 +#define XENIX_NICFREE 100 + +struct xenix_super_block { + 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; +} __attribute__((packed)); + + +#define SYSV_NICINOD 100 +#define SYSV_NICFREE 50 + +struct sysv_super_block +{ + 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; +}; + +static int probe_xenix(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct xenix_super_block *sb; + + sb = blkid_probe_get_sb(pr, mag, struct xenix_super_block); + if (!sb) + return -1; + blkid_probe_set_label(pr, sb->s_fname, sizeof(sb->s_fname)); + return 0; +} + +#define SYSV_BLOCK_SIZE 1024 + +/* Note that we don't probe for Coherent FS, this FS does not have + * magic string. (It requires to probe fname/fpack field..) + */ +static int probe_sysv(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct sysv_super_block *sb; + int blocks[] = {0, 9, 15, 18}; + int i; + + for (i = 0; i < ARRAY_SIZE(blocks); i++) { + int off = blocks[i] * SYSV_BLOCK_SIZE + SYSV_BLOCK_SIZE/2; + + sb = (struct sysv_super_block *) + blkid_probe_get_buffer(pr, + off, + sizeof(struct sysv_super_block)); + if (!sb) + return -1; + + if (sb->s_magic == cpu_to_le32(0xfd187e20) || + sb->s_magic == cpu_to_be32(0xfd187e20)) { + + if (blkid_probe_set_label(pr, sb->s_fname, + sizeof(sb->s_fname))) + return -1; + + if (blkid_probe_set_magic(pr, + off + offsetof(struct sysv_super_block, + s_magic), + sizeof(sb->s_magic), + (unsigned char *) &sb->s_magic)) + return -1; + + return 0; + } + } + return 1; +} + +const struct blkid_idinfo xenix_idinfo = +{ + .name = "xenix", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_xenix, + .magics = + { + { .magic = "\x2b\x55\x44", .len = 3, .kboff = 1, .sboff = 0x400 }, + { .magic = "\x44\x55\x2b", .len = 3, .kboff = 1, .sboff = 0x400 }, + { NULL } + } +}; + +const struct blkid_idinfo sysv_idinfo = +{ + .name = "sysv", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_sysv, + + /* SYSV is BE and LE and superblock could be on four positions. It's + * simpler to probe for the magic string by .probefunc(). + */ + .magics = BLKID_NONE_MAGIC +}; + diff --git a/libblkid/src/superblocks/ubifs.c b/libblkid/src/superblocks/ubifs.c new file mode 100644 index 00000000..87d94ba2 --- /dev/null +++ b/libblkid/src/superblocks/ubifs.c @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2009 Corentin Chary + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include + +#include "superblocks.h" + +/** + * struct ubifs_ch - common header node. + * @magic: UBIFS node magic number (%UBIFS_NODE_MAGIC) + * @crc: CRC-32 checksum of the node header + * @sqnum: sequence number + * @len: full node length + * @node_type: node type + * @group_type: node group type + * @padding: reserved for future, zeroes + * + * Every UBIFS node starts with this common part. If the node has a key, the + * key always goes next. + */ +struct ubifs_ch { + uint32_t magic; + uint32_t crc; + uint64_t sqnum; + uint32_t len; + uint8_t node_type; + uint8_t group_type; + uint8_t padding[2]; +} __attribute__ ((packed)); + +/** + * struct ubifs_sb_node - superblock node. + * @ch: common header + * @padding: reserved for future, zeroes + * @key_hash: type of hash function used in keys + * @key_fmt: format of the key + * @flags: file-system flags (%UBIFS_FLG_BIGLPT, etc) + * @min_io_size: minimal input/output unit size + * @leb_size: logical eraseblock size in bytes + * @leb_cnt: count of LEBs used by file-system + * @max_leb_cnt: maximum count of LEBs used by file-system + * @max_bud_bytes: maximum amount of data stored in buds + * @log_lebs: log size in logical eraseblocks + * @lpt_lebs: number of LEBs used for lprops table + * @orph_lebs: number of LEBs used for recording orphans + * @jhead_cnt: count of journal heads + * @fanout: tree fanout (max. number of links per indexing node) + * @lsave_cnt: number of LEB numbers in LPT's save table + * @fmt_version: UBIFS on-flash format version + * @default_compr: default compression algorithm (%UBIFS_COMPR_LZO, etc) + * @padding1: reserved for future, zeroes + * @rp_uid: reserve pool UID + * @rp_gid: reserve pool GID + * @rp_size: size of the reserved pool in bytes + * @padding2: reserved for future, zeroes + * @time_gran: time granularity in nanoseconds + * @uuid: UUID generated when the file system image was created + * @ro_compat_version: UBIFS R/O compatibility version + */ +struct ubifs_sb_node { + struct ubifs_ch ch; + uint8_t padding[2]; + uint8_t key_hash; + uint8_t key_fmt; + uint32_t flags; + uint32_t min_io_size; + uint32_t leb_size; + uint32_t leb_cnt; + uint32_t max_leb_cnt; + uint64_t max_bud_bytes; + uint32_t log_lebs; + uint32_t lpt_lebs; + uint32_t orph_lebs; + uint32_t jhead_cnt; + uint32_t fanout; + uint32_t lsave_cnt; + uint32_t fmt_version; + uint16_t default_compr; + uint8_t padding1[2]; + uint32_t rp_uid; + uint32_t rp_gid; + uint64_t rp_size; + uint32_t time_gran; + uint8_t uuid[16]; + uint32_t ro_compat_version; + uint8_t padding2[3968]; +} __attribute__ ((packed)); + + +static int probe_ubifs(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct ubifs_sb_node *sb; + + sb = blkid_probe_get_sb(pr, mag, struct ubifs_sb_node); + if (!sb) + return -1; + + blkid_probe_set_uuid(pr, sb->uuid); + blkid_probe_sprintf_version(pr, "w%dr%d", + sb->fmt_version, sb->ro_compat_version); + return 0; +} + +const struct blkid_idinfo ubifs_idinfo = +{ + .name = "ubifs", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_ubifs, + .magics = + { + { .magic = "\x31\x18\x10\x06", .len = 4 }, + { NULL } + } +}; diff --git a/libblkid/src/superblocks/udf.c b/libblkid/src/superblocks/udf.c new file mode 100644 index 00000000..766d6980 --- /dev/null +++ b/libblkid/src/superblocks/udf.c @@ -0,0 +1,168 @@ +/* + * Copyright (C) 1999 by Andries Brouwer + * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o + * Copyright (C) 2001 by Andreas Dilger + * Copyright (C) 2004 Kay Sievers + * Copyright (C) 2008 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include +#include +#include + +#include "superblocks.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; + } __attribute__((packed)) tag; + + union { + struct anchor_descriptor { + uint32_t length; + uint32_t location; + } __attribute__((packed)) anchor; + + struct primary_descriptor { + uint32_t seq_num; + uint32_t desc_num; + struct dstring { + uint8_t clen; + uint8_t c[31]; + } __attribute__((packed)) ident; + } __attribute__((packed)) primary; + + } __attribute__((packed)) type; + +} __attribute__((packed)); + +struct volume_structure_descriptor { + uint8_t type; + uint8_t id[5]; + uint8_t version; +} __attribute__((packed)); + +#define UDF_VSD_OFFSET 0x8000LL + +static int probe_udf(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct volume_descriptor *vd; + struct volume_structure_descriptor *vsd; + unsigned int bs; + unsigned int b; + unsigned int type; + unsigned int count; + unsigned int loc; + + /* search Volume Sequence Descriptor (VSD) to get the logical + * block size of the volume */ + for (bs = 0x800; bs < 0x8000; bs += 0x800) { + vsd = (struct volume_structure_descriptor *) + blkid_probe_get_buffer(pr, + UDF_VSD_OFFSET + bs, + sizeof(*vsd)); + if (!vsd) + return 1; + 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 *) + blkid_probe_get_buffer(pr, + UDF_VSD_OFFSET + ((blkid_loff_t) b * bs), + sizeof(*vsd)); + if (!vsd) + return -1; + 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 (AVDP) */ + vd = (struct volume_descriptor *) + blkid_probe_get_buffer(pr, 256 * bs, sizeof(*vd)); + if (!vd) + return -1; + + type = le16_to_cpu(vd->tag.id); + if (type != 2) /* TAG_ID_AVDP */ + return 0; + + /* get desriptor list address and block count */ + count = le32_to_cpu(vd->type.anchor.length) / bs; + loc = le32_to_cpu(vd->type.anchor.location); + + /* pick the primary descriptor from the list */ + for (b = 0; b < count; b++) { + vd = (struct volume_descriptor *) + blkid_probe_get_buffer(pr, + (blkid_loff_t) (loc + b) * bs, + sizeof(*vd)); + if (!vd) + return -1; + + type = le16_to_cpu(vd->tag.id); + if (type == 0) + break; + if (le32_to_cpu(vd->tag.location) != loc + b) + break; + if (type == 1) { /* TAG_ID_PVD */ + uint8_t clen = vd->type.primary.ident.clen; + + if (clen == 8) + blkid_probe_set_label(pr, + vd->type.primary.ident.c, 31); + else if (clen == 16) + blkid_probe_set_utf8label(pr, + vd->type.primary.ident.c, + 31, BLKID_ENC_UTF16BE); + + if (clen == 8 || clen == 16) + break; + } + } + + return 0; +} + + +const struct blkid_idinfo udf_idinfo = +{ + .name = "udf", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_udf, + .flags = BLKID_IDINFO_TOLERANT, + .magics = + { + { .magic = "BEA01", .len = 5, .kboff = 32, .sboff = 1 }, + { .magic = "BOOT2", .len = 5, .kboff = 32, .sboff = 1 }, + { .magic = "CD001", .len = 5, .kboff = 32, .sboff = 1 }, + { .magic = "CDW02", .len = 5, .kboff = 32, .sboff = 1 }, + { .magic = "NSR02", .len = 5, .kboff = 32, .sboff = 1 }, + { .magic = "NSR03", .len = 5, .kboff = 32, .sboff = 1 }, + { .magic = "TEA01", .len = 5, .kboff = 32, .sboff = 1 }, + { NULL } + } +}; diff --git a/libblkid/src/superblocks/ufs.c b/libblkid/src/superblocks/ufs.c new file mode 100644 index 00000000..05bed145 --- /dev/null +++ b/libblkid/src/superblocks/ufs.c @@ -0,0 +1,238 @@ +/* + * Copyright (C) 2008 Karel Zak + * + * Inspired by libvolume_id by + * Kay Sievers + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "superblocks.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; + } 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]; + } 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]; + } fs_cstotal; + struct ufs_timeval { + int32_t tv_sec; + int32_t tv_usec; + } fs_time; + int64_t fs_size; + int64_t fs_dsize; + uint64_t fs_csaddr; + int64_t fs_pendingblocks; + int32_t fs_pendinginodes; + } __attribute__((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]; + } 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]; + } 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; + } 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]; +} __attribute__((packed)); + +#define UFS_MAGIC 0x00011954 +#define UFS2_MAGIC 0x19540119 +#define UFS_MAGIC_FEA 0x00195612 +#define UFS_MAGIC_LFN 0x00095014 +#define UFS_MAGIC_SEC 0x00612195 +#define UFS_MAGIC_4GB 0x05231994 + +static int probe_ufs(blkid_probe pr, const struct blkid_idmag *mag) +{ + int offsets[] = { 0, 8, 64, 256 }; + int mags[] = { + UFS2_MAGIC, UFS_MAGIC, UFS_MAGIC_FEA, UFS_MAGIC_LFN, + UFS_MAGIC_SEC, UFS_MAGIC_4GB + }; + int i; + uint32_t magic; + struct ufs_super_block *ufs; + + for (i = 0; i < ARRAY_SIZE(offsets); i++) { + uint32_t magLE, magBE; + int y; + + ufs = (struct ufs_super_block *) + blkid_probe_get_buffer(pr, + offsets[i] * 1024, + sizeof(struct ufs_super_block)); + if (!ufs) + return -1; + + magBE = be32_to_cpu(ufs->fs_magic); + magLE = le32_to_cpu(ufs->fs_magic); + + for (y = 0; y < ARRAY_SIZE(mags); y++) { + if (magLE == mags[y] || magBE == mags[y]) { + magic = mags[y]; + goto found; + } + } + } + + return 1; + +found: + if (magic == UFS2_MAGIC) { + blkid_probe_set_version(pr, "2"); + blkid_probe_set_label(pr, ufs->fs_u11.fs_u2.fs_volname, + sizeof(ufs->fs_u11.fs_u2.fs_volname)); + } else + blkid_probe_set_version(pr, "1"); + + if (blkid_probe_set_magic(pr, + (offsets[i] * 1024) + + offsetof(struct ufs_super_block, fs_magic), + sizeof(ufs->fs_magic), + (unsigned char *) &ufs->fs_magic)) + return -1; + + return 0; +} + +/* + * According to libvolume_id the UFS superblock could be on four positions. + * The original libblkid has checked one position (.kboff=8) only. + * + * We know four UFS magic strings and UFS could be both little-endian and + * big-endian. ... so we have: + * + * 4 position * 4 string * 2 version = 32 magic strings + * + * It seems simpler to check for these string in probing function that hardcode + * all in the .magic array. + */ +const struct blkid_idinfo ufs_idinfo = +{ + .name = "ufs", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_ufs, + .magics = BLKID_NONE_MAGIC +}; + diff --git a/libblkid/src/superblocks/vfat.c b/libblkid/src/superblocks/vfat.c new file mode 100644 index 00000000..1584efae --- /dev/null +++ b/libblkid/src/superblocks/vfat.c @@ -0,0 +1,427 @@ +/* + * Copyright (C) 1999 by Andries Brouwer + * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o + * Copyright (C) 2001 by Andreas Dilger + * Copyright (C) 2004 Kay Sievers + * Copyright (C) 2008 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include +#include +#include + +#include "superblocks.h" + +/* Yucky misaligned values */ +struct vfat_super_block { +/* 00*/ unsigned char vs_ignored[3]; +/* 03*/ unsigned char vs_sysid[8]; +/* 0b*/ unsigned char vs_sector_size[2]; +/* 0d*/ uint8_t vs_cluster_size; +/* 0e*/ uint16_t vs_reserved; +/* 10*/ uint8_t vs_fats; +/* 11*/ unsigned char vs_dir_entries[2]; +/* 13*/ unsigned char vs_sectors[2]; +/* 15*/ unsigned char vs_media; +/* 16*/ uint16_t vs_fat_length; +/* 18*/ uint16_t vs_secs_track; +/* 1a*/ uint16_t vs_heads; +/* 1c*/ uint32_t vs_hidden; +/* 20*/ uint32_t vs_total_sect; +/* 24*/ uint32_t vs_fat32_length; +/* 28*/ uint16_t vs_flags; +/* 2a*/ uint8_t vs_version[2]; +/* 2c*/ uint32_t vs_root_cluster; +/* 30*/ uint16_t vs_fsinfo_sector; +/* 32*/ uint16_t vs_backup_boot; +/* 34*/ uint16_t vs_reserved2[6]; +/* 40*/ unsigned char vs_unknown[3]; +/* 43*/ unsigned char vs_serno[4]; +/* 47*/ unsigned char vs_label[11]; +/* 52*/ unsigned char vs_magic[8]; +/* 5a*/ unsigned char vs_dummy2[0x1fe - 0x5a]; +/*1fe*/ unsigned char vs_pmagic[2]; +} __attribute__((packed)); + +/* Yucky misaligned values */ +struct msdos_super_block { +/* 00*/ unsigned char ms_ignored[3]; +/* 03*/ unsigned char ms_sysid[8]; +/* 0b*/ unsigned char ms_sector_size[2]; +/* 0d*/ uint8_t ms_cluster_size; +/* 0e*/ uint16_t ms_reserved; +/* 10*/ uint8_t ms_fats; +/* 11*/ unsigned char ms_dir_entries[2]; +/* 13*/ unsigned char ms_sectors[2]; /* =0 iff V3 or later */ +/* 15*/ unsigned char ms_media; +/* 16*/ uint16_t ms_fat_length; /* Sectors per FAT */ +/* 18*/ uint16_t ms_secs_track; +/* 1a*/ uint16_t ms_heads; +/* 1c*/ uint32_t ms_hidden; +/* V3 BPB */ +/* 20*/ uint32_t ms_total_sect; /* iff ms_sectors == 0 */ +/* V4 BPB */ +/* 24*/ unsigned char ms_unknown[3]; /* Phys drive no., resvd, V4 sig (0x29) */ +/* 27*/ unsigned char ms_serno[4]; +/* 2b*/ unsigned char ms_label[11]; +/* 36*/ unsigned char ms_magic[8]; +/* 3e*/ unsigned char ms_dummy2[0x1fe - 0x3e]; +/*1fe*/ unsigned char ms_pmagic[2]; +} __attribute__((packed)); + +struct vfat_dir_entry { + uint8_t name[11]; + uint8_t attr; + uint16_t time_creat; + uint16_t date_creat; + uint16_t time_acc; + uint16_t date_acc; + uint16_t cluster_high; + uint16_t time_write; + uint16_t date_write; + uint16_t cluster_low; + uint32_t size; +} __attribute__((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]; +} __attribute__((packed)); + +/* maximum number of clusters */ +#define FAT12_MAX 0xFF4 +#define FAT16_MAX 0xFFF4 +#define FAT32_MAX 0x0FFFFFF6 + +#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 + +static const char *no_name = "NO NAME "; + +#define unaligned_le16(x) \ + (((unsigned char *) x)[0] + (((unsigned char *) x)[1] << 8)) + +/* + * Look for LABEL (name) in the FAT root directory. + */ +static unsigned char *search_fat_label(blkid_probe pr, + uint32_t offset, uint32_t entries) +{ + struct vfat_dir_entry *ent, *dir = NULL; + int i; + + DBG(DEBUG_LOWPROBE, + printf("\tlook for label in root-dir " + "(entries: %d, offset: %d)\n", entries, offset)); + + if (!blkid_probe_is_tiny(pr)) { + /* large disk, read whole root directory */ + dir = (struct vfat_dir_entry *) + blkid_probe_get_buffer(pr, + offset, + (blkid_loff_t) entries * + sizeof(struct vfat_dir_entry)); + if (!dir) + return NULL; + } + + for (i = 0; i < entries; i++) { + /* + * The root directory could be relatively large (4-16kB). + * Fortunately, the LABEL is usually the first entry in the + * directory. On tiny disks we call read() per entry. + */ + if (!dir) + ent = (struct vfat_dir_entry *) + blkid_probe_get_buffer(pr, + (blkid_loff_t) offset + (i * + sizeof(struct vfat_dir_entry)), + sizeof(struct vfat_dir_entry)); + else + ent = &dir[i]; + + if (!ent || ent->name[0] == 0x00) + break; + + if ((ent->name[0] == FAT_ENTRY_FREE) || + (ent->cluster_high != 0 || ent->cluster_low != 0) || + ((ent->attr & FAT_ATTR_MASK) == FAT_ATTR_LONG_NAME)) + continue; + + if ((ent->attr & (FAT_ATTR_VOLUME_ID | FAT_ATTR_DIR)) == + FAT_ATTR_VOLUME_ID) { + DBG(DEBUG_LOWPROBE, + printf("\tfound fs LABEL at entry %d\n", i)); + return ent->name; + } + } + return NULL; +} + +static int fat_valid_superblock(const struct blkid_idmag *mag, + struct msdos_super_block *ms, + struct vfat_super_block *vs, + uint32_t *cluster_count, uint32_t *fat_size) +{ + uint16_t sector_size, dir_entries, reserved; + uint32_t sect_count, __fat_size, dir_size, __cluster_count, fat_length; + uint32_t max_count; + + /* extra check for FATs without magic strings */ + if (mag->len <= 2) { + /* Old floppies have a valid MBR signature */ + if (ms->ms_pmagic[0] != 0x55 || ms->ms_pmagic[1] != 0xAA) + return 0; + + /* + * OS/2 and apparently DFSee will place a FAT12/16-like + * pseudo-superblock in the first 512 bytes of non-FAT + * filesystems --- at least JFS and HPFS, and possibly others. + * So we explicitly check for those filesystems at the + * FAT12/16 filesystem magic field identifier, and if they are + * present, we rule this out as a FAT filesystem, despite the + * FAT-like pseudo-header. + */ + if ((memcmp(ms->ms_magic, "JFS ", 8) == 0) || + (memcmp(ms->ms_magic, "HPFS ", 8) == 0)) + return 0; + } + + /* fat counts(Linux kernel expects at least 1 FAT table) */ + if (!ms->ms_fats) + return 0; + if (!ms->ms_reserved) + return 0; + if (!(0xf8 <= ms->ms_media || ms->ms_media == 0xf0)) + return 0; + if (!is_power_of_2(ms->ms_cluster_size)) + return 0; + + sector_size = unaligned_le16(&ms->ms_sector_size); + if (!is_power_of_2(sector_size) || + sector_size < 512 || sector_size > 4096) + return 0; + + dir_entries = unaligned_le16(&ms->ms_dir_entries); + reserved = le16_to_cpu(ms->ms_reserved); + sect_count = unaligned_le16(&ms->ms_sectors); + + if (sect_count == 0) + sect_count = le32_to_cpu(ms->ms_total_sect); + + fat_length = le16_to_cpu(ms->ms_fat_length); + if (fat_length == 0) + fat_length = le32_to_cpu(vs->vs_fat32_length); + + __fat_size = fat_length * ms->ms_fats; + dir_size = ((dir_entries * sizeof(struct vfat_dir_entry)) + + (sector_size-1)) / sector_size; + + __cluster_count = (sect_count - (reserved + __fat_size + dir_size)) / + ms->ms_cluster_size; + if (!ms->ms_fat_length && vs->vs_fat32_length) + max_count = FAT32_MAX; + else + max_count = __cluster_count > FAT12_MAX ? FAT16_MAX : FAT12_MAX; + + if (__cluster_count > max_count) + return 0; + + if (fat_size) + *fat_size = __fat_size; + if (cluster_count) + *cluster_count = __cluster_count; + + return 1; /* valid */ +} + +/* + * This function is used by MBR partition table parser to avoid + * misinterpretation of FAT filesystem. + */ +int blkid_probe_is_vfat(blkid_probe pr) +{ + struct vfat_super_block *vs; + struct msdos_super_block *ms; + const struct blkid_idmag *mag = NULL; + + if (blkid_probe_get_idmag(pr, &vfat_idinfo, NULL, &mag) || !mag) + return 0; + + ms = blkid_probe_get_sb(pr, mag, struct msdos_super_block); + if (!ms) + return 0; + vs = blkid_probe_get_sb(pr, mag, struct vfat_super_block); + if (!vs) + return 0; + + return fat_valid_superblock(mag, ms, vs, NULL, NULL); +} + +/* FAT label extraction from the root directory taken from Kay + * Sievers's volume_id library */ +static int probe_vfat(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct vfat_super_block *vs; + struct msdos_super_block *ms; + const unsigned char *vol_label = 0; + unsigned char *vol_serno = NULL, vol_label_buf[11]; + uint16_t sector_size = 0, reserved; + uint32_t cluster_count, fat_size; + const char *version = NULL; + + ms = blkid_probe_get_sb(pr, mag, struct msdos_super_block); + if (!ms) + return 0; + vs = blkid_probe_get_sb(pr, mag, struct vfat_super_block); + if (!vs) + return 0; + if (!fat_valid_superblock(mag, ms, vs, &cluster_count, &fat_size)) + return 1; + + sector_size = unaligned_le16(&ms->ms_sector_size); + reserved = le16_to_cpu(ms->ms_reserved); + + if (ms->ms_fat_length) { + /* the label may be an attribute in the root directory */ + uint32_t root_start = (reserved + fat_size) * sector_size; + uint32_t root_dir_entries = unaligned_le16(&vs->vs_dir_entries); + + vol_label = search_fat_label(pr, root_start, root_dir_entries); + if (vol_label) { + memcpy(vol_label_buf, vol_label, 11); + vol_label = vol_label_buf; + } + + if (!vol_label || !memcmp(vol_label, no_name, 11)) + vol_label = ms->ms_label; + vol_serno = ms->ms_serno; + + blkid_probe_set_value(pr, "SEC_TYPE", (unsigned char *) "msdos", + sizeof("msdos")); + + if (cluster_count < FAT12_MAX) + version = "FAT12"; + else if (cluster_count < FAT16_MAX) + version = "FAT16"; + + } else if (vs->vs_fat32_length) { + unsigned char *buf; + uint16_t fsinfo_sect; + int maxloop = 100; + + /* Search the FAT32 root dir for the label attribute */ + uint32_t buf_size = vs->vs_cluster_size * sector_size; + uint32_t start_data_sect = reserved + fat_size; + uint32_t entries = le32_to_cpu(vs->vs_fat32_length) * + sector_size / sizeof(uint32_t); + uint32_t next = le32_to_cpu(vs->vs_root_cluster); + + while (next && next < entries && --maxloop) { + uint32_t next_sect_off; + uint64_t next_off, fat_entry_off; + int count; + + next_sect_off = (next - 2) * vs->vs_cluster_size; + next_off = (start_data_sect + next_sect_off) * + sector_size; + + count = buf_size / sizeof(struct vfat_dir_entry); + + vol_label = search_fat_label(pr, next_off, count); + if (vol_label) { + memcpy(vol_label_buf, vol_label, 11); + vol_label = vol_label_buf; + break; + } + + /* get FAT entry */ + fat_entry_off = (reserved * sector_size) + + (next * sizeof(uint32_t)); + buf = blkid_probe_get_buffer(pr, fat_entry_off, buf_size); + if (buf == NULL) + break; + + /* set next cluster */ + next = le32_to_cpu(*((uint32_t *) buf) & 0x0fffffff); + } + + version = "FAT32"; + + if (!vol_label || !memcmp(vol_label, no_name, 11)) + vol_label = vs->vs_label; + vol_serno = vs->vs_serno; + + /* + * 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->vs_fsinfo_sector); + if (fsinfo_sect) { + struct fat32_fsinfo *fsinfo; + + buf = blkid_probe_get_buffer(pr, + (blkid_loff_t) fsinfo_sect * sector_size, + sizeof(struct fat32_fsinfo)); + if (buf == NULL) + return -1; + + fsinfo = (struct fat32_fsinfo *) buf; + if (memcmp(fsinfo->signature1, "\x52\x52\x61\x41", 4) != 0 && + memcmp(fsinfo->signature1, "\x52\x52\x64\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; + } + } + + if (vol_label && memcmp(vol_label, no_name, 11)) + blkid_probe_set_label(pr, (unsigned char *) vol_label, 11); + + /* We can't just print them as %04X, because they are unaligned */ + if (vol_serno) + blkid_probe_sprintf_uuid(pr, vol_serno, 4, "%02X%02X-%02X%02X", + vol_serno[3], vol_serno[2], vol_serno[1], vol_serno[0]); + if (version) + blkid_probe_set_version(pr, version); + + return 0; +} + + +const struct blkid_idinfo vfat_idinfo = +{ + .name = "vfat", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_vfat, + .magics = + { + { .magic = "MSWIN", .len = 5, .sboff = 0x52 }, + { .magic = "FAT32 ", .len = 8, .sboff = 0x52 }, + { .magic = "MSDOS", .len = 5, .sboff = 0x36 }, + { .magic = "FAT16 ", .len = 8, .sboff = 0x36 }, + { .magic = "FAT12 ", .len = 8, .sboff = 0x36 }, + { .magic = "FAT ", .len = 8, .sboff = 0x36 }, + { .magic = "\353", .len = 1, }, + { .magic = "\351", .len = 1, }, + { .magic = "\125\252", .len = 2, .sboff = 0x1fe }, + { NULL } + } +}; + diff --git a/libblkid/src/superblocks/via_raid.c b/libblkid/src/superblocks/via_raid.c new file mode 100644 index 00000000..20131380 --- /dev/null +++ b/libblkid/src/superblocks/via_raid.c @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2008 Karel Zak + * + * Inspired by libvolume_id by + * Kay Sievers + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "superblocks.h" + +struct via_metadata { + 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; + } __attribute__((packed)) array; + uint32_t serial_checksum[8]; + uint8_t checksum; +} __attribute__((packed)); + +#define VIA_SIGNATURE 0xAA55 + +/* 8 bit checksum on first 50 bytes of metadata. */ +static uint8_t via_checksum(struct via_metadata *v) +{ + uint8_t i = 50, cs = 0; + + while (i--) + cs += ((uint8_t*) v)[i]; + + return cs == v->checksum; +} + +static int probe_viaraid(blkid_probe pr, const struct blkid_idmag *mag) +{ + uint64_t off; + struct via_metadata *v; + + if (pr->size < 0x10000) + return -1; + if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) + return -1; + + off = ((pr->size / 0x200)-1) * 0x200; + + v = (struct via_metadata *) + blkid_probe_get_buffer(pr, + off, + sizeof(struct via_metadata)); + if (!v) + return -1; + if (le16_to_cpu(v->signature) != VIA_SIGNATURE) + return -1; + if (v->version_number > 2) + return -1; + if (!via_checksum(v)) + return -1; + if (blkid_probe_sprintf_version(pr, "%u", v->version_number) != 0) + return -1; + if (blkid_probe_set_magic(pr, off, + sizeof(v->signature), + (unsigned char *) &v->signature)) + return -1; + return 0; +} + +const struct blkid_idinfo viaraid_idinfo = { + .name = "via_raid_member", + .usage = BLKID_USAGE_RAID, + .probefunc = probe_viaraid, + .magics = BLKID_NONE_MAGIC +}; + + diff --git a/libblkid/src/superblocks/vmfs.c b/libblkid/src/superblocks/vmfs.c new file mode 100644 index 00000000..ead09a8d --- /dev/null +++ b/libblkid/src/superblocks/vmfs.c @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2009 Mike Hommey + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include "superblocks.h" + +struct vmfs_fs_info { + uint32_t magic; + uint32_t volume_version; + uint8_t version; + uint8_t uuid[16]; + uint32_t mode; + char label[128]; +} __attribute__ ((__packed__)); + +struct vmfs_volume_info { + uint32_t magic; + uint32_t ver; + uint8_t irrelevant[122]; + uint8_t uuid[16]; +} __attribute__ ((__packed__)); + +static int probe_vmfs_fs(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct vmfs_fs_info *header; + + header = blkid_probe_get_sb(pr, mag, struct vmfs_fs_info); + if (header == NULL) + return -1; + + blkid_probe_sprintf_uuid(pr, (unsigned char *) header->uuid, 16, + "%02x%02x%02x%02x-%02x%02x%02x%02x-" + "%02x%02x-%02x%02x%02x%02x%02x%02x", + header->uuid[3], header->uuid[2], header->uuid[1], + header->uuid[0], header->uuid[7], header->uuid[6], + header->uuid[5], header->uuid[4], header->uuid[9], + header->uuid[8], header->uuid[10], header->uuid[11], + header->uuid[12], header->uuid[13], header->uuid[14], + header->uuid[15]); + + blkid_probe_set_label(pr, (unsigned char *) header->label, + sizeof(header->label)); + blkid_probe_sprintf_version(pr, "%u", header->version); + return 0; +} + +static int probe_vmfs_volume(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct vmfs_volume_info *header; + unsigned char *lvm_uuid; + + header = blkid_probe_get_sb(pr, mag, struct vmfs_volume_info); + if (header == NULL) + return -1; + + blkid_probe_sprintf_value(pr, "UUID_SUB", + "%02x%02x%02x%02x-%02x%02x%02x%02x-" + "%02x%02x-%02x%02x%02x%02x%02x%02x", + header->uuid[3], header->uuid[2], header->uuid[1], + header->uuid[0], header->uuid[7], header->uuid[6], + header->uuid[5], header->uuid[4], header->uuid[9], + header->uuid[8], header->uuid[10], header->uuid[11], + header->uuid[12], header->uuid[13], header->uuid[14], + header->uuid[15]); + blkid_probe_sprintf_version(pr, "%u", le32_to_cpu(header->ver)); + + lvm_uuid = blkid_probe_get_buffer(pr, + 1024 * 1024 /* Start of the volume info */ + + 512 /* Offset to lvm info */ + + 20 /* Offset in lvm info */, 35); + if (lvm_uuid) + blkid_probe_strncpy_uuid(pr, lvm_uuid, 35); + + return 0; +} + +const struct blkid_idinfo vmfs_fs_idinfo = +{ + .name = "VMFS", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_vmfs_fs, + .magics = + { + { .magic = "\x5e\xf1\xab\x2f", .len = 4, .kboff = 2048 }, + { NULL } + } +}; + +const struct blkid_idinfo vmfs_volume_idinfo = +{ + .name = "VMFS_volume_member", + .usage = BLKID_USAGE_RAID, + .probefunc = probe_vmfs_volume, + .magics = + { + { .magic = "\x0d\xd0\x01\xc0", .len = 4, .kboff = 1024 }, + { NULL } + } +}; diff --git a/libblkid/src/superblocks/vxfs.c b/libblkid/src/superblocks/vxfs.c new file mode 100644 index 00000000..fdab85a7 --- /dev/null +++ b/libblkid/src/superblocks/vxfs.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2008 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ + +#include + +#include "superblocks.h" + +struct vxfs_super_block { + uint32_t vs_magic; + int32_t vs_version; +}; + +static int probe_vxfs(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct vxfs_super_block *vxs; + + vxs = blkid_probe_get_sb(pr, mag, struct vxfs_super_block); + if (!vxs) + return -1; + + blkid_probe_sprintf_version(pr, "%u", (unsigned int) vxs->vs_version); + return 0; +} + + +const struct blkid_idinfo vxfs_idinfo = +{ + .name = "vxfs", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_vxfs, + .magics = + { + { .magic = "\365\374\001\245", .len = 4, .kboff = 1 }, + { NULL } + } +}; + diff --git a/libblkid/src/superblocks/xfs.c b/libblkid/src/superblocks/xfs.c new file mode 100644 index 00000000..1399fe13 --- /dev/null +++ b/libblkid/src/superblocks/xfs.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) 1999 by Andries Brouwer + * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o + * Copyright (C) 2001 by Andreas Dilger + * Copyright (C) 2004 Kay Sievers + * Copyright (C) 2008 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "superblocks.h" + +struct xfs_super_block { + unsigned char xs_magic[4]; + uint32_t xs_blocksize; + uint64_t xs_dblocks; + uint64_t xs_rblocks; + uint32_t xs_dummy1[2]; + unsigned char xs_uuid[16]; + uint32_t xs_dummy2[15]; + char xs_fname[12]; + uint32_t xs_dummy3[2]; + uint64_t xs_icount; + uint64_t xs_ifree; + uint64_t xs_fdblocks; +} __attribute__((packed)); + +static int probe_xfs(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct xfs_super_block *xs; + + xs = blkid_probe_get_sb(pr, mag, struct xfs_super_block); + if (!xs) + return -1; + + if (strlen(xs->xs_fname)) + blkid_probe_set_label(pr, (unsigned char *) xs->xs_fname, + sizeof(xs->xs_fname)); + blkid_probe_set_uuid(pr, xs->xs_uuid); + return 0; +} + +const struct blkid_idinfo xfs_idinfo = +{ + .name = "xfs", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_xfs, + .magics = + { + { .magic = "XFSB", .len = 4 }, + { NULL } + } +}; + diff --git a/libblkid/src/superblocks/zfs.c b/libblkid/src/superblocks/zfs.c new file mode 100644 index 00000000..af5264d4 --- /dev/null +++ b/libblkid/src/superblocks/zfs.c @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2009-2010 by Andreas Dilger + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "superblocks.h" + +#define VDEV_LABEL_UBERBLOCK (128 * 1024ULL) +#define VDEV_LABEL_NVPAIR ( 16 * 1024ULL) +#define VDEV_LABEL_SIZE (256 * 1024ULL) + +/* #include */ +#define UBERBLOCK_MAGIC 0x00bab10c /* oo-ba-bloc! */ +struct zfs_uberblock { + uint64_t ub_magic; /* UBERBLOCK_MAGIC */ + uint64_t ub_version; /* SPA_VERSION */ + uint64_t ub_txg; /* txg of last sync */ + uint64_t ub_guid_sum; /* sum of all vdev guids */ + uint64_t ub_timestamp; /* UTC time of last sync */ + char ub_rootbp; /* MOS objset_phys_t */ +} __attribute__((packed)); + +#define ZFS_TRIES 64 +#define ZFS_WANT 4 + +#define DATA_TYPE_UINT64 8 +#define DATA_TYPE_STRING 9 + +struct nvpair { + uint32_t nvp_size; + uint32_t nvp_unkown; + uint32_t nvp_namelen; + char nvp_name[0]; /* aligned to 4 bytes */ + /* aligned ptr array for string arrays */ + /* aligned array of data for value */ +}; + +struct nvstring { + uint32_t nvs_type; + uint32_t nvs_elem; + uint32_t nvs_strlen; + unsigned char nvs_string[0]; +}; + +struct nvuint64 { + uint32_t nvu_type; + uint32_t nvu_elem; + uint64_t nvu_value; +}; + +struct nvlist { + uint32_t nvl_unknown[3]; + struct nvpair nvl_nvpair; +}; + +#define nvdebug(fmt, ...) do { } while(0) +/*#define nvdebug(fmt, a...) printf(fmt, ##a)*/ + +static void zfs_extract_guid_name(blkid_probe pr, loff_t offset) +{ + struct nvlist *nvl; + struct nvpair *nvp; + int left = 4096; + int found = 0; + + offset = (offset & ~(VDEV_LABEL_SIZE - 1)) + VDEV_LABEL_NVPAIR; + + /* Note that we currently assume that the desired fields are within + * the first 4k (left) of the nvlist. This is true for all pools + * I've seen, and simplifies this code somewhat, because we don't + * have to handle an nvpair crossing a buffer boundary. */ + nvl = (struct nvlist *)blkid_probe_get_buffer(pr, offset, left); + if (nvl == NULL) + return; + + nvdebug("zfs_extract: nvlist offset %llu\n", offset); + + nvp = &nvl->nvl_nvpair; + while (left > sizeof(*nvp) && nvp->nvp_size != 0 && found < 3) { + int avail; /* tracks that name/value data fits in nvp_size */ + int namesize; + + nvp->nvp_size = be32_to_cpu(nvp->nvp_size); + nvp->nvp_namelen = be32_to_cpu(nvp->nvp_namelen); + avail = nvp->nvp_size - nvp->nvp_namelen - sizeof(*nvp); + + nvdebug("left %u, nvp_size %u\n", left, nvp->nvp_size); + if (left < nvp->nvp_size || avail < 0) + break; + + namesize = (nvp->nvp_namelen + 3) & ~3; + + nvdebug("nvlist: size %u, namelen %u, name %*s\n", + nvp->nvp_size, nvp->nvp_namelen, nvp->nvp_namelen, + nvp->nvp_name); + if (strncmp(nvp->nvp_name, "name", nvp->nvp_namelen) == 0) { + struct nvstring *nvs = (void *)(nvp->nvp_name+namesize); + + nvs->nvs_type = be32_to_cpu(nvs->nvs_type); + nvs->nvs_strlen = be32_to_cpu(nvs->nvs_strlen); + avail -= nvs->nvs_strlen + sizeof(*nvs); + nvdebug("nvstring: type %u string %*s\n", nvs->nvs_type, + nvs->nvs_strlen, nvs->nvs_string); + if (nvs->nvs_type == DATA_TYPE_STRING && avail >= 0) + blkid_probe_set_label(pr, nvs->nvs_string, + nvs->nvs_strlen); + found++; + } else if (strncmp(nvp->nvp_name, "guid", + nvp->nvp_namelen) == 0) { + struct nvuint64 *nvu = (void *)(nvp->nvp_name+namesize); + uint64_t nvu_value; + + memcpy(&nvu_value, &nvu->nvu_value, sizeof(nvu_value)); + nvu->nvu_type = be32_to_cpu(nvu->nvu_type); + nvu_value = be64_to_cpu(nvu_value); + avail -= sizeof(*nvu); + nvdebug("nvuint64: type %u value %"PRIu64"\n", + nvu->nvu_type, nvu_value); + if (nvu->nvu_type == DATA_TYPE_UINT64 && avail >= 0) + blkid_probe_sprintf_value(pr, "UUID_SUB", + "%"PRIu64, nvu_value); + found++; + } else if (strncmp(nvp->nvp_name, "pool_guid", + nvp->nvp_namelen) == 0) { + struct nvuint64 *nvu = (void *)(nvp->nvp_name+namesize); + uint64_t nvu_value; + + memcpy(&nvu_value, &nvu->nvu_value, sizeof(nvu_value)); + nvu->nvu_type = be32_to_cpu(nvu->nvu_type); + nvu_value = be64_to_cpu(nvu_value); + avail -= sizeof(*nvu); + nvdebug("nvuint64: type %u value %"PRIu64"\n", + nvu->nvu_type, nvu_value); + if (nvu->nvu_type == DATA_TYPE_UINT64 && avail >= 0) + blkid_probe_sprintf_uuid(pr, (unsigned char *) + &nvu_value, + sizeof(nvu_value), + "%"PRIu64, nvu_value); + found++; + } + left -= nvp->nvp_size; + nvp = (struct nvpair *)((char *)nvp + nvp->nvp_size); + } +} + +#define zdebug(fmt, ...) do {} while(0) +/*#define zdebug(fmt, a...) printf(fmt, ##a)*/ + +/* ZFS has 128x1kB host-endian root blocks, stored in 2 areas at the start + * of the disk, and 2 areas at the end of the disk. Check only some of them... + * #4 (@ 132kB) is the first one written on a new filesystem. */ +static int probe_zfs(blkid_probe pr, const struct blkid_idmag *mag) +{ + uint64_t swab_magic = swab64(UBERBLOCK_MAGIC); + struct zfs_uberblock *ub; + int swab_endian; + loff_t offset; + int tried; + int found; + + zdebug("probe_zfs\n"); + /* Look for at least 4 uberblocks to ensure a positive match */ + for (tried = found = 0, offset = VDEV_LABEL_UBERBLOCK; + tried < ZFS_TRIES && found < ZFS_WANT; + tried++, offset += 4096) { + /* also try the second uberblock copy */ + if (tried == (ZFS_TRIES / 2)) + offset = VDEV_LABEL_SIZE + VDEV_LABEL_UBERBLOCK; + + ub = (struct zfs_uberblock *) + blkid_probe_get_buffer(pr, offset, + sizeof(struct zfs_uberblock)); + if (ub == NULL) + return -1; + + if (ub->ub_magic == UBERBLOCK_MAGIC) + found++; + + if ((swab_endian = (ub->ub_magic == swab_magic))) + found++; + + zdebug("probe_zfs: found %s-endian uberblock at %llu\n", + swab_endian ? "big" : "little", offset >> 10); + } + + if (found < 4) + return -1; + + /* If we found the 4th uberblock, then we will have exited from the + * scanning loop immediately, and ub will be a valid uberblock. */ + blkid_probe_sprintf_version(pr, "%" PRIu64, swab_endian ? + swab64(ub->ub_version) : ub->ub_version); + + zfs_extract_guid_name(pr, offset); + + if (blkid_probe_set_magic(pr, offset, + sizeof(ub->ub_magic), + (unsigned char *) &ub->ub_magic)) + return -1; + + return 0; +} + +const struct blkid_idinfo zfs_idinfo = +{ + .name = "zfs_member", + .usage = BLKID_USAGE_RAID, + .probefunc = probe_zfs, + .minsz = 64 * 1024 * 1024, + .magics = BLKID_NONE_MAGIC +}; + diff --git a/libblkid/src/tag.c b/libblkid/src/tag.c new file mode 100644 index 00000000..0dbe1ff5 --- /dev/null +++ b/libblkid/src/tag.c @@ -0,0 +1,474 @@ +/* + * tag.c - allocation/initialization/free routines for tag structs + * + * Copyright (C) 2001 Andreas Dilger + * Copyright (C) 2003 Theodore Ts'o + * + * %Begin-Header% + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * %End-Header% + */ + +#include +#include +#include +#include + +#include "blkidP.h" + +static blkid_tag blkid_new_tag(void) +{ + blkid_tag tag; + + if (!(tag = (blkid_tag) calloc(1, sizeof(struct blkid_struct_tag)))) + return NULL; + + INIT_LIST_HEAD(&tag->bit_tags); + INIT_LIST_HEAD(&tag->bit_names); + + return tag; +} + +#ifdef CONFIG_BLKID_DEBUG +void blkid_debug_dump_tag(blkid_tag tag) +{ + if (!tag) { + printf(" tag: NULL\n"); + return; + } + + printf(" tag: %s=\"%s\"\n", tag->bit_name, tag->bit_val); +} +#endif + +void blkid_free_tag(blkid_tag tag) +{ + if (!tag) + return; + + DBG(DEBUG_TAG, printf(" freeing tag %s=%s\n", tag->bit_name, + tag->bit_val ? tag->bit_val : "(NULL)")); + DBG(DEBUG_TAG, blkid_debug_dump_tag(tag)); + + list_del(&tag->bit_tags); /* list of tags for this device */ + list_del(&tag->bit_names); /* list of tags with this type */ + + free(tag->bit_name); + free(tag->bit_val); + + free(tag); +} + +/* + * Find the desired tag on a device. If value is NULL, then the + * first such tag is returned, otherwise return only exact tag if found. + */ +blkid_tag blkid_find_tag_dev(blkid_dev dev, const char *type) +{ + struct list_head *p; + + if (!dev || !type) + return NULL; + + list_for_each(p, &dev->bid_tags) { + blkid_tag tmp = list_entry(p, struct blkid_struct_tag, + bit_tags); + + if (!strcmp(tmp->bit_name, type)) + return tmp; + } + return NULL; +} + +extern int blkid_dev_has_tag(blkid_dev dev, const char *type, + const char *value) +{ + blkid_tag tag; + + if (!dev || !type) + return -1; + + tag = blkid_find_tag_dev(dev, type); + if (!value) + return (tag != NULL); + if (!tag || strcmp(tag->bit_val, value)) + return 0; + return 1; +} + +/* + * Find the desired tag type in the cache. + * We return the head tag for this tag type. + */ +static blkid_tag blkid_find_head_cache(blkid_cache cache, const char *type) +{ + blkid_tag head = NULL, tmp; + struct list_head *p; + + if (!cache || !type) + return NULL; + + list_for_each(p, &cache->bic_tags) { + tmp = list_entry(p, struct blkid_struct_tag, bit_tags); + if (!strcmp(tmp->bit_name, type)) { + DBG(DEBUG_TAG, + printf(" found cache tag head %s\n", type)); + head = tmp; + break; + } + } + return head; +} + +/* + * Set a tag on an existing device. + * + * If value is NULL, then delete the tagsfrom the device. + */ +int blkid_set_tag(blkid_dev dev, const char *name, + const char *value, const int vlength) +{ + blkid_tag t = 0, head = 0; + char *val = 0; + char **dev_var = 0; + + if (!dev || !name) + return -BLKID_ERR_PARAM; + + if (!(val = blkid_strndup(value, vlength)) && value) + return -BLKID_ERR_MEM; + + /* + * Certain common tags are linked directly to the device struct + * We need to know what they are before we do anything else because + * the function name parameter might get freed later on. + */ + if (!strcmp(name, "TYPE")) + dev_var = &dev->bid_type; + else if (!strcmp(name, "LABEL")) + dev_var = &dev->bid_label; + else if (!strcmp(name, "UUID")) + dev_var = &dev->bid_uuid; + + t = blkid_find_tag_dev(dev, name); + if (!value) { + if (t) + blkid_free_tag(t); + } else if (t) { + if (!strcmp(t->bit_val, val)) { + /* Same thing, exit */ + free(val); + return 0; + } + free(t->bit_val); + t->bit_val = val; + } else { + /* Existing tag not present, add to device */ + if (!(t = blkid_new_tag())) + goto errout; + t->bit_name = blkid_strdup(name); + t->bit_val = val; + t->bit_dev = dev; + + list_add_tail(&t->bit_tags, &dev->bid_tags); + + if (dev->bid_cache) { + head = blkid_find_head_cache(dev->bid_cache, + t->bit_name); + if (!head) { + head = blkid_new_tag(); + if (!head) + goto errout; + + DBG(DEBUG_TAG, + printf(" creating new cache tag head %s\n", name)); + head->bit_name = blkid_strdup(name); + if (!head->bit_name) + goto errout; + list_add_tail(&head->bit_tags, + &dev->bid_cache->bic_tags); + } + list_add_tail(&t->bit_names, &head->bit_names); + } + } + + /* Link common tags directly to the device struct */ + if (dev_var) + *dev_var = val; + + if (dev->bid_cache) + dev->bid_cache->bic_flags |= BLKID_BIC_FL_CHANGED; + return 0; + +errout: + if (t) + blkid_free_tag(t); + else + free(val); + if (head) + blkid_free_tag(head); + return -BLKID_ERR_MEM; +} + + +/* + * Parse a "NAME=value" string. This is slightly different than + * parse_token, because that will end an unquoted value at a space, while + * this will assume that an unquoted value is the rest of the token (e.g. + * if we are passed an already quoted string from the command-line we don't + * have to both quote and escape quote so that the quotes make it to + * us). + * + * Returns 0 on success, and -1 on failure. + */ +int blkid_parse_tag_string(const char *token, char **ret_type, char **ret_val) +{ + char *name, *value, *cp; + + DBG(DEBUG_TAG, printf("trying to parse '%s' as a tag\n", token)); + + if (!token || !(cp = strchr(token, '='))) + return -1; + + name = blkid_strdup(token); + if (!name) + return -1; + value = name + (cp - token); + *value++ = '\0'; + if (*value == '"' || *value == '\'') { + char c = *value++; + if (!(cp = strrchr(value, c))) + goto errout; /* missing closing quote */ + *cp = '\0'; + } + value = blkid_strdup(value); + if (!value) + goto errout; + + *ret_type = name; + *ret_val = value; + + return 0; + +errout: + free(name); + return -1; +} + +/* + * Tag iteration routines for the public libblkid interface. + * + * These routines do not expose the list.h implementation, which are a + * contamination of the namespace, and which force us to reveal far, far + * too much of our internal implemenation. I'm not convinced I want + * to keep list.h in the long term, anyway. It's fine for kernel + * programming, but performance is not the #1 priority for this + * library, and I really don't like the tradeoff of type-safety for + * performance for this application. [tytso:20030125.2007EST] + */ + +/* + * This series of functions iterate over all tags in a device + */ +#define TAG_ITERATE_MAGIC 0x01a5284c + +struct blkid_struct_tag_iterate { + int magic; + blkid_dev dev; + struct list_head *p; +}; + +extern blkid_tag_iterate blkid_tag_iterate_begin(blkid_dev dev) +{ + blkid_tag_iterate iter; + + iter = malloc(sizeof(struct blkid_struct_tag_iterate)); + if (iter) { + iter->magic = TAG_ITERATE_MAGIC; + iter->dev = dev; + iter->p = dev->bid_tags.next; + } + return (iter); +} + +/* + * Return 0 on success, -1 on error + */ +extern int blkid_tag_next(blkid_tag_iterate iter, + const char **type, const char **value) +{ + blkid_tag tag; + + *type = 0; + *value = 0; + if (!iter || iter->magic != TAG_ITERATE_MAGIC || + iter->p == &iter->dev->bid_tags) + return -1; + tag = list_entry(iter->p, struct blkid_struct_tag, bit_tags); + *type = tag->bit_name; + *value = tag->bit_val; + iter->p = iter->p->next; + return 0; +} + +extern void blkid_tag_iterate_end(blkid_tag_iterate iter) +{ + if (!iter || iter->magic != TAG_ITERATE_MAGIC) + return; + iter->magic = 0; + free(iter); +} + +/* + * This function returns a device which matches a particular + * type/value pair. If there is more than one device that matches the + * search specification, it returns the one with the highest priority + * value. This allows us to give preference to EVMS or LVM devices. + */ +extern blkid_dev blkid_find_dev_with_tag(blkid_cache cache, + const char *type, + const char *value) +{ + blkid_tag head; + blkid_dev dev; + int pri; + struct list_head *p; + int probe_new = 0; + + if (!cache || !type || !value) + return NULL; + + blkid_read_cache(cache); + + DBG(DEBUG_TAG, printf("looking for %s=%s in cache\n", type, value)); + +try_again: + pri = -1; + dev = 0; + head = blkid_find_head_cache(cache, type); + + if (head) { + list_for_each(p, &head->bit_names) { + blkid_tag tmp = list_entry(p, struct blkid_struct_tag, + bit_names); + + if (!strcmp(tmp->bit_val, value) && + (tmp->bit_dev->bid_pri > pri) && + !access(tmp->bit_dev->bid_name, F_OK)) { + dev = tmp->bit_dev; + pri = dev->bid_pri; + } + } + } + if (dev && !(dev->bid_flags & BLKID_BID_FL_VERIFIED)) { + dev = blkid_verify(cache, dev); + if (!dev || (dev && (dev->bid_flags & BLKID_BID_FL_VERIFIED))) + goto try_again; + } + + if (!dev && !probe_new) { + if (blkid_probe_all_new(cache) < 0) + return NULL; + probe_new++; + goto try_again; + } + + if (!dev && !(cache->bic_flags & BLKID_BIC_FL_PROBED)) { + if (blkid_probe_all(cache) < 0) + return NULL; + goto try_again; + } + return dev; +} + +#ifdef TEST_PROGRAM +#ifdef HAVE_GETOPT_H +#include +#else +extern char *optarg; +extern int optind; +#endif + +void usage(char *prog) +{ + fprintf(stderr, "Usage: %s [-f blkid_file] [-m debug_mask] device " + "[type value]\n", + prog); + fprintf(stderr, "\tList all tags for a device and exit\n"); + exit(1); +} + +int main(int argc, char **argv) +{ + blkid_tag_iterate iter; + blkid_cache cache = NULL; + blkid_dev dev; + int c, ret, found; + int flags = BLKID_DEV_FIND; + char *tmp; + char *file = NULL; + char *devname = NULL; + char *search_type = NULL; + char *search_value = NULL; + const char *type, *value; + + while ((c = getopt (argc, argv, "m:f:")) != EOF) + switch (c) { + case 'f': + file = optarg; + break; + case 'm': + { + int mask = strtoul (optarg, &tmp, 0); + if (*tmp) { + fprintf(stderr, "Invalid debug mask: %s\n", + optarg); + exit(1); + } + blkid_init_debug(mask); + break; + } + case '?': + usage(argv[0]); + } + if (argc > optind) + devname = argv[optind++]; + if (argc > optind) + search_type = argv[optind++]; + if (argc > optind) + search_value = argv[optind++]; + if (!devname || (argc != optind)) + usage(argv[0]); + + if ((ret = blkid_get_cache(&cache, file)) != 0) { + fprintf(stderr, "%s: error creating cache (%d)\n", + argv[0], ret); + exit(1); + } + + dev = blkid_get_dev(cache, devname, flags); + if (!dev) { + fprintf(stderr, "%s: Can not find device in blkid cache\n", + devname); + exit(1); + } + if (search_type) { + found = blkid_dev_has_tag(dev, search_type, search_value); + printf("Device %s: (%s, %s) %s\n", blkid_dev_devname(dev), + search_type, search_value ? search_value : "NULL", + found ? "FOUND" : "NOT FOUND"); + return(!found); + } + printf("Device %s...\n", blkid_dev_devname(dev)); + + iter = blkid_tag_iterate_begin(dev); + while (blkid_tag_next(iter, &type, &value) == 0) { + printf("\tTag %s has value %s\n", type, value); + } + blkid_tag_iterate_end(iter); + + blkid_put_cache(cache); + return (0); +} +#endif diff --git a/libblkid/src/topology/Makefile.am b/libblkid/src/topology/Makefile.am new file mode 100644 index 00000000..775fea3e --- /dev/null +++ b/libblkid/src/topology/Makefile.am @@ -0,0 +1,17 @@ +include $(top_srcdir)/config/include-Makefile.am + +AM_CPPFLAGS += -I$(ul_libblkid_incdir) -I$(ul_libblkid_srcdir) +libblkid_topology_la_LIBADD = + +noinst_LTLIBRARIES = libblkid_topology.la +libblkid_topology_la_SOURCES = topology.c \ + topology.h + +if LINUX +libblkid_topology_la_SOURCES += sysfs.c \ + dm.c \ + lvm.c \ + ioctl.c \ + md.c \ + evms.c +endif diff --git a/libblkid/src/topology/dm.c b/libblkid/src/topology/dm.c new file mode 100644 index 00000000..8f33911c --- /dev/null +++ b/libblkid/src/topology/dm.c @@ -0,0 +1,137 @@ +/* + * device-mapper (dm) topology + * -- this is fallback for old systems where the topology information is not + * exported by sysfs + * + * Copyright (C) 2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "topology.h" + +static int is_dm_device(dev_t devno) +{ + return blkid_driver_has_major("device-mapper", major(devno)); +} + +static int probe_dm_tp(blkid_probe pr, const struct blkid_idmag *mag) +{ + const char *paths[] = { + "/usr/local/sbin/dmsetup", + "/usr/sbin/dmsetup", + "/sbin/dmsetup" + }; + int i, dmpipe[] = { -1, -1 }, stripes, stripesize; + char *cmd = NULL; + FILE *stream = NULL; + long long offset, size; + dev_t devno = blkid_probe_get_devno(pr); + + if (!devno) + goto nothing; /* probably not a block device */ + if (!is_dm_device(devno)) + goto nothing; + + for (i = 0; i < ARRAY_SIZE(paths); i++) { + struct stat sb; + if (stat(paths[i], &sb) == 0) { + cmd = (char *) paths[i]; + break; + } + } + + if (!cmd) + goto nothing; + if (pipe(dmpipe) < 0) { + DBG(DEBUG_LOWPROBE, + printf("Failed to open pipe: errno=%d", errno)); + goto nothing; + } + + switch (fork()) { + case 0: + { + char *dmargv[7], maj[16], min[16]; + + /* Plumbing */ + close(dmpipe[0]); + + if (dmpipe[1] != STDOUT_FILENO) + dup2(dmpipe[1], STDOUT_FILENO); + + /* The libblkid library could linked with setuid programs */ + if (setgid(getgid()) < 0) + exit(1); + if (setuid(getuid()) < 0) + exit(1); + + snprintf(maj, sizeof(maj), "%d", major(devno)); + snprintf(min, sizeof(min), "%d", minor(devno)); + + dmargv[0] = cmd; + dmargv[1] = "table"; + dmargv[2] = "-j"; + dmargv[3] = maj; + dmargv[4] = "-m"; + dmargv[5] = min; + dmargv[6] = NULL; + + execv(dmargv[0], dmargv); + + DBG(DEBUG_LOWPROBE, + printf("Failed to execute %s: errno=%d", cmd, errno)); + exit(1); + } + case -1: + DBG(DEBUG_LOWPROBE, + printf("Failed to forking: errno=%d", errno)); + goto nothing; + default: + break; + } + + stream = fdopen(dmpipe[0], "r"); + if (!stream) + goto nothing; + + i = fscanf(stream, "%lld %lld striped %d %d ", + &offset, &size, &stripes, &stripesize); + if (i != 4) + goto nothing; + + blkid_topology_set_minimum_io_size(pr, stripesize << 9); + blkid_topology_set_optimal_io_size(pr, (stripes * stripesize) << 9); + + fclose(stream); + close(dmpipe[1]); + return 0; + +nothing: + if (stream) + fclose(stream); + else if (dmpipe[0] != -1) + close(dmpipe[0]); + if (dmpipe[1] != -1) + close(dmpipe[1]); + return 1; +} + +const struct blkid_idinfo dm_tp_idinfo = +{ + .name = "dm", + .probefunc = probe_dm_tp, + .magics = BLKID_NONE_MAGIC +}; + diff --git a/libblkid/src/topology/evms.c b/libblkid/src/topology/evms.c new file mode 100644 index 00000000..a30d8df7 --- /dev/null +++ b/libblkid/src/topology/evms.c @@ -0,0 +1,76 @@ +/* + * Evms topology + * -- this is fallback for old systems where the toplogy information is not + * exported by sysfs + * + * Copyright (C) 2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "topology.h" + +#define EVMS_MAJOR 117 + +#ifndef _IOT__IOTBASE_u_int32_t +#define _IOT__IOTBASE_u_int32_t IOT_SIMPLE(uint32_t) +#endif +#define _IOT_evms_stripe_info _IOT (_IOTS(uint32_t), 2, 0, 0, 0, 0) +#define EVMS_GET_STRIPE_INFO _IOR(EVMS_MAJOR, 0xF0, struct evms_stripe_info) + +struct evms_stripe_info { + uint32_t size; /* stripe unit 512-byte blocks */ + uint32_t width; /* the number of stripe members or RAID data disks */ +} evms_stripe_info; + +static int is_evms_device(dev_t devno) +{ + if (major(devno) == EVMS_MAJOR) + return 1; + return blkid_driver_has_major("evms", major(devno)); +} + +static int probe_evms_tp(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct evms_stripe_info evms; + dev_t devno = blkid_probe_get_devno(pr); + + if (!devno) + goto nothing; /* probably not a block device */ + + if (!is_evms_device(devno)) + goto nothing; + + memset(&evms, 0, sizeof(evms)); + + if (ioctl(pr->fd, EVMS_GET_STRIPE_INFO, &evms)) + goto nothing; + + blkid_topology_set_minimum_io_size(pr, evms.size << 9); + blkid_topology_set_optimal_io_size(pr, (evms.size * evms.width) << 9); + + return 0; + +nothing: + return 1; +} + +const struct blkid_idinfo evms_tp_idinfo = +{ + .name = "evms", + .probefunc = probe_evms_tp, + .magics = BLKID_NONE_MAGIC +}; + diff --git a/libblkid/src/topology/ioctl.c b/libblkid/src/topology/ioctl.c new file mode 100644 index 00000000..73c18ec9 --- /dev/null +++ b/libblkid/src/topology/ioctl.c @@ -0,0 +1,73 @@ +/* + * ioctl based topology -- gathers topology information + * + * Copyright (C) 2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "topology.h" + +/* + * ioctl topology values + */ +static struct topology_val { + + long ioc; + + /* functions to set probing result */ + int (*set_ulong)(blkid_probe, unsigned long); + int (*set_int)(blkid_probe, int); + +} topology_vals[] = { + { BLKALIGNOFF, NULL, blkid_topology_set_alignment_offset }, + { BLKIOMIN, blkid_topology_set_minimum_io_size }, + { BLKIOOPT, blkid_topology_set_optimal_io_size }, + { BLKPBSZGET, blkid_topology_set_physical_sector_size } + /* we read BLKSSZGET in topology.c */ +}; + +static int probe_ioctl_tp(blkid_probe pr, const struct blkid_idmag *mag) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(topology_vals); i++) { + struct topology_val *val = &topology_vals[i]; + int rc = 1; + unsigned int data; + + if (ioctl(pr->fd, val->ioc, &data) == -1) + goto nothing; + + if (val->set_int) + rc = val->set_int(pr, (int) data); + else + rc = val->set_ulong(pr, (unsigned long) data); + if (rc) + goto err; + } + + return 0; +nothing: + return 1; +err: + return -1; +} + +const struct blkid_idinfo ioctl_tp_idinfo = +{ + .name = "ioctl", + .probefunc = probe_ioctl_tp, + .magics = BLKID_NONE_MAGIC +}; + diff --git a/libblkid/src/topology/lvm.c b/libblkid/src/topology/lvm.c new file mode 100644 index 00000000..54438b0a --- /dev/null +++ b/libblkid/src/topology/lvm.c @@ -0,0 +1,148 @@ +/* + * lvm topology + * -- this is fallback for old systems where the topology information is not + * exported by sysfs + * + * Copyright (C) 2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "topology.h" + +#ifndef LVM_BLK_MAJOR +# define LVM_BLK_MAJOR 58 +#endif + +static int is_lvm_device(dev_t devno) +{ + if (major(devno) == LVM_BLK_MAJOR) + return 1; + return blkid_driver_has_major("lvm", major(devno)); +} + +static int probe_lvm_tp(blkid_probe pr, const struct blkid_idmag *mag) +{ + const char *paths[] = { + "/usr/local/sbin/lvdisplay", + "/usr/sbin/lvdisplay", + "/sbin/lvdisplay" + }; + int i, lvpipe[] = { -1, -1 }, stripes = 0, stripesize = 0; + FILE *stream = NULL; + char *cmd = NULL, *devname = NULL, buf[1024]; + dev_t devno = blkid_probe_get_devno(pr); + + if (!devno) + goto nothing; /* probably not a block device */ + if (!is_lvm_device(devno)) + goto nothing; + + for (i = 0; i < ARRAY_SIZE(paths); i++) { + struct stat sb; + if (stat(paths[i], &sb) == 0) { + cmd = (char *) paths[i]; + break; + } + } + + if (!cmd) + goto nothing; + + devname = blkid_devno_to_devname(devno); + if (!devname) + goto nothing; + + if (pipe(lvpipe) < 0) { + DBG(DEBUG_LOWPROBE, + printf("Failed to open pipe: errno=%d", errno)); + goto nothing; + } + + switch (fork()) { + case 0: + { + char *lvargv[3]; + + /* Plumbing */ + close(lvpipe[0]); + + if (lvpipe[1] != STDOUT_FILENO) + dup2(lvpipe[1], STDOUT_FILENO); + + /* The libblkid library could linked with setuid programs */ + if (setgid(getgid()) < 0) + exit(1); + if (setuid(getuid()) < 0) + exit(1); + + lvargv[0] = cmd; + lvargv[1] = devname; + lvargv[2] = NULL; + + execv(lvargv[0], lvargv); + + DBG(DEBUG_LOWPROBE, + printf("Failed to execute %s: errno=%d", cmd, errno)); + exit(1); + } + case -1: + DBG(DEBUG_LOWPROBE, + printf("Failed to forking: errno=%d", errno)); + goto nothing; + default: + break; + } + + stream = fdopen(lvpipe[0], "r"); + if (!stream) + goto nothing; + + while (fgets(buf, sizeof(buf), stream) != NULL) { + if (!strncmp(buf, "Stripes", 7)) + sscanf(buf, "Stripes %d", &stripes); + + if (!strncmp(buf, "Stripe size", 11)) + sscanf(buf, "Stripe size (KByte) %d", &stripesize); + } + + if (!stripes) + goto nothing; + + blkid_topology_set_minimum_io_size(pr, stripesize << 10); + blkid_topology_set_optimal_io_size(pr, (stripes * stripesize) << 10); + + free(devname); + fclose(stream); + close(lvpipe[1]); + return 0; + +nothing: + free(devname); + if (stream) + fclose(stream); + else if (lvpipe[0] != -1) + close(lvpipe[0]); + if (lvpipe[1] != -1) + close(lvpipe[1]); + return 1; +} + +const struct blkid_idinfo lvm_tp_idinfo = +{ + .name = "lvm", + .probefunc = probe_lvm_tp, + .magics = BLKID_NONE_MAGIC +}; + diff --git a/libblkid/src/topology/md.c b/libblkid/src/topology/md.c new file mode 100644 index 00000000..d7275edd --- /dev/null +++ b/libblkid/src/topology/md.c @@ -0,0 +1,151 @@ +/* + * Linux Software RAID (md) topology + * -- this is fallback for old systems where the topology information is not + * exported by sysfs + * + * Copyright (C) 2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "topology.h" + +#ifndef MD_MAJOR +#define MD_MAJOR 9 +#endif + +#ifndef _IOT__IOTBASE_uint32_t +#define _IOT__IOTBASE_uint32_t IOT_SIMPLE(uint32_t) +#endif +#define _IOT_md_array_info _IOT (_IOTS(uint32_t), 18, 0, 0, 0, 0) +#define GET_ARRAY_INFO _IOR (MD_MAJOR, 0x11, struct md_array_info) + +struct md_array_info { + /* + * Generic constant information + */ + uint32_t major_version; + uint32_t minor_version; + uint32_t patch_version; + 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; + + /* + * Generic state information + */ + uint32_t utime; /* 0 Superblock update time */ + uint32_t state; /* 1 State bits (clean, ...) */ + uint32_t active_disks; /* 2 Number of currently active disks */ + uint32_t working_disks; /* 3 Number of working disks */ + uint32_t failed_disks; /* 4 Number of failed disks */ + uint32_t spare_disks; /* 5 Number of spare disks */ + + /* + * Personality information + */ + uint32_t layout; /* 0 the array's physical layout */ + uint32_t chunk_size; /* 1 chunk size in bytes */ + +}; + +static int is_md_device(dev_t devno) +{ + if (major(devno) == MD_MAJOR) + return 1; + return blkid_driver_has_major("md", major(devno)); +} + +static int probe_md_tp(blkid_probe pr, const struct blkid_idmag *mag) +{ + int fd = -1; + dev_t disk = 0; + dev_t devno = blkid_probe_get_devno(pr); + struct md_array_info md; + + if (!devno) + goto nothing; /* probably not a block device */ + + if (!is_md_device(devno)) + goto nothing; + + if (blkid_devno_to_wholedisk(devno, NULL, 0, &disk)) + goto nothing; + + if (disk == devno) + fd = pr->fd; + else { + char *diskpath = blkid_devno_to_devname(disk); + + if (!diskpath) + goto nothing; + + fd = open(diskpath, O_RDONLY); + free(diskpath); + + if (fd == -1) + goto nothing; + } + + memset(&md, 0, sizeof(md)); + + if (ioctl(fd, GET_ARRAY_INFO, &md)) + goto nothing; + + if (fd != pr->fd) + close(fd); + + /* + * Ignore levels we don't want aligned (e.g. linear) + * and deduct disk(s) from stripe width on RAID4/5/6 + */ + switch (md.level) { + case 6: + md.raid_disks--; + /* fallthrough */ + case 5: + case 4: + md.raid_disks--; + /* fallthrough */ + case 1: + case 0: + case 10: + break; + default: + goto nothing; + } + + blkid_topology_set_minimum_io_size(pr, md.chunk_size); + blkid_topology_set_optimal_io_size(pr, md.chunk_size * md.raid_disks); + + return 0; + +nothing: + if (fd != -1 && fd != pr->fd) + close(fd); + return 1; +} + +const struct blkid_idinfo md_tp_idinfo = +{ + .name = "md", + .probefunc = probe_md_tp, + .magics = BLKID_NONE_MAGIC +}; + diff --git a/libblkid/src/topology/sysfs.c b/libblkid/src/topology/sysfs.c new file mode 100644 index 00000000..588fc7a1 --- /dev/null +++ b/libblkid/src/topology/sysfs.c @@ -0,0 +1,116 @@ +/* + * sysfs based topology -- gathers topology information from Linux sysfs + * + * Copyright (C) 2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * + * For more information see Linux kernel Documentation/ABI/testing/sysfs-block. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sysfs.h" +#include "topology.h" + +/* + * Sysfs topology values (since 2.6.31, May 2009). + */ +static struct topology_val { + + /* /sys/dev/block/:/ */ + const char *attr; + + /* functions to set probing resut */ + int (*set_ulong)(blkid_probe, unsigned long); + int (*set_int)(blkid_probe, int); + +} topology_vals[] = { + { "alignment_offset", NULL, blkid_topology_set_alignment_offset }, + { "queue/minimum_io_size", blkid_topology_set_minimum_io_size }, + { "queue/optimal_io_size", blkid_topology_set_optimal_io_size }, + { "queue/physical_block_size", blkid_topology_set_physical_sector_size }, +}; + +static int probe_sysfs_tp(blkid_probe pr, const struct blkid_idmag *mag) +{ + dev_t dev, disk = 0; + int i, count = 0, rc; + struct sysfs_cxt sysfs, parent; + + dev = blkid_probe_get_devno(pr); + if (!dev || sysfs_init(&sysfs, dev, NULL) != 0) + return 1; + + rc = 1; /* nothing (default) */ + + for (i = 0; i < ARRAY_SIZE(topology_vals); i++) { + struct topology_val *val = &topology_vals[i]; + int ok = sysfs_has_attribute(&sysfs, val->attr); + + rc = 1; /* nothing */ + + if (!ok) { + if (!disk) { + /* + * Read atrributes from "disk" if the current + * device is a partition. + */ + disk = blkid_probe_get_wholedisk_devno(pr); + if (disk && disk != dev) { + if (sysfs_init(&parent, disk, NULL) != 0) + goto done; + + sysfs.parent = &parent; + ok = sysfs_has_attribute(&sysfs, + val->attr); + } + } + if (!ok) + continue; /* attrinute does not exist */ + } + + if (val->set_ulong) { + uint64_t data; + + if (sysfs_read_u64(&sysfs, val->attr, &data) != 0) + continue; + rc = val->set_ulong(pr, (unsigned long) data); + + } else if (val->set_int) { + int64_t data; + + if (sysfs_read_s64(&sysfs, val->attr, &data) != 0) + continue; + rc = val->set_int(pr, (int) data); + } + + if (rc < 0) + goto done; /* error */ + if (rc == 0) + count++; + } + +done: + sysfs_deinit(&sysfs); + if (disk) + sysfs_deinit(&parent); + if (count) + return 0; /* success */ + return rc; /* error or nothing */ +} + +const struct blkid_idinfo sysfs_tp_idinfo = +{ + .name = "sysfs", + .probefunc = probe_sysfs_tp, + .magics = BLKID_NONE_MAGIC +}; + diff --git a/libblkid/src/topology/topology.c b/libblkid/src/topology/topology.c new file mode 100644 index 00000000..27dc755f --- /dev/null +++ b/libblkid/src/topology/topology.c @@ -0,0 +1,369 @@ +/* + * topology - gathers information about device topology + * + * Copyright 2009 Red Hat, Inc. All rights reserved. + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ + +#include +#include +#include +#include + +#include "topology.h" + +/** + * SECTION:topology + * @title: Topology information + * @short_description: block device topology information. + * + * The topology chain provides details about Linux block devices, for more + * information see: + * + * Linux kernel Documentation/ABI/testing/sysfs-block + * + * NAME=value (tags) interface is enabled by blkid_probe_enable_topology(), + * and provides: + * + * @LOGICAL_SECTOR_SIZE: this is the smallest unit the storage device can + * address. It is typically 512 bytes. + * + * @PHYSICAL_SECTOR_SIZE: this is the smallest unit a physical storage device + * can write atomically. It is usually the same as the + * logical sector size but may be bigger. + * + * @MINIMUM_IO_SIZE: minimum size which is the device's preferred unit of I/O. + * For RAID arrays it is often the stripe chunk size. + * + * @OPTIMAL_IO_SIZE: usually the stripe width for RAID or zero. For RAID arrays + * it is usually the stripe width or the internal track size. + * + * @ALIGNMENT_OFFSET: indicates how many bytes the beginning of the device is + * offset from the disk's natural alignment. + * + * The NAME=value tags are not defined when the corresponding topology value + * is zero. The MINIMUM_IO_SIZE should be always defined if kernel provides + * topology information. + * + * Binary interface: + * + * blkid_probe_get_topology() + * + * blkid_topology_get_'VALUENAME'() + */ +static int topology_probe(blkid_probe pr, struct blkid_chain *chn); +static void topology_free(blkid_probe pr, void *data); +static int topology_is_complete(blkid_probe pr); +static int topology_set_logical_sector_size(blkid_probe pr); + +/* + * Binary interface + */ +struct blkid_struct_topology { + unsigned long alignment_offset; + unsigned long minimum_io_size; + unsigned long optimal_io_size; + unsigned long logical_sector_size; + unsigned long physical_sector_size; +}; + +/* + * Topology chain probing functions + */ +static const struct blkid_idinfo *idinfos[] = +{ +#ifdef __linux__ + &ioctl_tp_idinfo, + &sysfs_tp_idinfo, + &md_tp_idinfo, + &dm_tp_idinfo, + &lvm_tp_idinfo, + &evms_tp_idinfo +#endif +}; + + +/* + * Driver definition + */ +const struct blkid_chaindrv topology_drv = { + .id = BLKID_CHAIN_TOPLGY, + .name = "topology", + .dflt_enabled = FALSE, + .idinfos = idinfos, + .nidinfos = ARRAY_SIZE(idinfos), + .probe = topology_probe, + .safeprobe = topology_probe, + .free_data = topology_free +}; + +/** + * blkid_probe_enable_topology: + * @pr: probe + * @enable: TRUE/FALSE + * + * Enables/disables the topology probing for non-binary interface. + * + * Returns: 0 on success, or -1 in case of error. + */ +int blkid_probe_enable_topology(blkid_probe pr, int enable) +{ + if (!pr) + return -1; + pr->chains[BLKID_CHAIN_TOPLGY].enabled = enable; + return 0; +} + +/** + * blkid_probe_get_topology: + * @pr: probe + * + * This is a binary interface for topology values. See also blkid_topology_* + * functions. + * + * This function is independent on blkid_do_[safe,full]probe() and + * blkid_probe_enable_topology() calls. + * + * WARNING: the returned object will be overwritten by the next + * blkid_probe_get_topology() call for the same @pr. If you want to + * use more blkid_topopogy objects in the same time you have to create + * more blkid_probe handlers (see blkid_new_probe()). + * + * TODO: add blkid_ref() and blkid_unref() to allows to use blkid_topology + * independently on libblkid probing stuff. + * + * Returns: blkid_topopogy, or NULL in case of error. + */ +blkid_topology blkid_probe_get_topology(blkid_probe pr) +{ + return (blkid_topology) blkid_probe_get_binary_data(pr, + &pr->chains[BLKID_CHAIN_TOPLGY]); +} + +/* + * The blkid_do_probe() backend. + */ +static int topology_probe(blkid_probe pr, struct blkid_chain *chn) +{ + int i = 0; + + if (!pr || chn->idx < -1) + return -1; + + if (!S_ISBLK(pr->mode)) + return -1; /* nothing, works with block devices only */ + + if (chn->binary) { + DBG(DEBUG_LOWPROBE, printf("initialize topology binary data\n")); + + if (chn->data) + /* reset binary data */ + memset(chn->data, 0, + sizeof(struct blkid_struct_topology)); + else { + chn->data = calloc(1, + sizeof(struct blkid_struct_topology)); + if (!chn->data) + return -1; + } + } + + blkid_probe_chain_reset_vals(pr, chn); + + DBG(DEBUG_LOWPROBE, + printf("--> starting probing loop [TOPOLOGY idx=%d]\n", + chn->idx)); + + i = chn->idx + 1; + + for ( ; i < ARRAY_SIZE(idinfos); i++) { + const struct blkid_idinfo *id = idinfos[i]; + + chn->idx = i; + + if (id->probefunc) { + DBG(DEBUG_LOWPROBE, printf( + "%s: call probefunc()\n", id->name)); + if (id->probefunc(pr, NULL) != 0) + continue; + } + + if (!topology_is_complete(pr)) + continue; + + /* generic for all probing drivers */ + topology_set_logical_sector_size(pr); + + DBG(DEBUG_LOWPROBE, + printf("<-- leaving probing loop (type=%s) [TOPOLOGY idx=%d]\n", + id->name, chn->idx)); + return 0; + } + + DBG(DEBUG_LOWPROBE, + printf("<-- leaving probing loop (failed) [TOPOLOGY idx=%d]\n", + chn->idx)); + return 1; +} + +static void topology_free(blkid_probe pr, void *data) +{ + free(data); +} + +static int topology_set_value(blkid_probe pr, const char *name, + size_t structoff, unsigned long data) +{ + struct blkid_chain *chn = blkid_probe_get_chain(pr); + + if (!chn) + return -1; + if (!data) + return 0; /* ignore zeros */ + + if (chn->binary) { + unsigned long *v = + (unsigned long *) (chn->data + structoff); + *v = data; + return 0; + } + return blkid_probe_sprintf_value(pr, name, "%llu", data); +} + +/* the topology info is complete when we have at least "minimum_io_size" which + * is provided by all blkid topology drivers */ +static int topology_is_complete(blkid_probe pr) +{ + struct blkid_chain *chn = blkid_probe_get_chain(pr); + + if (!chn) + return FALSE; + + if (chn->binary && chn->data) { + blkid_topology tp = (blkid_topology) chn->data; + if (tp->minimum_io_size) + return TRUE; + } + + return __blkid_probe_lookup_value(pr, "MINIMUM_IO_SIZE") ? TRUE : FALSE; +} + +int blkid_topology_set_alignment_offset(blkid_probe pr, int val) +{ + unsigned long xval; + + /* Welcome to Hell. The kernel is able to return -1 as an + * alignment_offset if no compatible sizes and alignments + * exist for stacked devices. + * + * There is no way how libblkid caller can respond to the value -1, so + * we will hide this corner case... + * + * (TODO: maybe we can export an extra boolean value 'misaligned' rather + * then complete hide this problem.) + */ + xval = val < 0 ? 0 : val; + + return topology_set_value(pr, + "ALIGNMENT_OFFSET", + offsetof(struct blkid_struct_topology, alignment_offset), + xval); +} + +int blkid_topology_set_minimum_io_size(blkid_probe pr, unsigned long val) +{ + return topology_set_value(pr, + "MINIMUM_IO_SIZE", + offsetof(struct blkid_struct_topology, minimum_io_size), + val); +} + +int blkid_topology_set_optimal_io_size(blkid_probe pr, unsigned long val) +{ + return topology_set_value(pr, + "OPTIMAL_IO_SIZE", + offsetof(struct blkid_struct_topology, optimal_io_size), + val); +} + +/* BLKSSZGET is provided on all systems since 2.3.3 -- so we don't have to + * waste time with sysfs. + */ +static int topology_set_logical_sector_size(blkid_probe pr) +{ + unsigned long val = blkid_probe_get_sectorsize(pr); + + if (!val) + return -1; + + return topology_set_value(pr, + "LOGICAL_SECTOR_SIZE", + offsetof(struct blkid_struct_topology, logical_sector_size), + val); +} + +int blkid_topology_set_physical_sector_size(blkid_probe pr, unsigned long val) +{ + return topology_set_value(pr, + "PHYSICAL_SECTOR_SIZE", + offsetof(struct blkid_struct_topology, physical_sector_size), + val); +} + +/** + * blkid_topology_get_alignment_offset: + * @tp: topology + * + * Returns: alignment offset in bytes or 0. + */ +unsigned long blkid_topology_get_alignment_offset(blkid_topology tp) +{ + return tp ? tp->alignment_offset : 0; +} + +/** + * blkid_topology_get_minimum_io_size: + * @tp: topology + * + * Returns: minimum io size in bytes or 0. + */ +unsigned long blkid_topology_get_minimum_io_size(blkid_topology tp) +{ + return tp ? tp->minimum_io_size : 0; +} + +/** + * blkid_topology_get_optimal_io_size + * @tp: topology + * + * Returns: optimal io size in bytes or 0. + */ +unsigned long blkid_topology_get_optimal_io_size(blkid_topology tp) +{ + return tp ? tp->optimal_io_size : 0; +} + +/** + * blkid_topology_get_logical_sector_size + * @tp: topology + * + * Returns: logical sector size (BLKSSZGET ioctl) in bytes or 0. + */ +unsigned long blkid_topology_get_logical_sector_size(blkid_topology tp) +{ + return tp ? tp->logical_sector_size : 0; +} + +/** + * blkid_topology_get_physical_sector_size + * @tp: topology + * + * Returns: logical sector size (BLKSSZGET ioctl) in bytes or 0. + */ +unsigned long blkid_topology_get_physical_sector_size(blkid_topology tp) +{ + return tp ? tp->physical_sector_size : 0; +} + diff --git a/libblkid/src/topology/topology.h b/libblkid/src/topology/topology.h new file mode 100644 index 00000000..6d2f4334 --- /dev/null +++ b/libblkid/src/topology/topology.h @@ -0,0 +1,24 @@ +#ifndef BLKID_TOPOLOGY_H +#define BLKID_TOPOLOGY_H + +#include "blkidP.h" + +extern int blkid_topology_set_alignment_offset(blkid_probe pr, int val); +extern int blkid_topology_set_minimum_io_size(blkid_probe pr, unsigned long val); +extern int blkid_topology_set_optimal_io_size(blkid_probe pr, unsigned long val); +extern int blkid_topology_set_physical_sector_size(blkid_probe pr, unsigned long val); + +/* + * topology probers + */ +#ifdef __linux__ +extern const struct blkid_idinfo ioctl_tp_idinfo; +extern const struct blkid_idinfo md_tp_idinfo; +extern const struct blkid_idinfo evms_tp_idinfo; +extern const struct blkid_idinfo sysfs_tp_idinfo; +extern const struct blkid_idinfo dm_tp_idinfo; +extern const struct blkid_idinfo lvm_tp_idinfo; +#endif + +#endif /* BLKID_TOPOLOGY_H */ + diff --git a/libblkid/src/tst_types.c b/libblkid/src/tst_types.c new file mode 100644 index 00000000..ecbc0321 --- /dev/null +++ b/libblkid/src/tst_types.c @@ -0,0 +1,63 @@ +/* + * This testing program makes sure the stdint.h header file + * + * Copyright (C) 2006 by Theodore Ts'o. + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Public + * License. + * %End-Header% + */ + +#include +#include + +#include +#include + +int main(int argc, char **argv) +{ + if (sizeof(uint8_t) != 1) { + printf("Sizeof(uint8_t) is %d should be 1\n", + (int)sizeof(uint8_t)); + exit(1); + } + if (sizeof(int8_t) != 1) { + printf("Sizeof(int8_t) is %d should be 1\n", + (int)sizeof(int8_t)); + exit(1); + } + if (sizeof(uint16_t) != 2) { + printf("Sizeof(uint16_t) is %d should be 2\n", + (int)sizeof(uint16_t)); + exit(1); + } + if (sizeof(int16_t) != 2) { + printf("Sizeof(int16_t) is %d should be 2\n", + (int)sizeof(int16_t)); + exit(1); + } + if (sizeof(uint32_t) != 4) { + printf("Sizeof(uint32_t) is %d should be 4\n", + (int)sizeof(uint32_t)); + exit(1); + } + if (sizeof(int32_t) != 4) { + printf("Sizeof(int32_t) is %d should be 4\n", + (int)sizeof(int32_t)); + exit(1); + } + if (sizeof(uint64_t) != 8) { + printf("Sizeof(uint64_t) is %d should be 8\n", + (int)sizeof(uint64_t)); + exit(1); + } + if (sizeof(int64_t) != 8) { + printf("Sizeof(int64_t) is %d should be 8\n", + (int)sizeof(int64_t)); + exit(1); + } + printf("The stdint.h types are correct.\n"); + exit(0); +} + diff --git a/libblkid/src/verify.c b/libblkid/src/verify.c new file mode 100644 index 00000000..a0cb3fea --- /dev/null +++ b/libblkid/src/verify.c @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2008 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_STAT_H +#include +#endif +#ifdef HAVE_ERRNO_H +#include +#endif +#include "blkidP.h" + +static void blkid_probe_to_tags(blkid_probe pr, blkid_dev dev) +{ + const char *data; + const char *name; + int nvals, n; + size_t len; + + nvals = blkid_probe_numof_values(pr); + + for (n = 0; n < nvals; n++) { + if (blkid_probe_get_value(pr, n, &name, &data, &len) == 0) + blkid_set_tag(dev, name, data, len); + } +} + +/* + * Verify that the data in dev is consistent with what is on the actual + * block device (using the devname field only). Normally this will be + * called when finding items in the cache, but for long running processes + * is also desirable to revalidate an item before use. + * + * If we are unable to revalidate the data, we return the old data and + * do not set the BLKID_BID_FL_VERIFIED flag on it. + */ +blkid_dev blkid_verify(blkid_cache cache, blkid_dev dev) +{ + struct stat st; + time_t diff, now; + char *fltr[2]; + int fd; + + if (!dev) + return NULL; + + now = time(0); + diff = now - dev->bid_time; + + if (stat(dev->bid_name, &st) < 0) { + DBG(DEBUG_PROBE, + printf("blkid_verify: error %s (%d) while " + "trying to stat %s\n", strerror(errno), errno, + dev->bid_name)); + open_err: + if ((errno == EPERM) || (errno == EACCES) || (errno == ENOENT)) { + /* We don't have read permission, just return cache data. */ + DBG(DEBUG_PROBE, printf("returning unverified data for %s\n", + dev->bid_name)); + return dev; + } + blkid_free_dev(dev); + return NULL; + } + + if (now >= dev->bid_time && +#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC + (st.st_mtime < dev->bid_time || + (st.st_mtime == dev->bid_time && + st.st_mtim.tv_nsec / 1000 <= dev->bid_utime)) && +#else + st.st_mtime <= dev->bid_time && +#endif + (diff < BLKID_PROBE_MIN || + (dev->bid_flags & BLKID_BID_FL_VERIFIED && + diff < BLKID_PROBE_INTERVAL))) + return dev; + +#ifndef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC + DBG(DEBUG_PROBE, + printf("need to revalidate %s (cache time %lu, stat time %lu,\n\t" + "time since last check %lu)\n", + dev->bid_name, (unsigned long)dev->bid_time, + (unsigned long)st.st_mtime, (unsigned long)diff)); +#else + DBG(DEBUG_PROBE, + printf("need to revalidate %s (cache time %lu.%lu, stat time %lu.%lu,\n\t" + "time since last check %lu)\n", + dev->bid_name, + (unsigned long)dev->bid_time, (unsigned long)dev->bid_utime, + (unsigned long)st.st_mtime, (unsigned long)st.st_mtim.tv_nsec / 1000, + (unsigned long)diff)); +#endif + + if (!cache->probe) { + cache->probe = blkid_new_probe(); + if (!cache->probe) { + blkid_free_dev(dev); + return NULL; + } + } + + fd = open(dev->bid_name, O_RDONLY); + if (fd < 0) { + DBG(DEBUG_PROBE, printf("blkid_verify: error %s (%d) while " + "opening %s\n", strerror(errno), errno, + dev->bid_name)); + goto open_err; + } + + if (blkid_probe_set_device(cache->probe, fd, 0, 0)) { + /* failed to read the device */ + close(fd); + blkid_free_dev(dev); + return NULL; + } + + blkid_probe_enable_superblocks(cache->probe, TRUE); + + blkid_probe_set_superblocks_flags(cache->probe, + BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID | + BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE); + + /* + * If we already know the type, then try that first. + */ + if (dev->bid_type) { + blkid_tag_iterate iter; + const char *type, *value; + + fltr[0] = dev->bid_type; + fltr[1] = NULL; + + blkid_probe_filter_superblocks_type(cache->probe, + BLKID_FLTR_ONLYIN, fltr); + + if (!blkid_do_probe(cache->probe)) + goto found_type; + blkid_probe_invert_superblocks_filter(cache->probe); + + /* + * Zap the device filesystem information and try again + */ + DBG(DEBUG_PROBE, + printf("previous fs type %s not valid, " + "trying full probe\n", dev->bid_type)); + iter = blkid_tag_iterate_begin(dev); + while (blkid_tag_next(iter, &type, &value) == 0) + blkid_set_tag(dev, type, 0, 0); + blkid_tag_iterate_end(iter); + } + + /* + * Probe for all types. + */ + if (blkid_do_safeprobe(cache->probe)) { + /* found nothing or error */ + blkid_free_dev(dev); + dev = NULL; + } + +found_type: + if (dev) { +#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC + struct timeval tv; + if (!gettimeofday(&tv, NULL)) { + dev->bid_time = tv.tv_sec; + dev->bid_utime = tv.tv_usec; + } else +#endif + dev->bid_time = time(0); + + dev->bid_devno = st.st_rdev; + dev->bid_flags |= BLKID_BID_FL_VERIFIED; + cache->bic_flags |= BLKID_BIC_FL_CHANGED; + + blkid_probe_to_tags(cache->probe, dev); + + DBG(DEBUG_PROBE, printf("%s: devno 0x%04llx, type %s\n", + dev->bid_name, (long long)st.st_rdev, dev->bid_type)); + } + + blkid_reset_probe(cache->probe); + blkid_probe_reset_superblocks_filter(cache->probe); + close(fd); + return dev; +} + +#ifdef TEST_PROGRAM +int main(int argc, char **argv) +{ + blkid_dev dev; + blkid_cache cache; + int ret; + + if (argc != 2) { + fprintf(stderr, "Usage: %s device\n" + "Probe a single device to determine type\n", argv[0]); + exit(1); + } + if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) { + fprintf(stderr, "%s: error creating cache (%d)\n", + argv[0], ret); + exit(1); + } + dev = blkid_get_dev(cache, argv[1], BLKID_DEV_NORMAL); + if (!dev) { + printf("%s: %s has an unsupported type\n", argv[0], argv[1]); + return (1); + } + printf("TYPE='%s'\n", dev->bid_type ? dev->bid_type : "(null)"); + if (dev->bid_label) + printf("LABEL='%s'\n", dev->bid_label); + if (dev->bid_uuid) + printf("UUID='%s'\n", dev->bid_uuid); + + blkid_free_dev(dev); + return (0); +} +#endif diff --git a/libblkid/src/version.c b/libblkid/src/version.c new file mode 100644 index 00000000..4c7fa06c --- /dev/null +++ b/libblkid/src/version.c @@ -0,0 +1,62 @@ +/* + * version.c --- Return the version of the blkid library + * + * Copyright (C) 2004 Theodore Ts'o. + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Public + * License. + * %End-Header% + */ + +#if HAVE_UNISTD_H +#include +#endif +#include +#include +#include + +#include "blkid.h" + +/* LIBBLKID_* defined in the global config.h */ +static const char *lib_version = LIBBLKID_VERSION; /* release version */ +static const char *lib_date = LIBBLKID_DATE; + +/** + * blkid_parse_version_string: + * @ver_string: version string (e.g. "2.16.0") + * + * Returns: release version code. + */ +int blkid_parse_version_string(const char *ver_string) +{ + const char *cp; + int version = 0; + + for (cp = ver_string; *cp; cp++) { + if (*cp == '.') + continue; + if (!isdigit(*cp)) + break; + version = (version * 10) + (*cp - '0'); + } + return version; +} + +/** + * blkid_get_library_version: + * @ver_string: returns relese version (!= SONAME version) + * @date_string: returns date + * + * Returns: release version code. + */ +int blkid_get_library_version(const char **ver_string, + const char **date_string) +{ + if (ver_string) + *ver_string = lib_version; + if (date_string) + *date_string = lib_date; + + return blkid_parse_version_string(lib_version); +} diff --git a/shlibs/blkid/.gitignore b/shlibs/blkid/.gitignore deleted file mode 100644 index 6ffe4a9e..00000000 --- a/shlibs/blkid/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -*.sh -bin/blkid -bin/findfs -test_* -blkid.h diff --git a/shlibs/blkid/COPYING.libblkid b/shlibs/blkid/COPYING.libblkid deleted file mode 100644 index cf9b6b99..00000000 --- a/shlibs/blkid/COPYING.libblkid +++ /dev/null @@ -1,510 +0,0 @@ - - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations -below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. -^L - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it -becomes a de-facto standard. To achieve this, non-free programs must -be allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. -^L - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control -compilation and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. -^L - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. -^L - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at least - three years, to give the same user the materials specified in - Subsection 6a, above, for a charge no more than the cost of - performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. -^L - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. -^L - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply, and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License -may add an explicit geographical distribution limitation excluding those -countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. -^L - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS -^L - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms -of the ordinary General Public License). - - To apply these terms, attach the following notices to the library. -It is safest to attach them to the start of each source file to most -effectively convey the exclusion of warranty; and each file should -have at least the "copyright" line and a pointer to where the full -notice is found. - - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or -your school, if any, to sign a "copyright disclaimer" for the library, -if necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James - Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/shlibs/blkid/Makefile.am b/shlibs/blkid/Makefile.am deleted file mode 100644 index 59362cfe..00000000 --- a/shlibs/blkid/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ -include $(top_srcdir)/config/include-Makefile.am - -SUBDIRS = src samples - -if ENABLE_GTK_DOC -SUBDIRS += docs -endif - -# pkg-config stuff -pkgconfigdir = $(usrlib_execdir)/pkgconfig -pkgconfig_DATA = blkid.pc - -dist_man_MANS = libblkid.3 - -EXTRA_DIST = COPYING.libblkid README.blkid blkid.pc.in libblkid.3 - diff --git a/shlibs/blkid/README.blkid b/shlibs/blkid/README.blkid deleted file mode 100644 index 4fa9be1f..00000000 --- a/shlibs/blkid/README.blkid +++ /dev/null @@ -1,78 +0,0 @@ -libblkid - a library to handle device identification and token extraction - -Basic usage is as follows - there are two normal usage patterns: - -For cases where a program wants information about multiple devices, or -expects to be doing multiple token searches, the program should -directly initialize cache file via (second parameter is cache -filename, NULL = default): - - blkid_cache cache = NULL; - if (blkid_get_cache(&cache, NULL) < 0) - /* error reading the cache file, not really fatal */ - -Note that if no cache file exists, an empty cache struct is still -allocated. Usage of libblkid functions will use the cache to avoid -needless device scans. - -The model of the blkid cache is that each device has a number of -attributes that can be associated with it. Currently the attributes -which are supported (and set) by blkid are: - - TYPE filesystem type - UUID filesystem uuid - LABEL filesystem label - - -How to use libblkid? Normally, you either want to find a device with -a specific NAME=value token, or you want to output token(s) from a -device. To find a device that matches a following attribute, you -simply call the blkid_get_devname() function: - - if ((devname = blkid_get_devname(cache, attribute_name, value))) { - /* do something with devname */ - string_free(devname); - } - -The cache parameter is optional; if it is NULL, then the blkid library -will load the default blkid.tab cache file, and then release the cache -before function call returns. The return value is an allocated string -which holds the resulting device name (if it is found). If the value -is NULL, then attribute_name is parsed as if it were -"="; if it cannot be so parsed, then the -original attribute_name is returned in a copied allocated string. -This is a convenience to allow user programs to want to translate user -input, whether it is of the form: "/dev/hda1", "LABEL=root", -"UUID=082D-26E3", and get back a device name that it can use. - -Alternatively, of course, the programmer can pass an attribute name of -"LABEL", and value of "root", if that is more convenient. - -Another common usage is to retrieve the value of a specific attribute -for a particular device. This can be used to determine the filesystem -type, or label, or uuid for a particular device: - - if ((value = blkid_get_tag_value(cache, attribute_name, devname))) { - /* do something with value */ - string_free(value); - } - -If a program needs to call multiple blkid functions, then passing in a -cache value of NULL is not recommended, since the /etc/blkid.tab file -will be repeatedly parsed over and over again, with memory allocated -and deallocated. To initialize the blkid cache, blkid_get_cache() -function is used: - - if (blkid_get_cache(&cache, NULL) < 0) - goto errout; - -The second parameter of blkid_get_cache (if non-zero) is the alternate -filename of the blkid cache file (where the default is -/etc/blkid.tab). Normally, programs should just pass in NULL. - -If you have called blkid_get_cache(), you should call blkid_put_cache() -when you are done using the blkid library functions. This will save the -cache to the blkid.tab file, if you have write access to the file. It -will also free all associated devices and tags: - - blkid_put_cache(cache); diff --git a/shlibs/blkid/blkid.pc.in b/shlibs/blkid/blkid.pc.in deleted file mode 100644 index 40ec8a9d..00000000 --- a/shlibs/blkid/blkid.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@usrlib_execdir@ -includedir=@includedir@ - -Name: blkid -Description: Block device id library -Version: @LIBBLKID_VERSION@ -Requires.private: uuid -Cflags: -I${includedir}/blkid -Libs: -L${libdir} -lblkid diff --git a/shlibs/blkid/docs/.gitignore b/shlibs/blkid/docs/.gitignore deleted file mode 100644 index 917c8481..00000000 --- a/shlibs/blkid/docs/.gitignore +++ /dev/null @@ -1,17 +0,0 @@ -*.args -*.bak -*-decl-list.txt -*-decl.txt -*.hierarchy -html/* -*.interfaces -*-overrides.txt -*.prerequisites -*.signals -*.stamp -tmpl/* -*-undeclared.txt -*-undocumented.txt -*-unused.txt -version.xml -xml/* diff --git a/shlibs/blkid/docs/Makefile.am b/shlibs/blkid/docs/Makefile.am deleted file mode 100644 index 8ef3b239..00000000 --- a/shlibs/blkid/docs/Makefile.am +++ /dev/null @@ -1,101 +0,0 @@ -include $(top_srcdir)/config/include-Makefile.am - -## Process this file with automake to produce Makefile.in - -# We require automake 1.10 at least. -AUTOMAKE_OPTIONS = 1.10 - -# This is a blank Makefile.am for using gtk-doc. -# Copy this to your project's API docs directory and modify the variables to -# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples -# of using the various options. - -# The name of the module, e.g. 'glib'. -DOC_MODULE=libblkid - -# Uncomment for versioned docs and specify the version of the module, e.g. '2'. -#DOC_MODULE_VERSION=2 - -# The top-level SGML file. You can change this if you want to. -DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml - -# The directory containing the source code. Relative to $(srcdir). -# gtk-doc will search all .c & .h files beneath here for inline comments -# documenting the functions and macros. -# e.g. DOC_SOURCE_DIR=../../../gtk -DOC_SOURCE_DIR=../src - -# Extra options to pass to gtkdoc-scangobj. Not normally needed. -SCANGOBJ_OPTIONS= - -# Extra options to supply to gtkdoc-scan. -# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" -SCAN_OPTIONS= - -# Extra options to supply to gtkdoc-mkdb. -# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml -MKDB_OPTIONS=--sgml-mode --output-format=xml --name-space blkid - -# Extra options to supply to gtkdoc-mktmpl -# e.g. MKTMPL_OPTIONS=--only-section-tmpl -MKTMPL_OPTIONS= - -# Extra options to supply to gtkdoc-mkhtml -MKHTML_OPTIONS= - -# Extra options to supply to gtkdoc-fixref. Not normally needed. -# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html -FIXXREF_OPTIONS= - -# Used for dependencies. The docs will be rebuilt if any of these change. -# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h -# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c -HFILE_GLOB=$(ul_libblkid_incdir)/blkid.h -CFILE_GLOB=$(ul_libblkid_srcdir)/*.c - -# Extra header to include when scanning, which are not under DOC_SOURCE_DIR -# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h -EXTRA_HFILES= - -# Header files to ignore when scanning. Use base file name, no paths -# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h -IGNORE_HFILES=blkidP.h list.h partitions.h superblocks.h topology.h aix.h dos.h - -# Images to copy into HTML directory. -# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png -HTML_IMAGES= - -# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). -# e.g. content_files=running.sgml building.sgml changes-2.0.sgml -content_files = $(builddir)/version.xml $(srcdir)/libblkid-config.xml - -# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded -# These files must be listed here *and* in content_files -# e.g. expand_content_files=running.sgml -expand_content_files= - -# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. -# Only needed if you are using gtkdoc-scangobj to dynamically query widget -# signals and properties. -# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) -# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) -GTKDOC_CFLAGS= -GTKDOC_LIBS= - -# This includes the standard gtk-doc make rules, copied by gtkdocize. -include $(top_srcdir)/config/gtk-doc.make - -# Other files to distribute -# e.g. EXTRA_DIST += version.xml.in -EXTRA_DIST += version.xml.in - -# Files not to distribute -# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types -# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt -#DISTCLEANFILES += - -# Comment this out if you want your docs-status tested during 'make check' -if ENABLE_GTK_DOC -#TESTS_ENVIRONMENT = cd $(srcsrc) -#TESTS = $(GTKDOC_CHECK) -endif diff --git a/shlibs/blkid/docs/libblkid-config.xml b/shlibs/blkid/docs/libblkid-config.xml deleted file mode 100644 index 89fbb7f1..00000000 --- a/shlibs/blkid/docs/libblkid-config.xml +++ /dev/null @@ -1,57 +0,0 @@ - - -]> - - -Config file -3 -LIBBLKID Library - - - -Config file -config file to control paths and basic library behavior - - - -Description - -The standard location of the -/etc/blkid.conf config file can be overridden by the environment variable -BLKID_CONF. The following options control the libblkid library: - - - - - SEND_UEVENT=yes|not - - Sends uevent when /dev/disk/by-{label,uuid}/ - symlink does not match with LABEL or UUID on the device. Default is "yes". - - - - CACHE_FILE=path - - Overrides the standard location of the cache file. This - setting can be overridden by the environment variable BLKID_FILE. Default is - /etc/blkid.tab. - - - - EVALUATE=method - - Defines LABEL and UUID evaluation method(s). Currently, - the libblkid library supports "udev" and "scan" methods. More than one methods - may be specified in a comma separated list. Default is "udev,scan". The "udev" - method uses udev /dev/disk/by-* symlinks and the "scan" method scans all - block devices from the /proc/partitions file. - - - - - - - diff --git a/shlibs/blkid/docs/libblkid-docs.xml b/shlibs/blkid/docs/libblkid-docs.xml deleted file mode 100644 index c99192a9..00000000 --- a/shlibs/blkid/docs/libblkid-docs.xml +++ /dev/null @@ -1,69 +0,0 @@ - - -]> - - - libblkid Reference Manual - for libblkid version &version; - - 2009 - Karel Zak <kzak@redhat.com> - - - - - libblkid Overview - - -The libblkid library is used to identify block devices (disks) as to their -content (e.g. filesystem type, partitions) as well as extracting additional -information such as filesystem labels/volume names, partitions, unique -identifiers/serial numbers, etc. A common use is to allow use of LABEL= and -UUID= tags instead of hard-coding specific block device names into -configuration files. - - -The libblkid librray -was written by Andreas Dilger for the ext2 filesystem utilties, with input -from Ted Ts'o. The library was subsequently heavily modified by Ted Ts'o. - - -The low-level probing code, topology and partitions support was written -by Karel Zak. Currently, the library is mainatned by Karel Zak. - - -The library is part of the util-linux package since version 2.15 and is -available from ftp://ftp.kernel.org/pub/linux/utils/util-linux/. - - - - - - - High-level - - - - - - Low-level - - - - - - - - Common utils - - - - - - API Index - - - diff --git a/shlibs/blkid/docs/libblkid-sections.txt b/shlibs/blkid/docs/libblkid-sections.txt deleted file mode 100644 index 47675f4a..00000000 --- a/shlibs/blkid/docs/libblkid-sections.txt +++ /dev/null @@ -1,145 +0,0 @@ -
-evaluate -blkid_evaluate_tag -
- -
-cache -blkid_cache -blkid_gc_cache -blkid_get_cache -blkid_put_cache -blkid_probe_all -blkid_probe_all_new -blkid_verify -
- -
-search -blkid_dev -blkid_dev_devname -blkid_dev_has_tag -blkid_dev_iterate -blkid_dev_iterate_begin -blkid_dev_iterate_end -blkid_dev_next -blkid_dev_set_search -blkid_find_dev_with_tag -blkid_get_dev -blkid_get_devname -blkid_get_tag_value -blkid_tag_iterate -blkid_tag_iterate_begin -blkid_tag_iterate_end -blkid_tag_next -
- -
-lowprobe -blkid_probe -blkid_free_probe -blkid_new_probe -blkid_new_probe_from_filename -blkid_probe_get_devno -blkid_probe_get_sectorsize -blkid_probe_get_sectors -blkid_probe_get_size -blkid_probe_set_device -blkid_reset_probe -
- -
-lowprobe-tags -blkid_do_fullprobe -blkid_do_probe -blkid_do_safeprobe - -blkid_probe_get_value -blkid_probe_has_value -blkid_probe_lookup_value -blkid_probe_numof_values -
- -
-partitions -blkid_partlist -blkid_partition -blkid_parttable -blkid_probe_enable_partitions -blkid_probe_set_partitions_flags - -blkid_known_pttype - -blkid_partition_get_name -blkid_partition_get_partno -blkid_partition_get_size -blkid_partition_get_start -blkid_partition_get_table -blkid_partition_get_type -blkid_partition_get_type_string -blkid_partition_get_uuid -blkid_partition_is_extended -blkid_partition_is_logical -blkid_partition_is_primary - -blkid_partlist_get_partition -blkid_partlist_numof_partitions - -blkid_parttable_get_offset -blkid_parttable_get_parent -blkid_parttable_get_type - -blkid_probe_get_partitions -
- -
-superblocks -blkid_probe_enable_superblocks - -blkid_known_fstype - -blkid_probe_filter_superblocks_type -blkid_probe_filter_superblocks_usage -blkid_probe_invert_superblocks_filter -blkid_probe_reset_superblocks_filter -blkid_probe_set_superblocks_flags - -blkid_probe_reset_filter -blkid_probe_filter_types -blkid_probe_filter_usage -blkid_probe_invert_filter -blkid_probe_set_request -
- -
-topology -blkid_topology -blkid_probe_enable_topology - -blkid_probe_get_topology -blkid_topology_get_alignment_offset -blkid_topology_get_logical_sector_size -blkid_topology_get_minimum_io_size -blkid_topology_get_optimal_io_size -blkid_topology_get_physical_sector_size -
- -
-encode -blkid_encode_string -blkid_safe_string -
- -
-misc -blkid_loff_t -blkid_devno_to_devname -blkid_devno_to_wholedisk -blkid_get_dev_size -blkid_get_library_version -blkid_parse_tag_string -blkid_parse_version_string -blkid_send_uevent -
- - diff --git a/shlibs/blkid/docs/libblkid.types b/shlibs/blkid/docs/libblkid.types deleted file mode 100644 index e69de29b..00000000 diff --git a/shlibs/blkid/docs/version.xml.in b/shlibs/blkid/docs/version.xml.in deleted file mode 100644 index d78bda93..00000000 --- a/shlibs/blkid/docs/version.xml.in +++ /dev/null @@ -1 +0,0 @@ -@VERSION@ diff --git a/shlibs/blkid/libblkid.3 b/shlibs/blkid/libblkid.3 deleted file mode 100644 index 15412a51..00000000 --- a/shlibs/blkid/libblkid.3 +++ /dev/null @@ -1,110 +0,0 @@ -.\" Copyright 2001 Andreas Dilger (adilger@turbolinux.com) -.\" -.\" This man page was created for libblkid.so.1.0 from e2fsprogs-1.24. -.\" -.\" This file may be copied under the terms of the GNU Public License. -.\" -.\" Created Wed Sep 14 12:02:12 2001, Andreas Dilger -.TH LIBBLKID 3 "May 2009" "util-linux" -.SH NAME -libblkid \- block device identification library -.SH SYNOPSIS -.B #include -.sp -.B cc -.I file.c -.B \-lblkid -.SH DESCRIPTION -The -.B libblkid -library is used to identify block devices (disks) as to their content (e.g. -filesystem type) as well as extracting additional information such as -filesystem labels/volume names, unique identifiers/serial numbers, etc. -A common use is to allow use of LABEL= and UUID= tags instead of hard-coding -specific block device names into configuration files. -.P -Block device information is normally kept in a cache file -.I /etc/blkid.tab -and is verified to still be valid before being returned to the user -(if the user has read permission on the raw block device, otherwise not). -The cache file also allows unprivileged users (normally anyone other -than root, or those not in the "disk" group) to locate devices by label/id. -The standard location of the cache file can be overridden by the -environment variable BLKID_FILE. -.P -In situations where one is getting information about a single known device, -it does not impact performance whether the cache is used or not (unless you -are not able to read the block device directly). If you are dealing with -multiple devices, use of the cache is highly recommended (even if empty) as -devices will be scanned at most one time and the on-disk cache will be -updated if possible. There is rarely a reason not to use the cache. -.P -In some cases (modular kernels), block devices are not even visible until -after they are accessed the first time, so it is critical that there is -some way to locate these devices without enumerating only visible devices, -so the use of the cache file is -.B required -in this situation. -.SH CONFIGURATION FILE -The standard location of the -.I /etc/blkid.conf -config file can be overridden by the environment variable BLKID_CONF. -The following options control the libblkid library: -.TP -.I SEND_UEVENT= -Sends uevent when -.I /dev/disk/by-{label,uuid}/ -symlink does not match with LABEL or UUID on the device. Default is "yes". -.TP -.I CACHE_FILE= -Overrides the standard location of the cache file. This setting can be -overridden by the environment variable BLKID_FILE. Default is -.I /etc/blkid.tab. -.TP -.I EVALUATE= -Defines LABEL and UUID evaluation method(s). Currently, the libblkid library -supports "udev" and "scan" methods. More than one methods may be specified in -a comma separated list. Default is "udev,scan". The "udev" method uses udev -.I /dev/disk/by-* -symlinks and the "scan" method scans all block devices from the -.I /proc/partitions -file. -.SH AUTHOR -.B libblkid -was written by Andreas Dilger for the ext2 filesystem utilties, with input -from Ted Ts'o. The library was subsequently heavily modified by Ted Ts'o. - -The low-level probing code was rewritten by Karel Zak. -.SH FILES -.TP 18 -.I /etc/blkid.tab -caches data extracted from each recognized block device -.TP -.I /etc/blkid.conf -configuration file -.SH AVAILABILITY -.B libblkid -is part of the util-linux package since version 2.15 and is available from -ftp://ftp.kernel.org/pub/linux/utils/util-linux/. -.SH COPYING -.B libblkid -is available under the terms of the GNU Library General Public License (LGPL), -version 2 (or at your discretion any later version). A copy of the LGPL -should be included with this library in the file COPYING. If not, write to -.RS -Free Software Foundation, Inc. -.br -51 Franklin St -.br -Fifth Floor -.br -Boston, MA 02110-1301 USA -.RE -.PP -or visit -.UR http://www.gnu.org/licenses/licenses.html#LGPL -http://www.gnu.org/licenses/licenses.html#LGPL -.UE -.SH "SEE ALSO" -.BR blkid (8) -.BR findfs (8) diff --git a/shlibs/blkid/samples/.gitignore b/shlibs/blkid/samples/.gitignore deleted file mode 100644 index 409e5cff..00000000 --- a/shlibs/blkid/samples/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -topology -partitions -mkfs -superblocks diff --git a/shlibs/blkid/samples/Makefile.am b/shlibs/blkid/samples/Makefile.am deleted file mode 100644 index 93588d57..00000000 --- a/shlibs/blkid/samples/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -include $(top_srcdir)/config/include-Makefile.am - -AM_CPPFLAGS += -I$(ul_libblkid_incdir) -AM_LDFLAGS += $(ul_libblkid_la) - -noinst_PROGRAMS = topology partitions mkfs superblocks - diff --git a/shlibs/blkid/samples/mkfs.c b/shlibs/blkid/samples/mkfs.c deleted file mode 100644 index 5c3ebe79..00000000 --- a/shlibs/blkid/samples/mkfs.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -#include -#include -#include -#include -#include -#include - -#include - -#include "c.h" - -int main(int argc, char *argv[]) -{ - int rc; - char *devname; - blkid_probe pr; - blkid_topology tp; - - if (argc < 2) { - fprintf(stderr, "usage: %s " - "-- checks based on libblkid for mkfs-like programs.\n", - program_invocation_short_name); - return EXIT_FAILURE; - } - - devname = argv[1]; - pr = blkid_new_probe_from_filename(devname); - if (!pr) - err(EXIT_FAILURE, "%s: faild to create a new libblkid probe", - devname); - - /* - * check Filesystems / Partitions overwrite - */ - - /* enable partitions probing (superblocks are enabled by default) */ - blkid_probe_enable_partitions(pr, TRUE); - - rc = blkid_do_fullprobe(pr); - if (rc == -1) - errx(EXIT_FAILURE, "%s: blkid_do_fullprobe() failed", devname); - else if (rc == 0) { - const char *type; - - if (!blkid_probe_lookup_value(pr, "TYPE", &type, NULL)) - errx(EXIT_FAILURE, "%s: appears to contain an existing " - "%s superblock", devname, type); - - if (!blkid_probe_lookup_value(pr, "PTTYPE", &type, NULL)) - errx(EXIT_FAILURE, "%s: appears to contain an partition " - "table (%s)", devname, type); - } - - /* - * get topology details - */ - tp = blkid_probe_get_topology(pr); - if (!tp) - errx(EXIT_FAILURE, "%s: failed to read topology", devname); - - - /* ... your mkfs. code or so ... - - off = blkid_topology_get_alignment_offset(tp); - - */ - - blkid_free_probe(pr); - - return EXIT_SUCCESS; -} diff --git a/shlibs/blkid/samples/partitions.c b/shlibs/blkid/samples/partitions.c deleted file mode 100644 index 3b527364..00000000 --- a/shlibs/blkid/samples/partitions.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include "c.h" - -int main(int argc, char *argv[]) -{ - int i, nparts; - char *devname; - blkid_probe pr; - blkid_partlist ls; - blkid_parttable root_tab; - - if (argc < 2) { - fprintf(stderr, "usage: %s " - "-- prints partitions\n", - program_invocation_short_name); - return EXIT_FAILURE; - } - - devname = argv[1]; - pr = blkid_new_probe_from_filename(devname); - if (!pr) - err(EXIT_FAILURE, "%s: faild to create a new libblkid probe", - devname); - /* Binary interface */ - ls = blkid_probe_get_partitions(pr); - if (!ls) - errx(EXIT_FAILURE, "%s: failed to read partitions\n", devname); - - /* - * Print info about the primary (root) partition table - */ - root_tab = blkid_partlist_get_table(ls); - if (!root_tab) - errx(EXIT_FAILURE, "%s: does not contains any " - "known partition table\n", devname); - - printf("size: %jd, sector size: %u, PT: %s, offset: %jd\n---\n", - blkid_probe_get_size(pr), - blkid_probe_get_sectorsize(pr), - blkid_parttable_get_type(root_tab), - blkid_parttable_get_offset(root_tab)); - - /* - * List partitions - */ - nparts = blkid_partlist_numof_partitions(ls); - if (!nparts) - goto done; - - for (i = 0; i < nparts; i++) { - const char *p; - blkid_partition par = blkid_partlist_get_partition(ls, i); - blkid_parttable tab = blkid_partition_get_table(par); - - printf("#%d: %10llu %10llu 0x%x", - blkid_partition_get_partno(par), - (unsigned long long) blkid_partition_get_start(par), - (unsigned long long) blkid_partition_get_size(par), - blkid_partition_get_type(par)); - - if (root_tab != tab) - /* subpartition (BSD, Minix, ...) */ - printf(" (%s)", blkid_parttable_get_type(tab)); - - p = blkid_partition_get_name(par); - if (p) - printf(" name='%s'", p); - p = blkid_partition_get_uuid(par); - if (p) - printf(" uuid='%s'", p); - p = blkid_partition_get_type_string(par); - if (p) - printf(" type='%s'", p); - - putc('\n', stdout); - } - -done: - blkid_free_probe(pr); - return EXIT_SUCCESS; -} diff --git a/shlibs/blkid/samples/superblocks.c b/shlibs/blkid/samples/superblocks.c deleted file mode 100644 index 20e39c97..00000000 --- a/shlibs/blkid/samples/superblocks.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -#include -#include -#include -#include -#include -#include - -#include - -#include "c.h" - -int main(int argc, char *argv[]) -{ - int rc; - char *devname; - blkid_probe pr; - - if (argc < 2) { - fprintf(stderr, "usage: %s " - "-- prints superblocks details about the device\n", - program_invocation_short_name); - return EXIT_FAILURE; - } - - devname = argv[1]; - pr = blkid_new_probe_from_filename(devname); - if (!pr) - err(EXIT_FAILURE, "%s: faild to create a new libblkid probe", - devname); - - /* enable topology probing */ - blkid_probe_enable_superblocks(pr, TRUE); - - /* set all flags */ - blkid_probe_set_superblocks_flags(pr, - BLKID_SUBLKS_LABEL | BLKID_SUBLKS_LABELRAW | - BLKID_SUBLKS_UUID | BLKID_SUBLKS_UUIDRAW | - BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE | - BLKID_SUBLKS_USAGE | BLKID_SUBLKS_VERSION | - BLKID_SUBLKS_MAGIC); - - rc = blkid_do_safeprobe(pr); - if (rc == -1) - errx(EXIT_FAILURE, "%s: blkid_do_safeprobe() failed", devname); - else if (rc == 1) - warnx("%s: cannot gather information about superblocks", devname); - else { - int i, nvals = blkid_probe_numof_values(pr); - - for (i = 0; i < nvals; i++) { - const char *name, *data; - - blkid_probe_get_value(pr, i, &name, &data, NULL); - printf("\t%s = %s\n", name, data); - } - } - - blkid_free_probe(pr); - return EXIT_SUCCESS; -} diff --git a/shlibs/blkid/samples/topology.c b/shlibs/blkid/samples/topology.c deleted file mode 100644 index de1c3a5e..00000000 --- a/shlibs/blkid/samples/topology.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -#include -#include -#include -#include -#include -#include - -#include - -#include "c.h" - -int main(int argc, char *argv[]) -{ - int rc; - char *devname; - blkid_probe pr; - blkid_topology tp; - - if (argc < 2) { - fprintf(stderr, "usage: %s " - "-- prints topology details about the device\n", - program_invocation_short_name); - return EXIT_FAILURE; - } - - devname = argv[1]; - pr = blkid_new_probe_from_filename(devname); - if (!pr) - err(EXIT_FAILURE, "%s: faild to create a new libblkid probe", - devname); - /* - * Binary interface - */ - tp = blkid_probe_get_topology(pr); - if (tp) { - printf("----- binary interface:\n"); - printf("\talignment offset : %lu\n", - blkid_topology_get_alignment_offset(tp)); - printf("\tminimum io size : %lu\n", - blkid_topology_get_minimum_io_size(tp)); - printf("\toptimal io size : %lu\n", - blkid_topology_get_optimal_io_size(tp)); - printf("\tlogical sector size : %lu\n", - blkid_topology_get_logical_sector_size(tp)); - printf("\tphysical sector size : %lu\n", - blkid_topology_get_physical_sector_size(tp)); - } - - /* - * NAME=value interface - */ - - /* enable topology probing */ - blkid_probe_enable_topology(pr, TRUE); - - /* disable superblocks probing (enabled by default) */ - blkid_probe_enable_superblocks(pr, FALSE); - - rc = blkid_do_fullprobe(pr); - if (rc == -1) - errx(EXIT_FAILURE, "%s: blkid_do_fullprobe() failed", devname); - else if (rc == 1) - warnx("%s: missing topology information", devname); - else { - int i, nvals = blkid_probe_numof_values(pr); - - printf("----- NAME=value interface (values: %d):\n", nvals); - - for (i = 0; i < nvals; i++) { - const char *name, *data; - - blkid_probe_get_value(pr, i, &name, &data, NULL); - printf("\t%s = %s\n", name, data); - } - } - - blkid_free_probe(pr); - return EXIT_SUCCESS; -} diff --git a/shlibs/blkid/src/Makefile.am b/shlibs/blkid/src/Makefile.am deleted file mode 100644 index 543f2f62..00000000 --- a/shlibs/blkid/src/Makefile.am +++ /dev/null @@ -1,72 +0,0 @@ -include $(top_srcdir)/config/include-Makefile.am - -SUBDIRS = superblocks topology partitions . - -common_ldadd = -common_cflags = - -if BUILD_LIBUUID -common_ldadd += $(ul_libuuid_la) -common_cflags += -I$(ul_libuuid_srcdir) -endif - -AM_CPPFLAGS += -I$(ul_libblkid_incdir) -I$(ul_libblkid_srcdir) $(common_cflags) - -# includes -blkidincdir = $(includedir)/blkid -nodist_blkidinc_HEADERS = blkid.h - -usrlib_exec_LTLIBRARIES = libblkid.la -libblkid_la_SOURCES = cache.c dev.c devname.c devno.c getsize.c llseek.c \ - probe.c read.c resolve.c save.c tag.c version.c verify.c \ - encode.c blkidP.h superblocks/superblocks.h \ - config.c evaluate.c \ - $(blkidinc_HEADERS) \ - $(top_srcdir)/lib/blkdev.c \ - $(top_srcdir)/lib/linux_version.c \ - $(top_srcdir)/lib/canonicalize.c \ - $(top_srcdir)/lib/md5.c \ - $(top_srcdir)/lib/crc32.c \ - $(top_srcdir)/include/list.h \ - $(top_srcdir)/lib/env.c \ - $(top_srcdir)/lib/strutils.c \ - $(top_srcdir)/lib/at.c \ - $(top_srcdir)/lib/sysfs.c - -nodist_libblkid_la_SOURCES = blkid.h - -libblkid_la_LIBADD = superblocks/libblkid_superblocks.la \ - topology/libblkid_topology.la \ - partitions/libblkid_partitions.la \ - $(common_ldadd) - -libblkid_la_DEPENDENCIES = $(libblkid_la_LIBADD) blkid.sym blkid.h.in - -libblkid_la_LDFLAGS = -Wl,--version-script=$(ul_libblkid_srcdir)/blkid.sym \ - -version-info $(LIBBLKID_VERSION_INFO) - -tests = test_cache test_config test_dev test_devname test_devno \ - test_read test_resolve test_save test_tag test_verify test_evaluate - -EXTRA_DIST = blkid.sym tst_types.c blkid.h.in -CLEANFILES = $(tests) - -tests: all $(tests) -test_%: %.c - $(AM_V_CC)$(COMPILE) -DTEST_PROGRAM $< .libs/libblkid.a -o $@ -luuid - - -# move lib from $(usrlib_execdir) to $(libdir) if needed -install-exec-hook: - if test "$(usrlib_execdir)" != "$(libdir)"; then \ - mkdir -p $(DESTDIR)$(libdir); \ - mv $(DESTDIR)$(usrlib_execdir)/libblkid.so.* $(DESTDIR)$(libdir); \ - so_img_name=$$(readlink $(DESTDIR)$(usrlib_execdir)/libblkid.so); \ - so_img_rel_target=$$(echo $(usrlib_execdir) | sed 's,\(^/\|\)[^/][^/]*,..,g'); \ - (cd $(DESTDIR)$(usrlib_execdir) && \ - rm -f libblkid.so && \ - $(LN_S) $$so_img_rel_target$(libdir)/$$so_img_name libblkid.so); \ - fi - -uninstall-hook: - rm -f $(DESTDIR)$(libdir)/libblkid.so* diff --git a/shlibs/blkid/src/blkid.h.in b/shlibs/blkid/src/blkid.h.in deleted file mode 100644 index 05527bed..00000000 --- a/shlibs/blkid/src/blkid.h.in +++ /dev/null @@ -1,336 +0,0 @@ -/* - * blkid.h - Interface for libblkid, a library to identify block devices - * - * Copyright (C) 2001 Andreas Dilger - * Copyright (C) 2003 Theodore Ts'o - * Copyright (C) 2008 Karel Zak - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _BLKID_BLKID_H -#define _BLKID_BLKID_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define BLKID_VERSION "@LIBBLKID_VERSION@" -#define BLKID_DATE "@LIBBLKID_DATE@" - -/** - * blkid_dev: - * - * The device object keeps information about one device - */ -typedef struct blkid_struct_dev *blkid_dev; - -/** - * blkid_cache: - * - * information about all system devices - */ -typedef struct blkid_struct_cache *blkid_cache; - -/** - * blkid_probe: - * - * low-level probing setting - */ -typedef struct blkid_struct_probe *blkid_probe; - -/** - * blkid_topology: - * - * device topology information - */ -typedef struct blkid_struct_topology *blkid_topology; - -/** - * blkid_partlist - * - * list of all detected partitions and partitions tables - */ -typedef struct blkid_struct_partlist *blkid_partlist; - -/** - * blkid_partition: - * - * information about a partition - */ -typedef struct blkid_struct_partition *blkid_partition; - -/** - * blkid_parttable: - * - * information about a partition table - */ -typedef struct blkid_struct_parttable *blkid_parttable; - -/** - * blkid_loff_t: - * - * 64-bit signed number for offsets and sizes - */ -typedef int64_t blkid_loff_t; - -/** - * blkid_tag_iterate: - * - * tags iterator for high-level (blkid_cache) API - */ -typedef struct blkid_struct_tag_iterate *blkid_tag_iterate; - -/** - * blkid_dev_iterate: - * - * devices iterator for high-level (blkid_cache) API - */ -typedef struct blkid_struct_dev_iterate *blkid_dev_iterate; - -/* - * Flags for blkid_get_dev - * - * BLKID_DEV_CREATE Create an empty device structure if not found - * in the cache. - * BLKID_DEV_VERIFY Make sure the device structure corresponds - * with reality. - * BLKID_DEV_FIND Just look up a device entry, and return NULL - * if it is not found. - * BLKID_DEV_NORMAL Get a valid device structure, either from the - * cache or by probing the device. - */ -#define BLKID_DEV_FIND 0x0000 -#define BLKID_DEV_CREATE 0x0001 -#define BLKID_DEV_VERIFY 0x0002 -#define BLKID_DEV_NORMAL (BLKID_DEV_CREATE | BLKID_DEV_VERIFY) - -/* cache.c */ -extern void blkid_put_cache(blkid_cache cache); -extern int blkid_get_cache(blkid_cache *cache, const char *filename); -extern void blkid_gc_cache(blkid_cache cache); - -/* dev.c */ -extern const char *blkid_dev_devname(blkid_dev dev); - -extern blkid_dev_iterate blkid_dev_iterate_begin(blkid_cache cache); -extern int blkid_dev_set_search(blkid_dev_iterate iter, - char *search_type, char *search_value); -extern int blkid_dev_next(blkid_dev_iterate iterate, blkid_dev *dev); -extern void blkid_dev_iterate_end(blkid_dev_iterate iterate); - -/* devno.c */ -extern char *blkid_devno_to_devname(dev_t devno); -extern int blkid_devno_to_wholedisk(dev_t dev, char *diskname, - size_t len, dev_t *diskdevno); - -/* devname.c */ -extern int blkid_probe_all(blkid_cache cache); -extern int blkid_probe_all_new(blkid_cache cache); -extern int blkid_probe_all_removable(blkid_cache cache); -extern blkid_dev blkid_get_dev(blkid_cache cache, const char *devname, - int flags); - -/* getsize.c */ -extern blkid_loff_t blkid_get_dev_size(int fd); - -/* verify.c */ -extern blkid_dev blkid_verify(blkid_cache cache, blkid_dev dev); - -/* read.c */ - -/* resolve.c */ -extern char *blkid_get_tag_value(blkid_cache cache, const char *tagname, - const char *devname); -extern char *blkid_get_devname(blkid_cache cache, const char *token, - const char *value); - -/* tag.c */ -extern blkid_tag_iterate blkid_tag_iterate_begin(blkid_dev dev); -extern int blkid_tag_next(blkid_tag_iterate iterate, - const char **type, const char **value); -extern void blkid_tag_iterate_end(blkid_tag_iterate iterate); -extern int blkid_dev_has_tag(blkid_dev dev, const char *type, - const char *value); -extern blkid_dev blkid_find_dev_with_tag(blkid_cache cache, - const char *type, - const char *value); -extern int blkid_parse_tag_string(const char *token, char **ret_type, - char **ret_val); - -/* version.c */ -extern int blkid_parse_version_string(const char *ver_string); -extern int blkid_get_library_version(const char **ver_string, - const char **date_string); - -/* encode.c */ -extern int blkid_encode_string(const char *str, char *str_enc, size_t len); -extern int blkid_safe_string(const char *str, char *str_safe, size_t len); - -/* evaluate.c */ -extern int blkid_send_uevent(const char *devname, const char *action); -extern char *blkid_evaluate_tag(const char *token, const char *value, - blkid_cache *cache); -extern char *blkid_evaluate_spec(const char *spec, blkid_cache *cache); - -/* probe.c */ -extern blkid_probe blkid_new_probe(void); -extern blkid_probe blkid_new_probe_from_filename(const char *filename); -extern void blkid_free_probe(blkid_probe pr); -extern void blkid_reset_probe(blkid_probe pr); - -extern int blkid_probe_set_device(blkid_probe pr, int fd, - blkid_loff_t off, blkid_loff_t size); - -extern dev_t blkid_probe_get_devno(blkid_probe pr); -extern dev_t blkid_probe_get_wholedisk_devno(blkid_probe pr); -extern int blkid_probe_is_wholedisk(blkid_probe pr); - -extern blkid_loff_t blkid_probe_get_size(blkid_probe pr); -extern blkid_loff_t blkid_probe_get_offset(blkid_probe pr); -extern unsigned int blkid_probe_get_sectorsize(blkid_probe pr); -extern blkid_loff_t blkid_probe_get_sectors(blkid_probe pr); - -extern int blkid_probe_get_fd(blkid_probe pr); - -/* - * superblocks probing - */ -extern int blkid_known_fstype(const char *fstype); -extern int blkid_probe_enable_superblocks(blkid_probe pr, int enable); - -#define BLKID_SUBLKS_LABEL (1 << 1) /* read LABEL from superblock */ -#define BLKID_SUBLKS_LABELRAW (1 << 2) /* read and define LABEL_RAW result value*/ -#define BLKID_SUBLKS_UUID (1 << 3) /* read UUID from superblock */ -#define BLKID_SUBLKS_UUIDRAW (1 << 4) /* read and define UUID_RAW result value */ -#define BLKID_SUBLKS_TYPE (1 << 5) /* define TYPE result value */ -#define BLKID_SUBLKS_SECTYPE (1 << 6) /* define compatible fs type (second type) */ -#define BLKID_SUBLKS_USAGE (1 << 7) /* define USAGE result value */ -#define BLKID_SUBLKS_VERSION (1 << 8) /* read FS type from superblock */ -#define BLKID_SUBLKS_MAGIC (1 << 9) /* define SBMAGIC and SBMAGIC_OFFSET */ - -#define BLKID_SUBLKS_DEFAULT (BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID | \ - BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE) - -extern int blkid_probe_set_superblocks_flags(blkid_probe pr, int flags); - -extern int blkid_probe_reset_superblocks_filter(blkid_probe pr); -extern int blkid_probe_invert_superblocks_filter(blkid_probe pr); - -#define BLKID_FLTR_NOTIN 1 -#define BLKID_FLTR_ONLYIN 2 -extern int blkid_probe_filter_superblocks_type(blkid_probe pr, int flag, char *names[]); - -#define BLKID_USAGE_FILESYSTEM (1 << 1) -#define BLKID_USAGE_RAID (1 << 2) -#define BLKID_USAGE_CRYPTO (1 << 3) -#define BLKID_USAGE_OTHER (1 << 4) -extern int blkid_probe_filter_superblocks_usage(blkid_probe pr, int flag, int usage); - -/* - * topology probing - */ -extern int blkid_probe_enable_topology(blkid_probe pr, int enable); - -/* binary interface */ -extern blkid_topology blkid_probe_get_topology(blkid_probe pr); - -extern unsigned long blkid_topology_get_alignment_offset(blkid_topology tp); -extern unsigned long blkid_topology_get_minimum_io_size(blkid_topology tp); -extern unsigned long blkid_topology_get_optimal_io_size(blkid_topology tp); -extern unsigned long blkid_topology_get_logical_sector_size(blkid_topology tp); -extern unsigned long blkid_topology_get_physical_sector_size(blkid_topology tp); - -/* - * partitions probing - */ -extern int blkid_known_pttype(const char *pttype); -extern int blkid_probe_enable_partitions(blkid_probe pr, int enable); - -extern int blkid_probe_reset_partitions_filter(blkid_probe pr); -extern int blkid_probe_invert_partitions_filter(blkid_probe pr); -extern int blkid_probe_filter_partitions_type(blkid_probe pr, int flag, char *names[]); - - -/* partitions probing flags */ -#define BLKID_PARTS_FORCE_GPT (1 << 1) -#define BLKID_PARTS_ENTRY_DETAILS (1 << 2) -extern int blkid_probe_set_partitions_flags(blkid_probe pr, int flags); - -/* binary interface */ -extern blkid_partlist blkid_probe_get_partitions(blkid_probe pr); - -extern int blkid_partlist_numof_partitions(blkid_partlist ls); -extern blkid_parttable blkid_partlist_get_table(blkid_partlist ls); -extern blkid_partition blkid_partlist_get_partition(blkid_partlist ls, int n); -extern blkid_partition blkid_partlist_devno_to_partition(blkid_partlist ls, dev_t devno); - -extern blkid_parttable blkid_partition_get_table(blkid_partition par); -extern const char *blkid_partition_get_name(blkid_partition par); -extern const char *blkid_partition_get_uuid(blkid_partition par); -extern int blkid_partition_get_partno(blkid_partition par); -extern blkid_loff_t blkid_partition_get_start(blkid_partition par); -extern blkid_loff_t blkid_partition_get_size(blkid_partition par); -extern int blkid_partition_get_type(blkid_partition par); -extern const char *blkid_partition_get_type_string(blkid_partition par); -extern unsigned long long blkid_partition_get_flags(blkid_partition par); -extern int blkid_partition_is_logical(blkid_partition par); -extern int blkid_partition_is_extended(blkid_partition par); -extern int blkid_partition_is_primary(blkid_partition par); - -extern const char *blkid_parttable_get_type(blkid_parttable tab); -extern blkid_loff_t blkid_parttable_get_offset(blkid_parttable tab); -extern blkid_partition blkid_parttable_get_parent(blkid_parttable tab); - -/* - * NAME=value low-level interface - */ -extern int blkid_do_probe(blkid_probe pr); -extern int blkid_do_safeprobe(blkid_probe pr); -extern int blkid_do_fullprobe(blkid_probe pr); - -extern int blkid_probe_numof_values(blkid_probe pr); -extern int blkid_probe_get_value(blkid_probe pr, int num, const char **name, - const char **data, size_t *len); -extern int blkid_probe_lookup_value(blkid_probe pr, const char *name, - const char **data, size_t *len); -extern int blkid_probe_has_value(blkid_probe pr, const char *name); - -/*** - * Deprecated functions/macros - */ -#define BLKID_PROBREQ_LABEL BLKID_SUBLKS_LABEL -#define BLKID_PROBREQ_LABELRAW BLKID_SUBLKS_LABELRAW -#define BLKID_PROBREQ_UUID BLKID_SUBLKS_UUID -#define BLKID_PROBREQ_UUIDRAW BLKID_SUBLKS_UUIDRAW -#define BLKID_PROBREQ_TYPE BLKID_SUBLKS_TYPE -#define BLKID_PROBREQ_SECTYPE BLKID_SUBLKS_SECTYPE -#define BLKID_PROBREQ_USAGE BLKID_SUBLKS_USAGE -#define BLKID_PROBREQ_VERSION BLKID_SUBLKS_VERSION - -extern int blkid_probe_set_request(blkid_probe pr, int flags); -extern int blkid_probe_filter_usage(blkid_probe pr, int flag, int usage); -extern int blkid_probe_filter_types(blkid_probe pr, int flag, char *names[]); -extern int blkid_probe_invert_filter(blkid_probe pr); -extern int blkid_probe_reset_filter(blkid_probe pr); - -#ifdef __cplusplus -} -#endif - -#endif /* _BLKID_BLKID_H */ diff --git a/shlibs/blkid/src/blkid.sym b/shlibs/blkid/src/blkid.sym deleted file mode 100644 index e758ff1a..00000000 --- a/shlibs/blkid/src/blkid.sym +++ /dev/null @@ -1,141 +0,0 @@ -/* - * The symbol versioning ensures that a new application requiring symbol foo() - * can't run with old libblkid.so not providing foo() - the global SONAME - * version info can't enforce this since we never change the SONAME. - * - * The original libblkid from e2fsprogs (<=1.41.4) does not to use - * symbol versioning -- all the original symbols are in BLKID_1.0 now. - */ -BLKID_1.0 { -global: - blkid_dev_devname; - blkid_dev_has_tag; - blkid_dev_iterate_begin; - blkid_dev_iterate_end; - blkid_dev_next; - blkid_devno_to_devname; - blkid_dev_set_search; - blkid_find_dev_with_tag; - blkid_gc_cache; - blkid_get_cache; - blkid_get_dev; - blkid_get_devname; - blkid_get_dev_size; - blkid_get_library_version; - blkid_get_tag_value; - blkid_known_fstype; - blkid_parse_tag_string; - blkid_parse_version_string; - blkid_probe_all; - blkid_probe_all_new; - blkid_put_cache; - blkid_tag_iterate_begin; - blkid_tag_iterate_end; - blkid_tag_next; - blkid_verify; -local: - *; -}; - - -/* - * symbols since util-linux 2.15 - */ -BLKID_2.15 { -global: - blkid_do_probe; - blkid_do_safeprobe; - blkid_encode_string; - blkid_evaluate_tag; - blkid_free_probe; - blkid_new_probe; - blkid_probe_all; - blkid_probe_all_new; - blkid_probe_filter_types; - blkid_probe_filter_usage; - blkid_probe_get_value; - blkid_probe_has_value; - blkid_probe_invert_filter; - blkid_probe_lookup_value; - blkid_probe_numof_values; - blkid_probe_reset_filter; - blkid_probe_set_device; - blkid_probe_set_request; - blkid_reset_probe; - blkid_safe_string; - blkid_send_uevent; -} BLKID_1.0; - -/* - * symbols since util-linux 2.17 - */ -BLKID_2.17 { -global: - blkid_devno_to_wholedisk; - blkid_do_fullprobe; - blkid_known_pttype; - blkid_new_probe_from_filename; - blkid_partition_get_name; - blkid_partition_get_partno; - blkid_partition_get_size; - blkid_partition_get_start; - blkid_partition_get_table; - blkid_partition_get_type; - blkid_partition_get_type_string; - blkid_partition_get_uuid; - blkid_partition_is_extended; - blkid_partition_is_logical; - blkid_partition_is_primary; - blkid_partlist_get_partition; - blkid_partlist_numof_partitions; - blkid_parttable_get_offset; - blkid_parttable_get_parent; - blkid_parttable_get_type; - blkid_probe_enable_partitions; - blkid_probe_enable_superblocks; - blkid_probe_enable_topology; - blkid_probe_filter_partitions_type; - blkid_probe_filter_superblocks_type; - blkid_probe_filter_superblocks_usage; - blkid_probe_get_devno; - blkid_probe_get_partitions; - blkid_probe_get_sectorsize; - blkid_probe_get_sectors; - blkid_probe_get_size; - blkid_probe_get_topology; - blkid_probe_invert_partitions_filter; - blkid_probe_invert_superblocks_filter; - blkid_probe_reset_partitions_filter; - blkid_probe_reset_superblocks_filter; - blkid_probe_set_partitions_flags; - blkid_probe_set_superblocks_flags; - blkid_topology_get_alignment_offset; - blkid_topology_get_logical_sector_size; - blkid_topology_get_minimum_io_size; - blkid_topology_get_optimal_io_size; - blkid_topology_get_physical_sector_size; -} BLKID_2.15; - -/* - * symbols since util-linux 2.18 - */ -BLKID_2.18 { -global: - blkid_partition_get_flags; - blkid_partlist_devno_to_partition; - blkid_partlist_get_table; - blkid_probe_all_removable; - blkid_probe_get_fd; - blkid_probe_get_offset; - blkid_probe_get_wholedisk_devno; - blkid_probe_is_wholedisk; -} BLKID_2.17; - -/* - * symbols since util-linux 2.20 - */ -BLKID_2.20 { -global: - blkid_evaluate_spec; -} BLKID_2.18; - diff --git a/shlibs/blkid/src/blkidP.h b/shlibs/blkid/src/blkidP.h deleted file mode 100644 index aeeebc16..00000000 --- a/shlibs/blkid/src/blkidP.h +++ /dev/null @@ -1,466 +0,0 @@ -/* - * blkidP.h - Internal interfaces for libblkid - * - * Copyright (C) 2001 Andreas Dilger - * Copyright (C) 2003 Theodore Ts'o - * - * %Begin-Header% - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * %End-Header% - */ - -#ifndef _BLKID_BLKIDP_H -#define _BLKID_BLKIDP_H - - -#define CONFIG_BLKID_DEBUG 1 - -#include -#include -#include -#include -#include -#include - -#include "c.h" -#include "bitops.h" /* $(top_srcdir)/include/ */ -#include "blkdev.h" - -#include "blkid.h" -#include "list.h" - -/* - * This describes the attributes of a specific device. - * We can traverse all of the tags by bid_tags (linking to the tag bit_names). - * The bid_label and bid_uuid fields are shortcuts to the LABEL and UUID tag - * values, if they exist. - */ -struct blkid_struct_dev -{ - struct list_head bid_devs; /* All devices in the cache */ - struct list_head bid_tags; /* All tags for this device */ - blkid_cache bid_cache; /* Dev belongs to this cache */ - char *bid_name; /* Device inode pathname */ - char *bid_type; /* Preferred device TYPE */ - int bid_pri; /* Device priority */ - dev_t bid_devno; /* Device major/minor number */ - time_t bid_time; /* Last update time of device */ - suseconds_t bid_utime; /* Last update time (microseconds) */ - unsigned int bid_flags; /* Device status bitflags */ - char *bid_label; /* Shortcut to device LABEL */ - char *bid_uuid; /* Shortcut to binary UUID */ -}; - -#define BLKID_BID_FL_VERIFIED 0x0001 /* Device data validated from disk */ -#define BLKID_BID_FL_INVALID 0x0004 /* Device is invalid */ -#define BLKID_BID_FL_REMOVABLE 0x0008 /* Device added by blkid_probe_all_removable() */ - -/* - * Each tag defines a NAME=value pair for a particular device. The tags - * are linked via bit_names for a single device, so that traversing the - * names list will get you a list of all tags associated with a device. - * They are also linked via bit_values for all devices, so one can easily - * search all tags with a given NAME for a specific value. - */ -struct blkid_struct_tag -{ - struct list_head bit_tags; /* All tags for this device */ - struct list_head bit_names; /* All tags with given NAME */ - char *bit_name; /* NAME of tag (shared) */ - char *bit_val; /* value of tag */ - blkid_dev bit_dev; /* pointer to device */ -}; -typedef struct blkid_struct_tag *blkid_tag; - -/* - * Chain IDs - */ -enum { - BLKID_CHAIN_SUBLKS, /* FS/RAID superblocks (enabled by default) */ - BLKID_CHAIN_TOPLGY, /* Block device topology */ - BLKID_CHAIN_PARTS, /* Partition tables */ - - BLKID_NCHAINS /* number of chains */ -}; - -struct blkid_chain { - const struct blkid_chaindrv *driver; /* chain driver */ - - int enabled; /* boolean */ - int flags; /* BLKID__* */ - int binary; /* boolean */ - int idx; /* index of the current prober */ - unsigned long *fltr; /* filter or NULL */ - void *data; /* private chain data or NULL */ -}; - -/* - * Chain driver - */ -struct blkid_chaindrv { - const int id; /* BLKID_CHAIN_* */ - const char *name; /* name of chain (for debug purpose) */ - const int dflt_flags; /* default chain flags */ - const int dflt_enabled; /* default enabled boolean */ - int has_fltr; /* boolean */ - - const struct blkid_idinfo **idinfos; /* description of probing functions */ - const size_t nidinfos; /* number of idinfos */ - - /* driver operations */ - int (*probe)(blkid_probe, struct blkid_chain *); - int (*safeprobe)(blkid_probe, struct blkid_chain *); - void (*free_data)(blkid_probe, void *); -}; - -/* - * Low-level probe result - */ -#define BLKID_PROBVAL_BUFSIZ 64 - -#define BLKID_NVALS_SUBLKS 14 -#define BLKID_NVALS_TOPLGY 5 -#define BLKID_NVALS_PARTS 13 - -/* Max number of all values in probing result */ -#define BLKID_NVALS (BLKID_NVALS_SUBLKS + \ - BLKID_NVALS_TOPLGY + \ - BLKID_NVALS_PARTS) - -struct blkid_prval -{ - const char *name; /* value name */ - unsigned char data[BLKID_PROBVAL_BUFSIZ]; /* value data */ - size_t len; /* length of value data */ - - struct blkid_chain *chain; /* owner */ -}; - -/* - * Filesystem / Raid magic strings - */ -struct blkid_idmag -{ - const char *magic; /* magic string */ - unsigned int len; /* length of magic */ - - long kboff; /* kilobyte offset of superblock */ - unsigned int sboff; /* byte offset within superblock */ -}; - -/* - * Filesystem / Raid description - */ -struct blkid_idinfo -{ - const char *name; /* fs, raid or partition table name */ - int usage; /* BLKID_USAGE_* flag */ - int flags; /* BLKID_IDINFO_* flags */ - int minsz; /* minimal device size */ - - /* probe function */ - int (*probefunc)(blkid_probe pr, const struct blkid_idmag *mag); - - struct blkid_idmag magics[]; /* NULL or array with magic strings */ -}; - -#define BLKID_NONE_MAGIC {{ NULL }} - -/* - * tolerant FS - can share the same device with more filesystems (e.g. typical - * on CD-ROMs). We need this flag to detect ambivalent results (e.g. valid fat - * and valid linux swap on the same device). - */ -#define BLKID_IDINFO_TOLERANT (1 << 1) - -struct blkid_bufinfo { - unsigned char *data; - blkid_loff_t off; - blkid_loff_t len; - struct list_head bufs; /* list of buffers */ -}; - -/* - * Low-level probing control struct - */ -struct blkid_struct_probe -{ - int fd; /* device file descriptor */ - blkid_loff_t off; /* begin of data on the device */ - blkid_loff_t size; /* end of data on the device */ - - dev_t devno; /* device number (st.st_rdev) */ - dev_t disk_devno; /* devno of the whole-disk or 0 */ - unsigned int blkssz; /* sector size (BLKSSZGET ioctl) */ - mode_t mode; /* struct stat.sb_mode */ - - int flags; /* private libray flags */ - int prob_flags; /* always zeroized by blkid_do_*() */ - - blkid_loff_t wipe_off; /* begin of the wiped area */ - blkid_loff_t wipe_size; /* size of the wiped area */ - struct blkid_chain *wipe_chain; /* superblock, partition, ... */ - - struct list_head buffers; /* list of buffers */ - - struct blkid_chain chains[BLKID_NCHAINS]; /* array of chains */ - struct blkid_chain *cur_chain; /* current chain */ - - struct blkid_prval vals[BLKID_NVALS]; /* results */ - int nvals; /* number of assigned vals */ - - struct blkid_struct_probe *parent; /* for clones */ - struct blkid_struct_probe *disk_probe; /* whole-disk probing */ -}; - -/* private flags library flags */ -#define BLKID_FL_PRIVATE_FD (1 << 1) /* see blkid_new_probe_from_filename() */ -#define BLKID_FL_TINY_DEV (1 << 2) /* <= 1.47MiB (floppy or so) */ -#define BLKID_FL_CDROM_DEV (1 << 3) /* is a CD/DVD drive */ - -/* private per-probing flags */ -#define BLKID_PROBE_FL_IGNORE_PT (1 << 1) /* ignore partition table */ - -extern blkid_probe blkid_clone_probe(blkid_probe parent); -extern blkid_probe blkid_probe_get_wholedisk_probe(blkid_probe pr); - -/* - * Evaluation methods (for blkid_eval_* API) - */ -enum { - BLKID_EVAL_UDEV = 0, - BLKID_EVAL_SCAN, - - __BLKID_EVAL_LAST -}; - -/* - * Library config options - */ -struct blkid_config { - int eval[__BLKID_EVAL_LAST]; /* array with EVALUATION= options */ - int nevals; /* number of elems in eval array */ - int uevent; /* SEND_UEVENT= option */ - char *cachefile; /* CACHE_FILE= option */ -}; - -extern struct blkid_config *blkid_read_config(const char *filename); -extern void blkid_free_config(struct blkid_config *conf); - -/* - * Minimum number of seconds between device probes, even when reading - * from the cache. This is to avoid re-probing all devices which were - * just probed by another program that does not share the cache. - */ -#define BLKID_PROBE_MIN 2 - -/* - * Time in seconds an entry remains verified in the in-memory cache - * before being reverified (in case of long-running processes that - * keep a cache in memory and continue to use it for a long time). - */ -#define BLKID_PROBE_INTERVAL 200 - -/* This describes an entire blkid cache file and probed devices. - * We can traverse all of the found devices via bic_list. - * We can traverse all of the tag types by bic_tags, which hold empty tags - * for each tag type. Those tags can be used as list_heads for iterating - * through all devices with a specific tag type (e.g. LABEL). - */ -struct blkid_struct_cache -{ - struct list_head bic_devs; /* List head of all devices */ - struct list_head bic_tags; /* List head of all tag types */ - time_t bic_time; /* Last probe time */ - time_t bic_ftime; /* Mod time of the cachefile */ - unsigned int bic_flags; /* Status flags of the cache */ - char *bic_filename; /* filename of cache */ - blkid_probe probe; /* low-level probing stuff */ -}; - -#define BLKID_BIC_FL_PROBED 0x0002 /* We probed /proc/partition devices */ -#define BLKID_BIC_FL_CHANGED 0x0004 /* Cache has changed from disk */ - -extern char *blkid_strdup(const char *s); -extern char *blkid_strndup(const char *s, const int length); -extern char *blkid_strconcat(const char *a, const char *b, const char *c); - -#define BLKID_CACHE_FILE "/etc/blkid.tab" -#define BLKID_CONFIG_FILE "/etc/blkid.conf" - -#define BLKID_ERR_IO 5 -#define BLKID_ERR_PROC 9 -#define BLKID_ERR_MEM 12 -#define BLKID_ERR_CACHE 14 -#define BLKID_ERR_DEV 19 -#define BLKID_ERR_PARAM 22 -#define BLKID_ERR_BIG 27 - -/* - * Priority settings for different types of devices - */ -#define BLKID_PRI_UBI 50 -#define BLKID_PRI_DM 40 -#define BLKID_PRI_EVMS 30 -#define BLKID_PRI_LVM 20 -#define BLKID_PRI_MD 10 - -#if defined(TEST_PROGRAM) && !defined(CONFIG_BLKID_DEBUG) -#define CONFIG_BLKID_DEBUG -#endif - -#define DEBUG_CACHE 0x0001 -#define DEBUG_DUMP 0x0002 -#define DEBUG_DEV 0x0004 -#define DEBUG_DEVNAME 0x0008 -#define DEBUG_DEVNO 0x0010 -#define DEBUG_PROBE 0x0020 -#define DEBUG_READ 0x0040 -#define DEBUG_RESOLVE 0x0080 -#define DEBUG_SAVE 0x0100 -#define DEBUG_TAG 0x0200 -#define DEBUG_LOWPROBE 0x0400 -#define DEBUG_CONFIG 0x0800 -#define DEBUG_EVALUATE 0x1000 -#define DEBUG_INIT 0x8000 -#define DEBUG_ALL 0xFFFF - -#ifdef CONFIG_BLKID_DEBUG -extern int blkid_debug_mask; -extern void blkid_init_debug(int mask); -extern void blkid_debug_dump_dev(blkid_dev dev); -extern void blkid_debug_dump_tag(blkid_tag tag); - -#define DBG(m,x) if ((m) & blkid_debug_mask) x; - -#else /* !CONFIG_BLKID_DEBUG */ -#define DBG(m,x) -#define blkid_init_debug(x) -#endif /* CONFIG_BLKID_DEBUG */ - -/* devno.c */ -struct dir_list { - char *name; - struct dir_list *next; -}; -extern void blkid__scan_dir(char *, dev_t, struct dir_list **, char **); -extern int blkid_driver_has_major(const char *drvname, int major); - -/* lseek.c */ -extern blkid_loff_t blkid_llseek(int fd, blkid_loff_t offset, int whence); - -/* read.c */ -extern void blkid_read_cache(blkid_cache cache); - -/* save.c */ -extern int blkid_flush_cache(blkid_cache cache); - -/* cache */ -extern char *blkid_safe_getenv(const char *arg); -extern char *blkid_get_cache_filename(struct blkid_config *conf); - -/* - * Functions to create and find a specific tag type: tag.c - */ -extern void blkid_free_tag(blkid_tag tag); -extern blkid_tag blkid_find_tag_dev(blkid_dev dev, const char *type); -extern int blkid_set_tag(blkid_dev dev, const char *name, - const char *value, const int vlength); - -/* - * Functions to create and find a specific tag type: dev.c - */ -extern blkid_dev blkid_new_dev(void); -extern void blkid_free_dev(blkid_dev dev); - -/* probe.c */ -extern int blkid_probe_is_tiny(blkid_probe pr); -extern int blkid_probe_is_cdrom(blkid_probe pr); -extern unsigned char *blkid_probe_get_buffer(blkid_probe pr, - blkid_loff_t off, blkid_loff_t len); - -extern unsigned char *blkid_probe_get_sector(blkid_probe pr, unsigned int sector); - -extern int blkid_probe_get_dimension(blkid_probe pr, - blkid_loff_t *off, blkid_loff_t *size); - -extern int blkid_probe_set_dimension(blkid_probe pr, - blkid_loff_t off, blkid_loff_t size); - -extern int blkid_probe_get_idmag(blkid_probe pr, const struct blkid_idinfo *id, - blkid_loff_t *offset, const struct blkid_idmag **res); - -/* returns superblok according to 'struct blkid_idmag' */ -#define blkid_probe_get_sb(_pr, _mag, type) \ - ((type *) blkid_probe_get_buffer((_pr),\ - (_mag)->kboff << 10, sizeof(type))) - -extern blkid_partlist blkid_probe_get_partlist(blkid_probe pr); - -extern int blkid_probe_is_covered_by_pt(blkid_probe pr, - blkid_loff_t offset, blkid_loff_t size); - -extern void blkid_probe_chain_reset_vals(blkid_probe pr, struct blkid_chain *chn); -extern int blkid_probe_chain_copy_vals(blkid_probe pr, struct blkid_chain *chn, - struct blkid_prval *vals, int nvals); -extern struct blkid_prval *blkid_probe_assign_value(blkid_probe pr, const char *name); -extern int blkid_probe_reset_last_value(blkid_probe pr); -extern void blkid_probe_append_vals(blkid_probe pr, struct blkid_prval *vals, int nvals); - -extern struct blkid_chain *blkid_probe_get_chain(blkid_probe pr); - -extern struct blkid_prval *__blkid_probe_get_value(blkid_probe pr, int num); -extern struct blkid_prval *__blkid_probe_lookup_value(blkid_probe pr, const char *name); - -extern unsigned long *blkid_probe_get_filter(blkid_probe pr, int chain, int create); -extern int __blkid_probe_invert_filter(blkid_probe pr, int chain); -extern int __blkid_probe_reset_filter(blkid_probe pr, int chain); -extern int __blkid_probe_filter_types(blkid_probe pr, int chain, int flag, char *names[]); - -extern void *blkid_probe_get_binary_data(blkid_probe pr, struct blkid_chain *chn); - -extern int blkid_probe_set_value(blkid_probe pr, const char *name, - unsigned char *data, size_t len); -extern int blkid_probe_vsprintf_value(blkid_probe pr, const char *name, - const char *fmt, va_list ap); -extern int blkid_probe_sprintf_value(blkid_probe pr, const char *name, - const char *fmt, ...); - -extern void blkid_unparse_uuid(const unsigned char *uuid, char *str, size_t len); -extern size_t blkid_rtrim_whitespace(unsigned char *str); - -extern void blkid_probe_set_wiper(blkid_probe pr, blkid_loff_t off, - blkid_loff_t size); -extern int blkid_probe_is_wiped(blkid_probe pr, struct blkid_chain **chn, - blkid_loff_t off, blkid_loff_t size); -extern void blkid_probe_use_wiper(blkid_probe pr, blkid_loff_t off, blkid_loff_t size); - -/* filter bitmap macros */ -#define blkid_bmp_wordsize (8 * sizeof(unsigned long)) -#define blkid_bmp_idx_bit(item) (1UL << ((item) % blkid_bmp_wordsize)) -#define blkid_bmp_idx_byte(item) ((item) / blkid_bmp_wordsize) - -#define blkid_bmp_set_item(bmp, item) \ - ((bmp)[ blkid_bmp_idx_byte(item) ] |= blkid_bmp_idx_bit(item)) - -#define blkid_bmp_unset_item(bmp, item) \ - ((bmp)[ blkid_bmp_idx_byte(item) ] &= ~blkid_bmp_idx_bit(item)) - -#define blkid_bmp_get_item(bmp, item) \ - ((bmp)[ blkid_bmp_idx_byte(item) ] & blkid_bmp_idx_bit(item)) - -#define blkid_bmp_nwords(max_items) \ - (((max_items) + blkid_bmp_wordsize) / blkid_bmp_wordsize) - -#define blkid_bmp_nbytes(max_items) \ - (blkid_bmp_nwords(max_items) * sizeof(unsigned long)) - -/* encode.c */ -extern size_t blkid_encode_to_utf8(int enc, unsigned char *dest, size_t len, - const unsigned char *src, size_t count); - -#define BLKID_ENC_UTF16BE 0 -#define BLKID_ENC_UTF16LE 1 - -#endif /* _BLKID_BLKIDP_H */ diff --git a/shlibs/blkid/src/cache.c b/shlibs/blkid/src/cache.c deleted file mode 100644 index feec6ddf..00000000 --- a/shlibs/blkid/src/cache.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * cache.c - allocation/initialization/free routines for cache - * - * Copyright (C) 2001 Andreas Dilger - * Copyright (C) 2003 Theodore Ts'o - * - * %Begin-Header% - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * %End-Header% - */ - -#if HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#include -#include -#ifdef HAVE_SYS_STAT_H -#include -#endif -#include "blkidP.h" -#include "env.h" - -int blkid_debug_mask = 0; - -/** - * SECTION:cache - * @title: Cache - * @short_description: basic routines to work with libblkid cache - * - * Block device information is normally kept in a cache file /etc/blkid.tab and is - * verified to still be valid before being returned to the user (if the user has - * read permission on the raw block device, otherwise not). The cache file also - * allows unprivileged users (normally anyone other than root, or those not in the - * "disk" group) to locate devices by label/id. The standard location of the - * cache file can be overridden by the environment variable BLKID_FILE. - * - * In situations where one is getting information about a single known device, it - * does not impact performance whether the cache is used or not (unless you are - * not able to read the block device directly). If you are dealing with multiple - * devices, use of the cache is highly recommended (even if empty) as devices will - * be scanned at most one time and the on-disk cache will be updated if possible. - * There is rarely a reason not to use the cache. - * - * In some cases (modular kernels), block devices are not even visible until after - * they are accessed the first time, so it is critical that there is some way to - * locate these devices without enumerating only visible devices, so the use of - * the cache file is required in this situation. - */ - -#if 0 /* ifdef CONFIG_BLKID_DEBUG */ -static blkid_debug_dump_cache(int mask, blkid_cache cache) -{ - struct list_head *p; - - if (!cache) { - printf("cache: NULL\n"); - return; - } - - printf("cache: time = %lu\n", cache->bic_time); - printf("cache: flags = 0x%08X\n", cache->bic_flags); - - list_for_each(p, &cache->bic_devs) { - blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs); - blkid_debug_dump_dev(dev); - } -} -#endif - -#ifdef CONFIG_BLKID_DEBUG -void blkid_init_debug(int mask) -{ - if (blkid_debug_mask & DEBUG_INIT) - return; - - if (!mask) - { - char *dstr = getenv("LIBBLKID_DEBUG"); - - if (!dstr) - dstr = getenv("BLKID_DEBUG"); /* for backward compatibility */ - if (dstr) - blkid_debug_mask = strtoul(dstr, 0, 0); - } else - blkid_debug_mask = mask; - - if (blkid_debug_mask) - printf("libblkid: debug mask set to 0x%04x.\n", blkid_debug_mask); - - blkid_debug_mask |= DEBUG_INIT; -} -#endif - -/* returns allocated path to cache */ -char *blkid_get_cache_filename(struct blkid_config *conf) -{ - char *filename; - - filename = safe_getenv("BLKID_FILE"); - if (filename) - filename = blkid_strdup(filename); - else if (conf) - filename = blkid_strdup(conf->cachefile); - else { - struct blkid_config *c = blkid_read_config(NULL); - if (!c) - filename = blkid_strdup(BLKID_CACHE_FILE); - else { - filename = c->cachefile; /* already allocated */ - c->cachefile = NULL; - blkid_free_config(c); - } - } - return filename; -} - -/** - * blkid_get_cache: - * @cache: pointer to return cache handler - * @filename: path to the cache file or NULL for the default path - * - * Allocates and initialize librray cache handler. - * - * Returns: 0 on success or number less than zero in case of error. - */ -int blkid_get_cache(blkid_cache *ret_cache, const char *filename) -{ - blkid_cache cache; - - blkid_init_debug(0); - - DBG(DEBUG_CACHE, printf("creating blkid cache (using %s)\n", - filename ? filename : "default cache")); - - if (!(cache = (blkid_cache) calloc(1, sizeof(struct blkid_struct_cache)))) - return -BLKID_ERR_MEM; - - INIT_LIST_HEAD(&cache->bic_devs); - INIT_LIST_HEAD(&cache->bic_tags); - - if (filename && !*filename) - filename = NULL; - if (filename) - cache->bic_filename = blkid_strdup(filename); - else - cache->bic_filename = blkid_get_cache_filename(NULL); - - blkid_read_cache(cache); - *ret_cache = cache; - return 0; -} - -/** - * blkid_put_cache: - * @cache: cache handler - * - * Saves changes to cache file. - */ -void blkid_put_cache(blkid_cache cache) -{ - if (!cache) - return; - - (void) blkid_flush_cache(cache); - - DBG(DEBUG_CACHE, printf("freeing cache struct\n")); - - /* DBG(DEBUG_CACHE, blkid_debug_dump_cache(cache)); */ - - while (!list_empty(&cache->bic_devs)) { - blkid_dev dev = list_entry(cache->bic_devs.next, - struct blkid_struct_dev, - bid_devs); - blkid_free_dev(dev); - } - - while (!list_empty(&cache->bic_tags)) { - blkid_tag tag = list_entry(cache->bic_tags.next, - struct blkid_struct_tag, - bit_tags); - - while (!list_empty(&tag->bit_names)) { - blkid_tag bad = list_entry(tag->bit_names.next, - struct blkid_struct_tag, - bit_names); - - DBG(DEBUG_CACHE, printf("warning: unfreed tag %s=%s\n", - bad->bit_name, bad->bit_val)); - blkid_free_tag(bad); - } - blkid_free_tag(tag); - } - - blkid_free_probe(cache->probe); - - free(cache->bic_filename); - free(cache); -} - -/** - * blkid_gc_cache: - * @cache: cache handler - * - * Removes garbage (non-existing devices) from the cache. - */ -void blkid_gc_cache(blkid_cache cache) -{ - struct list_head *p, *pnext; - struct stat st; - - if (!cache) - return; - - list_for_each_safe(p, pnext, &cache->bic_devs) { - blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs); - if (!p) - break; - if (stat(dev->bid_name, &st) < 0) { - DBG(DEBUG_CACHE, - printf("freeing %s\n", dev->bid_name)); - blkid_free_dev(dev); - cache->bic_flags |= BLKID_BIC_FL_CHANGED; - } else { - DBG(DEBUG_CACHE, - printf("Device %s exists\n", dev->bid_name)); - } - } -} - -#ifdef TEST_PROGRAM -int main(int argc, char** argv) -{ - blkid_cache cache = NULL; - int ret; - - blkid_init_debug(DEBUG_ALL); - - if ((argc > 2)) { - fprintf(stderr, "Usage: %s [filename] \n", argv[0]); - exit(1); - } - - if ((ret = blkid_get_cache(&cache, argv[1])) < 0) { - fprintf(stderr, "error %d parsing cache file %s\n", ret, - argv[1] ? argv[1] : BLKID_CACHE_FILE); - exit(1); - } - if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) { - fprintf(stderr, "%s: error creating cache (%d)\n", - argv[0], ret); - exit(1); - } - if ((ret = blkid_probe_all(cache) < 0)) - fprintf(stderr, "error probing devices\n"); - - blkid_put_cache(cache); - - return ret; -} -#endif diff --git a/shlibs/blkid/src/config.c b/shlibs/blkid/src/config.c deleted file mode 100644 index 110251a9..00000000 --- a/shlibs/blkid/src/config.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * config.c - blkid.conf routines - * - * Copyright (C) 2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#include -#include - -#include "blkidP.h" -#include "env.h" - -static int parse_evaluate(struct blkid_config *conf, char *s) -{ - while(s && *s) { - char *sep; - - if (conf->nevals >= __BLKID_EVAL_LAST) - goto err; - sep = strchr(s, ','); - if (sep) - *sep = '\0'; - if (strcmp(s, "udev") == 0) - conf->eval[conf->nevals] = BLKID_EVAL_UDEV; - else if (strcmp(s, "scan") == 0) - conf->eval[conf->nevals] = BLKID_EVAL_SCAN; - else - goto err; - conf->nevals++; - if (sep) - s = sep + 1; - else - break; - } - return 0; -err: - DBG(DEBUG_CONFIG, printf( - "config file: unknown evaluation method '%s'.\n", s)); - return -1; -} - -static int parse_next(FILE *fd, struct blkid_config *conf) -{ - char buf[BUFSIZ]; - char *s; - - /* read the next non-blank non-comment line */ - do { - if (fgets (buf, sizeof(buf), fd) == NULL) - return feof(fd) ? 0 : -1; - s = strchr (buf, '\n'); - if (!s) { - /* Missing final newline? Otherwise extremely */ - /* long line - assume file was corrupted */ - if (feof(fd)) - s = strchr (buf, '\0'); - else { - DBG(DEBUG_CONFIG, fprintf(stderr, - "libblkid: config file: missing newline at line '%s'.\n", - buf)); - return -1; - } - } - *s = '\0'; - if (--s >= buf && *s == '\r') - *s = '\0'; - - s = buf; - while (*s == ' ' || *s == '\t') /* skip space */ - s++; - - } while (*s == '\0' || *s == '#'); - - if (!strncmp(s, "SEND_UEVENT=", 12)) { - s += 13; - if (*s && !strcasecmp(s, "yes")) - conf->uevent = TRUE; - else if (*s) - conf->uevent = FALSE; - } else if (!strncmp(s, "CACHE_FILE=", 11)) { - s += 11; - if (*s) - conf->cachefile = blkid_strdup(s); - } else if (!strncmp(s, "EVALUATE=", 9)) { - s += 9; - if (*s && parse_evaluate(conf, s) == -1) - return -1; - } else { - DBG(DEBUG_CONFIG, printf( - "config file: unknown option '%s'.\n", s)); - return -1; - } - return 0; -} - -/* return real config data or built-in default */ -struct blkid_config *blkid_read_config(const char *filename) -{ - struct blkid_config *conf; - FILE *f; - - if (!filename) - filename = safe_getenv("BLKID_CONF"); - if (!filename) - filename = BLKID_CONFIG_FILE; - - conf = (struct blkid_config *) calloc(1, sizeof(*conf)); - if (!conf) - return NULL; - conf->uevent = -1; - - DBG(DEBUG_CONFIG, fprintf(stderr, - "reading config file: %s.\n", filename)); - - f = fopen(filename, "r"); - if (!f) { - DBG(DEBUG_CONFIG, fprintf(stderr, - "%s: does not exist, using built-in default\n", filename)); - goto dflt; - } - while (!feof(f)) { - if (parse_next(f, conf)) { - DBG(DEBUG_CONFIG, fprintf(stderr, - "%s: parse error\n", filename)); - goto err; - } - } -dflt: - if (!conf->nevals) { - conf->eval[0] = BLKID_EVAL_UDEV; - conf->eval[1] = BLKID_EVAL_SCAN; - conf->nevals = 2; - } - if (!conf->cachefile) - conf->cachefile = blkid_strdup(BLKID_CACHE_FILE); - if (conf->uevent == -1) - conf->uevent = TRUE; - if (f) - fclose(f); - return conf; -err: - free(conf); - fclose(f); - return NULL; -} - -void blkid_free_config(struct blkid_config *conf) -{ - if (!conf) - return; - free(conf->cachefile); - free(conf); -} - -#ifdef TEST_PROGRAM -/* - * usage: tst_config [] - */ -int main(int argc, char *argv[]) -{ - int i; - struct blkid_config *conf; - char *filename = NULL; - - blkid_init_debug(DEBUG_ALL); - - if (argc == 2) - filename = argv[1]; - - conf = blkid_read_config(filename); - if (!conf) - return EXIT_FAILURE; - - printf("EVALUATE: "); - for (i = 0; i < conf->nevals; i++) - printf("%s ", conf->eval[i] == BLKID_EVAL_UDEV ? "udev" : "scan"); - printf("\n"); - - printf("SEND UEVENT: %s\n", conf->uevent ? "TRUE" : "FALSE"); - printf("CACHE_FILE: %s\n", conf->cachefile); - - blkid_free_config(conf); - return EXIT_SUCCESS; -} -#endif diff --git a/shlibs/blkid/src/dev.c b/shlibs/blkid/src/dev.c deleted file mode 100644 index 791a6c18..00000000 --- a/shlibs/blkid/src/dev.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * dev.c - allocation/initialization/free routines for dev - * - * Copyright (C) 2001 Andreas Dilger - * Copyright (C) 2003 Theodore Ts'o - * - * %Begin-Header% - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * %End-Header% - */ - -#include -#include - -#include "blkidP.h" - -/* - * NOTE: reference manual is not structured as code. The following section is a generic - * section for all high-level cache search+iterate routines. - */ - -/** - * SECTION:search - * @title: Search and iterate - * @short_description: search devices and iterate over devices in the cache. - * - * Note that high-level probing API provides information about superblocks - * (filesystems/raids) only. For partitions and topology is necessary to use - * the low-level API. - */ - -blkid_dev blkid_new_dev(void) -{ - blkid_dev dev; - - if (!(dev = (blkid_dev) calloc(1, sizeof(struct blkid_struct_dev)))) - return NULL; - - INIT_LIST_HEAD(&dev->bid_devs); - INIT_LIST_HEAD(&dev->bid_tags); - - return dev; -} - -void blkid_free_dev(blkid_dev dev) -{ - if (!dev) - return; - - DBG(DEBUG_DEV, - printf(" freeing dev %s (%s)\n", dev->bid_name, dev->bid_type ? - dev->bid_type : "(null)")); - DBG(DEBUG_DEV, blkid_debug_dump_dev(dev)); - - list_del(&dev->bid_devs); - while (!list_empty(&dev->bid_tags)) { - blkid_tag tag = list_entry(dev->bid_tags.next, - struct blkid_struct_tag, - bit_tags); - blkid_free_tag(tag); - } - free(dev->bid_name); - free(dev); -} - -/* - * Given a blkid device, return its name - */ -extern const char *blkid_dev_devname(blkid_dev dev) -{ - return dev->bid_name; -} - -#ifdef CONFIG_BLKID_DEBUG -void blkid_debug_dump_dev(blkid_dev dev) -{ - struct list_head *p; - - if (!dev) { - printf(" dev: NULL\n"); - return; - } - - printf(" dev: name = %s\n", dev->bid_name); - printf(" dev: DEVNO=\"0x%0llx\"\n", (long long)dev->bid_devno); - printf(" dev: TIME=\"%ld.%ld\"\n", (long)dev->bid_time, (long)dev->bid_utime); - printf(" dev: PRI=\"%d\"\n", dev->bid_pri); - printf(" dev: flags = 0x%08X\n", dev->bid_flags); - - list_for_each(p, &dev->bid_tags) { - blkid_tag tag = list_entry(p, struct blkid_struct_tag, bit_tags); - if (tag) - printf(" tag: %s=\"%s\"\n", tag->bit_name, - tag->bit_val); - else - printf(" tag: NULL\n"); - } - printf("\n"); -} -#endif - -/* - * dev iteration routines for the public libblkid interface. - * - * These routines do not expose the list.h implementation, which are a - * contamination of the namespace, and which force us to reveal far, far - * too much of our internal implemenation. I'm not convinced I want - * to keep list.h in the long term, anyway. It's fine for kernel - * programming, but performance is not the #1 priority for this - * library, and I really don't like the tradeoff of type-safety for - * performance for this application. [tytso:20030125.2007EST] - */ - -/* - * This series of functions iterate over all devices in a blkid cache - */ -#define DEV_ITERATE_MAGIC 0x01a5284c - -struct blkid_struct_dev_iterate { - int magic; - blkid_cache cache; - char *search_type; - char *search_value; - struct list_head *p; -}; - -extern blkid_dev_iterate blkid_dev_iterate_begin(blkid_cache cache) -{ - blkid_dev_iterate iter; - - iter = malloc(sizeof(struct blkid_struct_dev_iterate)); - if (iter) { - iter->magic = DEV_ITERATE_MAGIC; - iter->cache = cache; - iter->p = cache->bic_devs.next; - iter->search_type = 0; - iter->search_value = 0; - } - return (iter); -} - -extern int blkid_dev_set_search(blkid_dev_iterate iter, - char *search_type, char *search_value) -{ - char *new_type, *new_value; - - if (!iter || iter->magic != DEV_ITERATE_MAGIC || !search_type || - !search_value) - return -1; - new_type = malloc(strlen(search_type)+1); - new_value = malloc(strlen(search_value)+1); - if (!new_type || !new_value) { - free(new_type); - free(new_value); - return -1; - } - strcpy(new_type, search_type); - strcpy(new_value, search_value); - free(iter->search_type); - free(iter->search_value); - iter->search_type = new_type; - iter->search_value = new_value; - return 0; -} - -/* - * Return 0 on success, -1 on error - */ -extern int blkid_dev_next(blkid_dev_iterate iter, - blkid_dev *ret_dev) -{ - blkid_dev dev; - - *ret_dev = 0; - if (!iter || iter->magic != DEV_ITERATE_MAGIC) - return -1; - while (iter->p != &iter->cache->bic_devs) { - dev = list_entry(iter->p, struct blkid_struct_dev, bid_devs); - iter->p = iter->p->next; - if (iter->search_type && - !blkid_dev_has_tag(dev, iter->search_type, - iter->search_value)) - continue; - *ret_dev = dev; - return 0; - } - return -1; -} - -extern void blkid_dev_iterate_end(blkid_dev_iterate iter) -{ - if (!iter || iter->magic != DEV_ITERATE_MAGIC) - return; - iter->magic = 0; - free(iter->search_type); - free(iter->search_value); - free(iter); -} - -#ifdef TEST_PROGRAM -#ifdef HAVE_GETOPT_H -#include -#else -extern char *optarg; -extern int optind; -#endif - -void usage(char *prog) -{ - fprintf(stderr, "Usage: %s [-f blkid_file] [-m debug_mask]\n", prog); - fprintf(stderr, "\tList all devices and exit\n"); - exit(1); -} - -int main(int argc, char **argv) -{ - blkid_dev_iterate iter; - blkid_cache cache = NULL; - blkid_dev dev; - int c, ret; - char *tmp; - char *file = NULL; - char *search_type = NULL; - char *search_value = NULL; - - while ((c = getopt (argc, argv, "m:f:")) != EOF) - switch (c) { - case 'f': - file = optarg; - break; - case 'm': - { - int mask = strtoul (optarg, &tmp, 0); - if (*tmp) { - fprintf(stderr, "Invalid debug mask: %s\n", - optarg); - exit(1); - } - blkid_init_debug(mask); - break; - } - case '?': - usage(argv[0]); - } - if (argc >= optind+2) { - search_type = argv[optind]; - search_value = argv[optind+1]; - optind += 2; - } - if (argc != optind) - usage(argv[0]); - - if ((ret = blkid_get_cache(&cache, file)) != 0) { - fprintf(stderr, "%s: error creating cache (%d)\n", - argv[0], ret); - exit(1); - } - - iter = blkid_dev_iterate_begin(cache); - if (search_type) - blkid_dev_set_search(iter, search_type, search_value); - while (blkid_dev_next(iter, &dev) == 0) { - printf("Device: %s\n", blkid_dev_devname(dev)); - } - blkid_dev_iterate_end(iter); - - - blkid_put_cache(cache); - return (0); -} -#endif diff --git a/shlibs/blkid/src/devname.c b/shlibs/blkid/src/devname.c deleted file mode 100644 index e1fc2c84..00000000 --- a/shlibs/blkid/src/devname.c +++ /dev/null @@ -1,680 +0,0 @@ -/* - * devname.c - get a dev by its device inode name - * - * Copyright (C) Andries Brouwer - * Copyright (C) 1999, 2000, 2001, 2002, 2003 Theodore Ts'o - * Copyright (C) 2001 Andreas Dilger - * - * %Begin-Header% - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * %End-Header% - */ - -#define _GNU_SOURCE 1 - -#include -#include -#include -#if HAVE_UNISTD_H -#include -#endif -#include -#include -#include -#if HAVE_SYS_TYPES_H -#include -#endif -#include -#if HAVE_SYS_STAT_H -#include -#endif -#if HAVE_ERRNO_H -#include -#endif -#include - -#include "blkidP.h" - -#include "canonicalize.h" /* $(top_srcdir)/include */ -#include "pathnames.h" -#include "sysfs.h" -#include "at.h" - -/* - * Find a dev struct in the cache by device name, if available. - * - * If there is no entry with the specified device name, and the create - * flag is set, then create an empty device entry. - */ -blkid_dev blkid_get_dev(blkid_cache cache, const char *devname, int flags) -{ - blkid_dev dev = NULL, tmp; - struct list_head *p, *pnext; - - if (!cache || !devname) - return NULL; - - list_for_each(p, &cache->bic_devs) { - tmp = list_entry(p, struct blkid_struct_dev, bid_devs); - if (strcmp(tmp->bid_name, devname)) - continue; - - DBG(DEBUG_DEVNAME, - printf("found devname %s in cache\n", tmp->bid_name)); - dev = tmp; - break; - } - - if (!dev && (flags & BLKID_DEV_CREATE)) { - if (access(devname, F_OK) < 0) - return NULL; - dev = blkid_new_dev(); - if (!dev) - return NULL; - dev->bid_time = INT_MIN; - dev->bid_name = blkid_strdup(devname); - dev->bid_cache = cache; - list_add_tail(&dev->bid_devs, &cache->bic_devs); - cache->bic_flags |= BLKID_BIC_FL_CHANGED; - } - - if (flags & BLKID_DEV_VERIFY) { - dev = blkid_verify(cache, dev); - if (!dev || !(dev->bid_flags & BLKID_BID_FL_VERIFIED)) - return dev; - /* - * If the device is verified, then search the blkid - * cache for any entries that match on the type, uuid, - * and label, and verify them; if a cache entry can - * not be verified, then it's stale and so we remove - * it. - */ - list_for_each_safe(p, pnext, &cache->bic_devs) { - blkid_dev dev2; - if (!p) - break; - dev2 = list_entry(p, struct blkid_struct_dev, bid_devs); - if (dev2->bid_flags & BLKID_BID_FL_VERIFIED) - continue; - if (!dev->bid_type || !dev2->bid_type || - strcmp(dev->bid_type, dev2->bid_type)) - continue; - if (dev->bid_label && dev2->bid_label && - strcmp(dev->bid_label, dev2->bid_label)) - continue; - if (dev->bid_uuid && dev2->bid_uuid && - strcmp(dev->bid_uuid, dev2->bid_uuid)) - continue; - if ((dev->bid_label && !dev2->bid_label) || - (!dev->bid_label && dev2->bid_label) || - (dev->bid_uuid && !dev2->bid_uuid) || - (!dev->bid_uuid && dev2->bid_uuid)) - continue; - dev2 = blkid_verify(cache, dev2); - if (dev2 && !(dev2->bid_flags & BLKID_BID_FL_VERIFIED)) - blkid_free_dev(dev2); - } - } - return dev; -} - -/* Directories where we will try to search for device names */ -static const char *dirlist[] = { "/dev", "/devfs", "/devices", NULL }; - -static int is_dm_leaf(const char *devname) -{ - struct dirent *de, *d_de; - DIR *dir, *d_dir; - char path[256]; - int ret = 1; - - if ((dir = opendir("/sys/block")) == NULL) - return 0; - while ((de = readdir(dir)) != NULL) { - if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..") || - !strcmp(de->d_name, devname) || - strncmp(de->d_name, "dm-", 3) || - strlen(de->d_name) > sizeof(path)-32) - continue; - sprintf(path, "/sys/block/%s/slaves", de->d_name); - if ((d_dir = opendir(path)) == NULL) - continue; - while ((d_de = readdir(d_dir)) != NULL) { - if (!strcmp(d_de->d_name, devname)) { - ret = 0; - break; - } - } - closedir(d_dir); - if (!ret) - break; - } - closedir(dir); - return ret; -} - -/* - * Probe a single block device to add to the device cache. - */ -static void probe_one(blkid_cache cache, const char *ptname, - dev_t devno, int pri, int only_if_new, int removable) -{ - blkid_dev dev = NULL; - struct list_head *p, *pnext; - const char **dir; - char *devname = NULL; - - /* See if we already have this device number in the cache. */ - list_for_each_safe(p, pnext, &cache->bic_devs) { - blkid_dev tmp = list_entry(p, struct blkid_struct_dev, - bid_devs); - if (tmp->bid_devno == devno) { - if (only_if_new && !access(tmp->bid_name, F_OK)) - return; - dev = blkid_verify(cache, tmp); - if (dev && (dev->bid_flags & BLKID_BID_FL_VERIFIED)) - break; - dev = 0; - } - } - if (dev && dev->bid_devno == devno) - goto set_pri; - - /* Try to translate private device-mapper dm- names - * to standard /dev/mapper/. - */ - if (!strncmp(ptname, "dm-", 3) && isdigit(ptname[3])) { - devname = canonicalize_dm_name(ptname); - if (!devname) - blkid__scan_dir("/dev/mapper", devno, 0, &devname); - if (devname) - goto get_dev; - } - - /* - * Take a quick look at /dev/ptname for the device number. We check - * all of the likely device directories. If we don't find it, or if - * the stat information doesn't check out, use blkid_devno_to_devname() - * to find it via an exhaustive search for the device major/minor. - */ - for (dir = dirlist; *dir; dir++) { - struct stat st; - char device[256]; - - sprintf(device, "%s/%s", *dir, ptname); - if ((dev = blkid_get_dev(cache, device, BLKID_DEV_FIND)) && - dev->bid_devno == devno) - goto set_pri; - - if (stat(device, &st) == 0 && - (S_ISBLK(st.st_mode) || - (S_ISCHR(st.st_mode) && !strncmp(ptname, "ubi", 3))) && - st.st_rdev == devno) { - devname = blkid_strdup(device); - goto get_dev; - } - } - /* Do a short-cut scan of /dev/mapper first */ - if (!devname) - blkid__scan_dir("/dev/mapper", devno, 0, &devname); - if (!devname) { - devname = blkid_devno_to_devname(devno); - if (!devname) - return; - } - -get_dev: - dev = blkid_get_dev(cache, devname, BLKID_DEV_NORMAL); - free(devname); - -set_pri: - if (dev) { - if (pri) - dev->bid_pri = pri; - else if (!strncmp(dev->bid_name, "/dev/mapper/", 11)) { - dev->bid_pri = BLKID_PRI_DM; - if (is_dm_leaf(ptname)) - dev->bid_pri += 5; - } else if (!strncmp(ptname, "md", 2)) - dev->bid_pri = BLKID_PRI_MD; - if (removable) - dev->bid_flags |= BLKID_BID_FL_REMOVABLE; - } - return; -} - -#define PROC_PARTITIONS "/proc/partitions" -#define VG_DIR "/proc/lvm/VGs" - -/* - * This function initializes the UUID cache with devices from the LVM - * proc hierarchy. We currently depend on the names of the LVM - * hierarchy giving us the device structure in /dev. (XXX is this a - * safe thing to do?) - */ -#ifdef VG_DIR -static dev_t lvm_get_devno(const char *lvm_device) -{ - FILE *lvf; - char buf[1024]; - int ma, mi; - dev_t ret = 0; - - DBG(DEBUG_DEVNAME, printf("opening %s\n", lvm_device)); - if ((lvf = fopen(lvm_device, "r")) == NULL) { - DBG(DEBUG_DEVNAME, printf("%s: (%d) %s\n", lvm_device, errno, - strerror(errno))); - return 0; - } - - while (fgets(buf, sizeof(buf), lvf)) { - if (sscanf(buf, "device: %d:%d", &ma, &mi) == 2) { - ret = makedev(ma, mi); - break; - } - } - fclose(lvf); - - return ret; -} - -static void lvm_probe_all(blkid_cache cache, int only_if_new) -{ - DIR *vg_list; - struct dirent *vg_iter; - int vg_len = strlen(VG_DIR); - dev_t dev; - - if ((vg_list = opendir(VG_DIR)) == NULL) - return; - - DBG(DEBUG_DEVNAME, printf("probing LVM devices under %s\n", VG_DIR)); - - while ((vg_iter = readdir(vg_list)) != NULL) { - DIR *lv_list; - char *vdirname; - char *vg_name; - struct dirent *lv_iter; - - vg_name = vg_iter->d_name; - if (!strcmp(vg_name, ".") || !strcmp(vg_name, "..")) - continue; - vdirname = malloc(vg_len + strlen(vg_name) + 8); - if (!vdirname) - goto exit; - sprintf(vdirname, "%s/%s/LVs", VG_DIR, vg_name); - - lv_list = opendir(vdirname); - free(vdirname); - if (lv_list == NULL) - continue; - - while ((lv_iter = readdir(lv_list)) != NULL) { - char *lv_name, *lvm_device; - - lv_name = lv_iter->d_name; - if (!strcmp(lv_name, ".") || !strcmp(lv_name, "..")) - continue; - - lvm_device = malloc(vg_len + strlen(vg_name) + - strlen(lv_name) + 8); - if (!lvm_device) { - closedir(lv_list); - goto exit; - } - sprintf(lvm_device, "%s/%s/LVs/%s", VG_DIR, vg_name, - lv_name); - dev = lvm_get_devno(lvm_device); - sprintf(lvm_device, "%s/%s", vg_name, lv_name); - DBG(DEBUG_DEVNAME, printf("LVM dev %s: devno 0x%04X\n", - lvm_device, - (unsigned int) dev)); - probe_one(cache, lvm_device, dev, BLKID_PRI_LVM, - only_if_new, 0); - free(lvm_device); - } - closedir(lv_list); - } -exit: - closedir(vg_list); -} -#endif - -#define PROC_EVMS_VOLUMES "/proc/evms/volumes" - -static int -evms_probe_all(blkid_cache cache, int only_if_new) -{ - char line[100]; - int ma, mi, sz, num = 0; - FILE *procpt; - char device[110]; - - procpt = fopen(PROC_EVMS_VOLUMES, "r"); - if (!procpt) - return 0; - while (fgets(line, sizeof(line), procpt)) { - if (sscanf (line, " %d %d %d %*s %*s %[^\n ]", - &ma, &mi, &sz, device) != 4) - continue; - - DBG(DEBUG_DEVNAME, printf("Checking partition %s (%d, %d)\n", - device, ma, mi)); - - probe_one(cache, device, makedev(ma, mi), BLKID_PRI_EVMS, - only_if_new, 0); - num++; - } - fclose(procpt); - return num; -} - -static void -ubi_probe_all(blkid_cache cache, int only_if_new) -{ - const char **dirname; - - for (dirname = dirlist; *dirname; dirname++) { - DBG(DEBUG_DEVNAME, printf("probing UBI volumes under %s\n", - *dirname)); - - DIR *dir; - struct dirent *iter; - - dir = opendir(*dirname); - if (dir == NULL) - continue ; - - while ((iter = readdir(dir)) != NULL) { - char *name; - struct stat st; - dev_t dev; - - name = iter->d_name; -#ifdef _DIRENT_HAVE_D_TYPE - if (iter->d_type != DT_UNKNOWN && - iter->d_type != DT_CHR && iter->d_type != DT_LNK) - continue; -#endif - if (!strcmp(name, ".") || !strcmp(name, "..") || - !strstr(name, "ubi")) - continue; - if (!strcmp(name, "ubi_ctrl")) - continue; - if (fstat_at(dirfd(dir), *dirname, name, &st, 0)) - continue; - - dev = st.st_rdev; - - if (!S_ISCHR(st.st_mode) || !minor(dev)) - continue; - DBG(DEBUG_DEVNAME, printf("UBI vol %s/%s: devno 0x%04X\n", - *dirname, name, (int) dev)); - probe_one(cache, name, dev, BLKID_PRI_UBI, only_if_new, 0); - } - closedir(dir); - } -} - -/* - * Read the device data for all available block devices in the system. - */ -static int probe_all(blkid_cache cache, int only_if_new) -{ - FILE *proc; - char line[1024]; - char ptname0[128], ptname1[128], *ptname = 0; - char *ptnames[2]; - dev_t devs[2]; - int ma, mi; - unsigned long long sz; - int lens[2] = { 0, 0 }; - int which = 0, last = 0; - struct list_head *p, *pnext; - - ptnames[0] = ptname0; - ptnames[1] = ptname1; - - if (!cache) - return -BLKID_ERR_PARAM; - - if (cache->bic_flags & BLKID_BIC_FL_PROBED && - time(0) - cache->bic_time < BLKID_PROBE_INTERVAL) - return 0; - - blkid_read_cache(cache); - evms_probe_all(cache, only_if_new); -#ifdef VG_DIR - lvm_probe_all(cache, only_if_new); -#endif - ubi_probe_all(cache, only_if_new); - - proc = fopen(PROC_PARTITIONS, "r"); - if (!proc) - return -BLKID_ERR_PROC; - - while (fgets(line, sizeof(line), proc)) { - last = which; - which ^= 1; - ptname = ptnames[which]; - - if (sscanf(line, " %d %d %llu %128[^\n ]", - &ma, &mi, &sz, ptname) != 4) - continue; - devs[which] = makedev(ma, mi); - - DBG(DEBUG_DEVNAME, printf("read partition name %s\n", ptname)); - - /* Skip whole disk devs unless they have no partitions. - * If base name of device has changed, also - * check previous dev to see if it didn't have a partn. - * heuristic: partition name ends in a digit, & partition - * names contain whole device name as substring. - * - * Skip extended partitions. - * heuristic: size is 1 - * - * FIXME: skip /dev/{ida,cciss,rd} whole-disk devs - */ - - lens[which] = strlen(ptname); - - /* ends in a digit, clearly a partition, so check */ - if (isdigit(ptname[lens[which] - 1])) { - DBG(DEBUG_DEVNAME, - printf("partition dev %s, devno 0x%04X\n", - ptname, (unsigned int) devs[which])); - - if (sz > 1) - probe_one(cache, ptname, devs[which], 0, - only_if_new, 0); - lens[which] = 0; /* mark as checked */ - } - - /* - * If last was a whole disk and we just found a partition - * on it, remove the whole-disk dev from the cache if - * it exists. - */ - if (lens[last] && !strncmp(ptnames[last], ptname, lens[last])) { - list_for_each_safe(p, pnext, &cache->bic_devs) { - blkid_dev tmp; - - /* find blkid dev for the whole-disk devno */ - tmp = list_entry(p, struct blkid_struct_dev, - bid_devs); - if (tmp->bid_devno == devs[last]) { - DBG(DEBUG_DEVNAME, - printf("freeing %s\n", - tmp->bid_name)); - blkid_free_dev(tmp); - cache->bic_flags |= BLKID_BIC_FL_CHANGED; - break; - } - } - lens[last] = 0; - } - /* - * If last was not checked because it looked like a whole-disk - * dev, and the device's base name has changed, - * check last as well. - */ - if (lens[last] && strncmp(ptnames[last], ptname, lens[last])) { - DBG(DEBUG_DEVNAME, - printf("whole dev %s, devno 0x%04X\n", - ptnames[last], (unsigned int) devs[last])); - probe_one(cache, ptnames[last], devs[last], 0, - only_if_new, 0); - lens[last] = 0; - } - } - - /* Handle the last device if it wasn't partitioned */ - if (lens[which]) - probe_one(cache, ptname, devs[which], 0, only_if_new, 0); - - fclose(proc); - blkid_flush_cache(cache); - return 0; -} - -/* Don't use it by default -- it's pretty slow (because cdroms, floppy, ...) - */ -static int probe_all_removable(blkid_cache cache) -{ - DIR *dir; - struct dirent *d; - - if (!cache) - return -BLKID_ERR_PARAM; - - dir = opendir(_PATH_SYS_BLOCK); - if (!dir) - return -BLKID_ERR_PROC; - - while((d = readdir(dir))) { - struct sysfs_cxt sysfs; - int removable = 0; - dev_t devno; - -#ifdef _DIRENT_HAVE_D_TYPE - if (d->d_type != DT_UNKNOWN && d->d_type != DT_LNK) - continue; -#endif - if (d->d_name[0] == '.' && - ((d->d_name[1] == 0) || - ((d->d_name[1] == '.') && (d->d_name[2] == 0)))) - continue; - - devno = sysfs_devname_to_devno(d->d_name, NULL); - if (!devno) - continue; - - if (sysfs_init(&sysfs, devno, NULL) == 0) { - sysfs_read_int(&sysfs, "removable", &removable); - sysfs_deinit(&sysfs); - } - - if (removable) - probe_one(cache, d->d_name, devno, 0, 0, 1); - } - - closedir(dir); - return 0; -} - - -/** - * blkid_probe_all: - * @cache: cache handler - * - * Probes all block devices. - * - * Returns: 0 on success, or number less than zero in case of error. - */ -int blkid_probe_all(blkid_cache cache) -{ - int ret; - - DBG(DEBUG_PROBE, printf("Begin blkid_probe_all()\n")); - ret = probe_all(cache, 0); - cache->bic_time = time(0); - cache->bic_flags |= BLKID_BIC_FL_PROBED; - DBG(DEBUG_PROBE, printf("End blkid_probe_all()\n")); - return ret; -} - -/** - * blkid_probe_all_new: - * @cache: cache handler - * - * Probes all new block devices. - * - * Returns: 0 on success, or number less than zero in case of error. - */ -int blkid_probe_all_new(blkid_cache cache) -{ - int ret; - - DBG(DEBUG_PROBE, printf("Begin blkid_probe_all_new()\n")); - ret = probe_all(cache, 1); - DBG(DEBUG_PROBE, printf("End blkid_probe_all_new()\n")); - return ret; -} - -/** - * blkid_probe_all_removable: - * @cache: cache handler - * - * The libblkid probing is based on devices from /proc/partitions by default. - * This file usually does not contain removable devices (e.g. CDROMs) and this kind - * of devices are invisible for libblkid. - * - * This function adds removable block devices to @cache (probing is based on - * information from the /sys directory). Don't forget that removable devices - * (floppies, CDROMs, ...) could be pretty slow. It's very bad idea to call - * this function by default. - * - * Note that devices which were detected by this function won't be written to - * blkid.tab cache file. - * - * Returns: 0 on success, or number less than zero in case of error. - */ -int blkid_probe_all_removable(blkid_cache cache) -{ - int ret; - - DBG(DEBUG_PROBE, printf("Begin blkid_probe_all_removable()\n")); - ret = probe_all_removable(cache); - DBG(DEBUG_PROBE, printf("End blkid_probe_all_removable()\n")); - return ret; -} - -#ifdef TEST_PROGRAM -int main(int argc, char **argv) -{ - blkid_cache cache = NULL; - int ret; - - blkid_init_debug(DEBUG_ALL); - if (argc != 1) { - fprintf(stderr, "Usage: %s\n" - "Probe all devices and exit\n", argv[0]); - exit(1); - } - if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) { - fprintf(stderr, "%s: error creating cache (%d)\n", - argv[0], ret); - exit(1); - } - if (blkid_probe_all(cache) < 0) - printf("%s: error probing devices\n", argv[0]); - - if (blkid_probe_all_removable(cache) < 0) - printf("%s: error probing removable devices\n", argv[0]); - - blkid_put_cache(cache); - return (0); -} -#endif diff --git a/shlibs/blkid/src/devno.c b/shlibs/blkid/src/devno.c deleted file mode 100644 index 9a356a84..00000000 --- a/shlibs/blkid/src/devno.c +++ /dev/null @@ -1,527 +0,0 @@ -/* - * devno.c - find a particular device by its device number (major/minor) - * - * Copyright (C) 2000, 2001, 2003 Theodore Ts'o - * Copyright (C) 2001 Andreas Dilger - * - * %Begin-Header% - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * %End-Header% - */ - -#include -#include -#if HAVE_UNISTD_H -#include -#endif -#include -#if HAVE_SYS_TYPES_H -#include -#endif -#if HAVE_SYS_STAT_H -#include -#endif -#include -#if HAVE_ERRNO_H -#include -#endif -#if HAVE_SYS_MKDEV_H -#include -#endif -#include -#include - -#include "blkidP.h" -#include "pathnames.h" -#include "at.h" -#include "sysfs.h" - -char *blkid_strndup(const char *s, int length) -{ - char *ret; - - if (!s) - return NULL; - - if (!length) - length = strlen(s); - - ret = malloc(length + 1); - if (ret) { - strncpy(ret, s, length); - ret[length] = '\0'; - } - return ret; -} - -char *blkid_strdup(const char *s) -{ - return blkid_strndup(s, 0); -} - -char *blkid_strconcat(const char *a, const char *b, const char *c) -{ - char *res, *p; - size_t len, al, bl, cl; - - al = a ? strlen(a) : 0; - bl = b ? strlen(b) : 0; - cl = c ? strlen(c) : 0; - - len = al + bl + cl; - if (!len) - return NULL; - p = res = malloc(len + 1); - if (!res) - return NULL; - if (al) { - memcpy(p, a, al); - p += al; - } - if (bl) { - memcpy(p, b, bl); - p += bl; - } - if (cl) { - memcpy(p, c, cl); - p += cl; - } - *p = '\0'; - return res; -} - -/* - * This function adds an entry to the directory list - */ -static void add_to_dirlist(const char *dir, const char *subdir, - struct dir_list **list) -{ - struct dir_list *dp; - - dp = malloc(sizeof(struct dir_list)); - if (!dp) - return; - dp->name = subdir ? blkid_strconcat(dir, "/", subdir) : - blkid_strdup(dir); - if (!dp->name) { - free(dp); - return; - } - dp->next = *list; - *list = dp; -} - -/* - * This function frees a directory list - */ -static void free_dirlist(struct dir_list **list) -{ - struct dir_list *dp, *next; - - for (dp = *list; dp; dp = next) { - next = dp->next; - free(dp->name); - free(dp); - } - *list = NULL; -} - -void blkid__scan_dir(char *dirname, dev_t devno, struct dir_list **list, - char **devname) -{ - DIR *dir; - struct dirent *dp; - struct stat st; - - if ((dir = opendir(dirname)) == NULL) - return; - - while ((dp = readdir(dir)) != 0) { -#ifdef _DIRENT_HAVE_D_TYPE - if (dp->d_type != DT_UNKNOWN && dp->d_type != DT_BLK && - dp->d_type != DT_LNK && dp->d_type != DT_DIR) - continue; -#endif - if (dp->d_name[0] == '.' && - ((dp->d_name[1] == 0) || - ((dp->d_name[1] == '.') && (dp->d_name[2] == 0)))) - continue; - - if (fstat_at(dirfd(dir), dirname, dp->d_name, &st, 0)) - continue; - - if (S_ISBLK(st.st_mode) && st.st_rdev == devno) { - *devname = blkid_strconcat(dirname, "/", dp->d_name); - DBG(DEBUG_DEVNO, - printf("found 0x%llx at %s\n", (long long)devno, - *devname)); - break; - } - - if (!list || !S_ISDIR(st.st_mode)) - continue; - - /* add subdirectory (but not symlink) to the list */ -#ifdef _DIRENT_HAVE_D_TYPE - if (dp->d_type == DT_LNK) - continue; - if (dp->d_type == DT_UNKNOWN) -#endif - { - if (fstat_at(dirfd(dir), dirname, dp->d_name, &st, 1) || - !S_ISDIR(st.st_mode)) - continue; /* symlink or lstat() failed */ - } - - if (*dp->d_name == '.' || ( -#ifdef _DIRENT_HAVE_D_TYPE - dp->d_type == DT_DIR && -#endif - strcmp(dp->d_name, "shm") == 0)) - /* ignore /dev/.{udev,mount,mdadm} and /dev/shm */ - continue; - - add_to_dirlist(dirname, dp->d_name, list); - } - closedir(dir); - return; -} - -/* Directories where we will try to search for device numbers */ -static const char *devdirs[] = { "/devices", "/devfs", "/dev", NULL }; - -/** - * SECTION: misc - * @title: Miscellaneous utils - * @short_description: mix of various utils for low-level and high-level API - */ - -/* returns basename and keeps dirname in the @path */ -static char *stripoff_last_component(char *path) -{ - char *p = strrchr(path, '/'); - - if (!p) - return NULL; - *p = '\0'; - return ++p; -} - -static char *scandev_devno_to_devpath(dev_t devno) -{ - struct dir_list *list = NULL, *new_list = NULL; - char *devname = NULL; - const char **dir; - - /* - * Add the starting directories to search in reverse order of - * importance, since we are using a stack... - */ - for (dir = devdirs; *dir; dir++) - add_to_dirlist(*dir, NULL, &list); - - while (list) { - struct dir_list *current = list; - - list = list->next; - DBG(DEBUG_DEVNO, printf("directory %s\n", current->name)); - blkid__scan_dir(current->name, devno, &new_list, &devname); - free(current->name); - free(current); - if (devname) - break; - /* - * If we're done checking at this level, descend to - * the next level of subdirectories. (breadth-first) - */ - if (list == NULL) { - list = new_list; - new_list = NULL; - } - } - free_dirlist(&list); - free_dirlist(&new_list); - - return devname; -} - -/** - * blkid_devno_to_devname: - * @devno: device number - * - * This function finds the pathname to a block device with a given - * device number. - * - * Returns: a pointer to allocated memory to the pathname on success, - * and NULL on failure. - */ -char *blkid_devno_to_devname(dev_t devno) -{ - char *path = NULL; - char buf[PATH_MAX]; - - path = sysfs_devno_to_devpath(devno, buf, sizeof(buf)); - if (path) - path = strdup(path); - if (!path) - path = scandev_devno_to_devpath(devno); - - if (!path) { - DBG(DEBUG_DEVNO, - printf("blkid: couldn't find devno 0x%04lx\n", - (unsigned long) devno)); - } else { - DBG(DEBUG_DEVNO, - printf("found devno 0x%04llx as %s\n", (long long)devno, path)); - } - - return path; -} - -static int get_dm_wholedisk(struct sysfs_cxt *cxt, char *diskname, - size_t len, dev_t *diskdevno) -{ - int rc = 0; - char *name; - - /* Note, sysfs_get_slave() returns the first slave only, - * if there is more slaves, then return NULL - */ - name = sysfs_get_slave(cxt); - if (!name) - return -1; - - if (diskname && len) { - strncpy(diskname, name, len); - diskname[len - 1] = '\0'; - } - - if (diskdevno) { - *diskdevno = sysfs_devname_to_devno(name, NULL); - if (!*diskdevno) - rc = -1; - } - - free(name); - return rc; -} - -/** - * blkid_devno_to_wholedisk: - * @dev: device number - * @diskname: buffer to return diskname (or NULL) - * @len: diskname buffer size (or 0) - * @diskdevno: pointer to returns devno of entire disk (or NULL) - * - * This function uses sysfs to convert the @devno device number to the *name* - * of the whole disk. The function DOES NOT return full device name. The @dev - * argument could be partition or whole disk -- both is converted. - * - * For example: sda1, 0x0801 --> sda, 0x0800 - * - * For conversion to the full disk *path* use blkid_devno_to_devname(), for - * example: - * - * - * - * - * dev_t dev = 0x0801, disk; // sda1 = 8:1 - * char *diskpath, diskname[32]; - * - * blkid_devno_to_wholedisk(dev, diskname, sizeof(diskname), &disk); - * diskpath = blkid_devno_to_devname(disk); - * - * // print "0x0801: sda, /dev/sda, 8:0 - * printf("0x%x: %s, %s, %d:%d\n", - * dev, diskname, diskpath, major(disk), minor(disk)); - * - * free(diskpath); - * - * - * - * - * Returns: 0 on success or -1 in case of error. - */ -int blkid_devno_to_wholedisk(dev_t dev, char *diskname, - size_t len, dev_t *diskdevno) -{ - struct sysfs_cxt cxt; - int is_part = 0; - - if (!dev || sysfs_init(&cxt, dev, NULL) != 0) - return -1; - - is_part = sysfs_has_attribute(&cxt, "partition"); - if (!is_part) { - /* - * Extra case for partitions mapped by device-mapper. - * - * All regualar partitions (added by BLKPG ioctl or kernel PT - * parser) have the /sys/.../partition file. The partitions - * mapped by DM don't have such file, but they have "part" - * prefix in DM UUID. - */ - char *uuid = sysfs_strdup(&cxt, "dm/uuid"); - char *tmp = uuid; - char *prefix = uuid ? strsep(&tmp, "-") : NULL; - - if (prefix && strncasecmp(prefix, "part", 4) == 0) - is_part = 1; - free(uuid); - - if (is_part && - get_dm_wholedisk(&cxt, diskname, len, diskdevno) == 0) - /* - * partitioned device, mapped by DM - */ - goto done; - - is_part = 0; - } - - if (!is_part) { - /* - * unpartitioned device - */ - if (diskname && len) { - if (!sysfs_get_devname(&cxt, diskname, len)) - goto err; - } - if (diskdevno) - *diskdevno = dev; - - } else { - /* - * partitioned device - * - readlink /sys/dev/block/8:1 = ../../block/sda/sda1 - * - dirname ../../block/sda/sda1 = ../../block/sda - * - basename ../../block/sda = sda - */ - char linkpath[PATH_MAX]; - char *name; - int linklen; - - linklen = sysfs_readlink(&cxt, NULL, - linkpath, sizeof(linkpath) - 1); - if (linklen < 0) - goto err; - linkpath[linklen] = '\0'; - - stripoff_last_component(linkpath); /* dirname */ - name = stripoff_last_component(linkpath); /* basename */ - if (!name) - goto err; - - if (diskname && len) { - strncpy(diskname, name, len); - diskname[len - 1] = '\0'; - } - - if (diskdevno) { - *diskdevno = sysfs_devname_to_devno(name, NULL); - if (!*diskdevno) - goto err; - } - } - -done: - sysfs_deinit(&cxt); - - DBG(DEBUG_DEVNO, - printf("found entire diskname for devno 0x%04llx %s\n", - (long long) dev, diskname ? diskname : "")); - return 0; -err: - sysfs_deinit(&cxt); - - DBG(DEBUG_DEVNO, - printf("failed to convert 0x%04llx to wholedisk name, errno=%d\n", - (long long) dev, errno)); - return -1; -} - -/* - * Returns 1 if the @major number is associated with @drvname. - */ -int blkid_driver_has_major(const char *drvname, int major) -{ - FILE *f; - char buf[128]; - int match = 0; - - f = fopen(_PATH_PROC_DEVICES, "r"); - if (!f) - return 0; - - while (fgets(buf, sizeof(buf), f)) { /* skip to block dev section */ - if (strncmp("Block devices:\n", buf, sizeof(buf)) == 0) - break; - } - - while (fgets(buf, sizeof(buf), f)) { - unsigned int maj; - char name[64]; - - if (sscanf(buf, "%u %64[^\n ]", &maj, name) != 2) - continue; - - if (maj == major && strcmp(name, drvname) == 0) { - match = 1; - break; - } - } - - fclose(f); - - DBG(DEBUG_DEVNO, printf("major %d %s associated with '%s' driver\n", - major, match ? "is" : "is NOT", drvname)); - return match; -} - - -#ifdef TEST_PROGRAM -int main(int argc, char** argv) -{ - char *devname, *tmp; - char diskname[PATH_MAX]; - int major, minor; - dev_t devno, disk_devno; - const char *errmsg = "Couldn't parse %s: %s\n"; - - blkid_init_debug(DEBUG_ALL); - if ((argc != 2) && (argc != 3)) { - fprintf(stderr, "Usage:\t%s device_number\n\t%s major minor\n" - "Resolve a device number to a device name\n", - argv[0], argv[0]); - exit(1); - } - if (argc == 2) { - devno = strtoul(argv[1], &tmp, 0); - if (*tmp) { - fprintf(stderr, errmsg, "device number", argv[1]); - exit(1); - } - } else { - major = strtoul(argv[1], &tmp, 0); - if (*tmp) { - fprintf(stderr, errmsg, "major number", argv[1]); - exit(1); - } - minor = strtoul(argv[2], &tmp, 0); - if (*tmp) { - fprintf(stderr, errmsg, "minor number", argv[2]); - exit(1); - } - devno = makedev(major, minor); - } - printf("Looking for device 0x%04llx\n", (long long)devno); - devname = blkid_devno_to_devname(devno); - free(devname); - - printf("Looking for whole-device for 0x%04llx\n", (long long)devno); - blkid_devno_to_wholedisk(devno, diskname, sizeof(diskname), &disk_devno); - - return 0; -} -#endif diff --git a/shlibs/blkid/src/encode.c b/shlibs/blkid/src/encode.c deleted file mode 100644 index 03d5f4ef..00000000 --- a/shlibs/blkid/src/encode.c +++ /dev/null @@ -1,338 +0,0 @@ - -/* - * encode.c - string convertion routines (mostly for compatibility with - * udev/volume_id) - * - * Copyright (C) 2008 Kay Sievers - * Copyright (C) 2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include -#include -#include - -#include "blkidP.h" - -#define UDEV_ALLOWED_CHARS_INPUT "/ $%?," - -/** - * SECTION: encode - * @title: Encoding utils - * @short_description: encode strings to safe udev-compatible formats - * - */ - -/* 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 */ -static int 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; -} - -static int replace_whitespace(const char *str, char *to, size_t len) -{ - size_t i, j; - - /* strip trailing whitespace */ - len = strnlen(str, len); - while (len && isspace(str[len-1])) - len--; - - /* strip leading whitespace */ - i = 0; - while (isspace(str[i]) && (i < len)) - i++; - - j = 0; - while (i < len) { - /* substitute multiple whitespace with a single '_' */ - if (isspace(str[i])) { - while (isspace(str[i])) - i++; - to[j++] = '_'; - } - to[j++] = str[i++]; - } - to[j] = '\0'; - return 0; -} - -static int is_whitelisted(char c, const char *white) -{ - if ((c >= '0' && c <= '9') || - (c >= 'A' && c <= 'Z') || - (c >= 'a' && c <= 'z') || - strchr("#+-.:=@_", c) != NULL || - (white != NULL && strchr(white, c) != NULL)) - return 1; - return 0; -} - -/* allow chars in whitelist, plain ascii, hex-escaping and valid utf8 */ -static int replace_chars(char *str, const char *white) -{ - size_t i = 0; - int replaced = 0; - - while (str[i] != '\0') { - int len; - - if (is_whitelisted(str[i], white)) { - i++; - continue; - } - - /* accept hex encoding */ - if (str[i] == '\\' && str[i+1] == 'x') { - i += 2; - continue; - } - - /* accept valid utf8 */ - len = utf8_encoded_valid_unichar(&str[i]); - if (len > 1) { - i += len; - continue; - } - - /* if space is allowed, replace whitespace with ordinary space */ - if (isspace(str[i]) && white != NULL && strchr(white, ' ') != NULL) { - str[i] = ' '; - i++; - replaced++; - continue; - } - - /* everything else is replaced with '_' */ - str[i] = '_'; - i++; - replaced++; - } - return replaced; -} - -size_t blkid_encode_to_utf8(int enc, unsigned char *dest, size_t len, - const unsigned char *src, size_t count) -{ - size_t i, j; - uint16_t c; - - for (j = i = 0; i + 2 <= count; i += 2) { - if (enc == BLKID_ENC_UTF16LE) - c = (src[i+1] << 8) | src[i]; - else /* BLKID_ENC_UTF16BE */ - c = (src[i] << 8) | src[i+1]; - if (c == 0) { - dest[j] = '\0'; - break; - } else if (c < 0x80) { - if (j+1 >= len) - break; - dest[j++] = (uint8_t) c; - } else if (c < 0x800) { - if (j+2 >= len) - break; - dest[j++] = (uint8_t) (0xc0 | (c >> 6)); - dest[j++] = (uint8_t) (0x80 | (c & 0x3f)); - } else { - if (j+3 >= len) - break; - dest[j++] = (uint8_t) (0xe0 | (c >> 12)); - dest[j++] = (uint8_t) (0x80 | ((c >> 6) & 0x3f)); - dest[j++] = (uint8_t) (0x80 | (c & 0x3f)); - } - } - dest[j] = '\0'; - return j; -} - -/** - * blkid_encode_string: - * @str: input string to be encoded - * @str_enc: output string to store the encoded input string - * @len: maximum size of the output 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: 0 if the entire string was copied, non-zero otherwise. - **/ -int blkid_encode_string(const char *str, char *str_enc, size_t len) -{ - size_t i, j; - - if (str == NULL || str_enc == NULL) - return -1; - - for (i = 0, j = 0; str[i] != '\0'; i++) { - int seqlen; - - seqlen = utf8_encoded_valid_unichar(&str[i]); - if (seqlen > 1) { - if (len-j < (size_t)seqlen) - goto err; - memcpy(&str_enc[j], &str[i], seqlen); - j += seqlen; - i += (seqlen-1); - } else if (str[i] == '\\' || !is_whitelisted(str[i], NULL)) { - if (len-j < 4) - goto err; - sprintf(&str_enc[j], "\\x%02x", (unsigned char) str[i]); - j += 4; - } else { - if (len-j < 1) - goto err; - str_enc[j] = str[i]; - j++; - } - if (j+3 >= len) - goto err; - } - if (len-j < 1) - goto err; - str_enc[j] = '\0'; - return 0; -err: - return -1; -} - -/** - * blkid_safe_string: - * @str: input string - * @str_safe: output string - * @len: size of output string - * - * Allows plain ascii, hex-escaping and valid utf8. Replaces all whitespaces - * with '_'. - * - * Returns: 0 on success or -1 in case of error. - */ -int blkid_safe_string(const char *str, char *str_safe, size_t len) -{ - replace_whitespace(str, str_safe, len); - replace_chars(str_safe, UDEV_ALLOWED_CHARS_INPUT); - return 0; -} diff --git a/shlibs/blkid/src/evaluate.c b/shlibs/blkid/src/evaluate.c deleted file mode 100644 index 88c6830e..00000000 --- a/shlibs/blkid/src/evaluate.c +++ /dev/null @@ -1,315 +0,0 @@ -/* - * evaluate.c - very high-level API to evaluate LABELs or UUIDs - * - * Copyright (C) 2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#include -#include - -#include "pathnames.h" -#include "canonicalize.h" - -#include "blkidP.h" - -/** - * SECTION:evaluate - * @title: Tags evaluation - * @short_description: top-level API for LABEL and UUID evaluation. - * - * This API provides very simple and portable way how evaluate LABEL and UUID - * tags. The blkid_evaluate_tag() works on 2.4 and 2.6 systems and on systems - * with or without udev. Currently, the libblkid library supports "udev" and - * "scan" methods. The "udev" method uses udev /dev/disk/by-* symlinks and the - * "scan" method scans all block devices from the /proc/partitions file. The - * evaluation could be controlled by the /etc/blkid.conf config file. The - * default is to try "udev" and then "scan" method. - * - * The blkid_evaluate_tag() also automatically informs udevd when an obsolete - * /dev/disk/by-* symlink is detected. - * - * If you are not sure how translate LABEL or UUID to the device name use this - * API. - */ - -/* returns zero when the device has NAME=value (LABEL/UUID) */ -static int verify_tag(const char *devname, const char *name, const char *value) -{ - blkid_probe pr; - int fd = -1, rc = -1; - size_t len; - const char *data; - int errsv = 0; - - pr = blkid_new_probe(); - if (!pr) - return -1; - - blkid_probe_enable_superblocks(pr, TRUE); - blkid_probe_set_superblocks_flags(pr, - BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID); - - fd = open(devname, O_RDONLY); - if (fd < 0) { - errsv = errno; - goto done; - } - if (blkid_probe_set_device(pr, fd, 0, 0)) - goto done; - rc = blkid_do_safeprobe(pr); - if (rc) - goto done; - rc = blkid_probe_lookup_value(pr, name, &data, &len); - if (!rc) - rc = memcmp(value, data, len); -done: - DBG(DEBUG_EVALUATE, printf("%s: %s verification %s\n", - devname, name, rc == 0 ? "PASS" : "FAILED")); - if (fd >= 0) - close(fd); - blkid_free_probe(pr); - - /* for non-root users we use unverified udev links */ - return errsv == EACCES ? 0 : rc; -} - -/** - * blkid_send_uevent: - * @devname: absolute path to the device - * - * Returns: -1 in case of failure, or 0 on success. - */ -int blkid_send_uevent(const char *devname, const char *action) -{ - char uevent[PATH_MAX]; - struct stat st; - FILE *f; - int rc = -1; - - DBG(DEBUG_EVALUATE, printf("%s: uevent '%s' requested\n", devname, action)); - - if (!devname || !action) - return -1; - if (stat(devname, &st) || !S_ISBLK(st.st_mode)) - return -1; - - snprintf(uevent, sizeof(uevent), "/sys/dev/block/%d:%d/uevent", - major(st.st_rdev), minor(st.st_rdev)); - - f = fopen(uevent, "w"); - if (f) { - rc = 0; - if (fputs(action, f) >= 0) - rc = 0; - fclose(f); - } - DBG(DEBUG_EVALUATE, printf("%s: send uevent %s\n", - uevent, rc == 0 ? "SUCCES" : "FAILED")); - return rc; -} - -static char *evaluate_by_udev(const char *token, const char *value, int uevent) -{ - char dev[PATH_MAX]; - char *path = NULL; - size_t len; - struct stat st; - - DBG(DEBUG_EVALUATE, - printf("evaluating by udev %s=%s\n", token, value)); - - if (!strcmp(token, "UUID")) - strcpy(dev, _PATH_DEV_BYUUID "/"); - else if (!strcmp(token, "LABEL")) - strcpy(dev, _PATH_DEV_BYLABEL "/"); - else { - DBG(DEBUG_EVALUATE, - printf("unsupported token %s\n", token)); - return NULL; /* unsupported tag */ - } - - len = strlen(dev); - if (blkid_encode_string(value, &dev[len], sizeof(dev) - len) != 0) - return NULL; - - DBG(DEBUG_EVALUATE, - printf("expected udev link: %s\n", dev)); - - if (stat(dev, &st)) - goto failed; /* link or device does not exist */ - - if (!S_ISBLK(st.st_mode)) - return NULL; - - path = canonicalize_path(dev); - if (!path) - return NULL; - - if (verify_tag(path, token, value)) - goto failed; - return path; - -failed: - DBG(DEBUG_EVALUATE, printf("failed to evaluate by udev\n")); - - if (uevent && path) - blkid_send_uevent(path, "change"); - free(path); - return NULL; -} - -static char *evaluate_by_scan(const char *token, const char *value, - blkid_cache *cache, struct blkid_config *conf) -{ - blkid_cache c = cache ? *cache : NULL; - char *res; - - DBG(DEBUG_EVALUATE, - printf("evaluating by blkid scan %s=%s\n", token, value)); - - if (!c) { - char *cachefile = blkid_get_cache_filename(conf); - blkid_get_cache(&c, cachefile); - free(cachefile); - } - if (!c) - return NULL; - - res = blkid_get_devname(c, token, value); - - if (cache) - *cache = c; - else - blkid_put_cache(c); - - return res; -} - -/** - * blkid_evaluate_tag: - * @token: token name (e.g "LABEL" or "UUID") or unparsed tag (e.g. "LABEL=foo") - * @value: token data (e.g. "foo") - * @cache: pointer to cache (or NULL when you don't want to re-use the cache) - * - * Returns: allocated string with a device name. - */ -char *blkid_evaluate_tag(const char *token, const char *value, blkid_cache *cache) -{ - struct blkid_config *conf = NULL; - char *t = NULL, *v = NULL; - char *ret = NULL; - int i; - - if (!token) - return NULL; - - if (!cache || !*cache) - blkid_init_debug(0); - - DBG(DEBUG_EVALUATE, - printf("evaluating %s%s%s\n", token, value ? "=" : "", - value ? value : "")); - - if (!value) { - if (!strchr(token, '=')) { - ret = blkid_strdup(token); - goto out; - } - blkid_parse_tag_string(token, &t, &v); - if (!t || !v) - goto out; - token = t; - value = v; - } - - conf = blkid_read_config(NULL); - if (!conf) - goto out; - - for (i = 0; i < conf->nevals; i++) { - if (conf->eval[i] == BLKID_EVAL_UDEV) - ret = evaluate_by_udev(token, value, conf->uevent); - else if (conf->eval[i] == BLKID_EVAL_SCAN) - ret = evaluate_by_scan(token, value, cache, conf); - if (ret) - break; - } - - DBG(DEBUG_EVALUATE, - printf("%s=%s evaluated as %s\n", token, value, ret)); -out: - blkid_free_config(conf); - free(t); - free(v); - return ret; -} - -/** - * blkid_evaluate_spec: - * @spec: unparsed tag (e.g. "LABEL=foo") or path (e.g. /dev/dm-0) - * @cache: pointer to cache (or NULL when you don't want to re-use the cache) - * - * All returned paths are canonicalized, device-mapper paths are converted - * to the /dev/mapper/ format. - * - * Returns: allocated string with a device name. - */ -char *blkid_evaluate_spec(const char *spec, blkid_cache *cache) -{ - char *t = NULL, *v = NULL, *res; - - if (!spec) - return NULL; - - if (strchr(spec, '=') && - blkid_parse_tag_string(spec, &t, &v) != 0) /* parse error */ - return NULL; - - if (v) - res = blkid_evaluate_tag(t, v, cache); - else - res = canonicalize_path(spec); - - free(t); - free(v); - return res; -} - - -#ifdef TEST_PROGRAM -int main(int argc, char *argv[]) -{ - blkid_cache cache = NULL; - char *res; - - if (argc < 2) { - fprintf(stderr, "usage: %s | \n", argv[0]); - return EXIT_FAILURE; - } - - blkid_init_debug(0); - - res = blkid_evaluate_spec(argv[1], &cache); - if (res) - printf("%s\n", res); - if (cache) - blkid_put_cache(cache); - - return res ? EXIT_SUCCESS : EXIT_FAILURE; -} -#endif diff --git a/shlibs/blkid/src/getsize.c b/shlibs/blkid/src/getsize.c deleted file mode 100644 index abe6ebc9..00000000 --- a/shlibs/blkid/src/getsize.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * getsize.c --- get the size of a partition. - * - * Copyright (C) 1995, 1995 Theodore Ts'o. - * Copyright (C) 2010 Karel Zak - * - * %Begin-Header% - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * %End-Header% - */ - -#include -#include -#include - -#include "blkidP.h" - -/** - * blkid_get_dev_size: - * @fd: file descriptor - * - * Returns: size (in bytes) of the block device or size of the regular file or 0. - */ -blkid_loff_t blkid_get_dev_size(int fd) -{ - unsigned long long bytes; - - if (blkdev_get_size(fd, &bytes)) - return 0; - - return bytes; -} - diff --git a/shlibs/blkid/src/llseek.c b/shlibs/blkid/src/llseek.c deleted file mode 100644 index 5bd0e516..00000000 --- a/shlibs/blkid/src/llseek.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * llseek.c -- stub calling the llseek system call - * - * Copyright (C) 1994, 1995, 1996, 1997 Theodore Ts'o. - * - * %Begin-Header% - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * %End-Header% - */ - -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE - -#if HAVE_SYS_TYPES_H -#include -#endif - -#if HAVE_ERRNO_H -#include -#endif -#if HAVE_UNISTD_H -#include -#endif -#ifdef __MSDOS__ -#include -#endif - -#include "blkidP.h" - -#ifdef __linux__ - -#if defined(HAVE_LSEEK64) && defined(HAVE_LSEEK64_PROTOTYPE) - -#define my_llseek lseek64 - -#elif defined(HAVE_LLSEEK) -#include - -#ifndef HAVE_LLSEEK_PROTOTYPE -extern long long llseek(int fd, long long offset, int origin); -#endif - -#define my_llseek llseek - -#else /* ! HAVE_LLSEEK */ - -#if SIZEOF_LONG == SIZEOF_LONG_LONG - -#define llseek lseek - -#else /* SIZEOF_LONG != SIZEOF_LONG_LONG */ - -#include - -#ifndef __NR__llseek -#define __NR__llseek 140 -#endif - -#ifndef __i386__ -static int _llseek(unsigned int, unsigned long, unsigned long, - blkid_loff_t *, unsigned int); - -static _syscall5(int, _llseek, unsigned int, fd, unsigned long, offset_high, - unsigned long, offset_low, blkid_loff_t *, result, - unsigned int, origin) -#endif - -static blkid_loff_t my_llseek(int fd, blkid_loff_t offset, int origin) -{ - blkid_loff_t result; - int retval; - -#ifndef __i386__ - retval = _llseek(fd, ((unsigned long long) offset) >> 32, - ((unsigned long long)offset) & 0xffffffff, - &result, origin); -#else - retval = syscall(__NR__llseek, fd, ((unsigned long long) offset) >> 32, - ((unsigned long long)offset) & 0xffffffff, - &result, origin); -#endif - return (retval == -1 ? (blkid_loff_t) retval : result); -} - -#endif /* __alpha__ || __ia64__ */ - -#endif /* HAVE_LLSEEK */ - -blkid_loff_t blkid_llseek(int fd, blkid_loff_t offset, int whence) -{ - blkid_loff_t result; - static int do_compat = 0; - - if ((sizeof(off_t) >= sizeof(blkid_loff_t)) || - (offset < ((blkid_loff_t) 1 << ((sizeof(off_t)*8) -1)))) - return lseek(fd, (off_t) offset, whence); - - if (do_compat) { - errno = EOVERFLOW; - return -1; - } - - result = my_llseek(fd, offset, whence); - if (result == -1 && errno == ENOSYS) { - /* - * Just in case this code runs on top of an old kernel - * which does not support the llseek system call - */ - do_compat++; - errno = EOVERFLOW; - } - return result; -} - -#else /* !linux */ - -#ifndef EOVERFLOW -#ifdef EXT2_ET_INVALID_ARGUMENT -#define EOVERFLOW EXT2_ET_INVALID_ARGUMENT -#else -#define EOVERFLOW 112 -#endif -#endif - -blkid_loff_t blkid_llseek(int fd, blkid_loff_t offset, int origin) -{ -#if defined(HAVE_LSEEK64) && defined(HAVE_LSEEK64_PROTOTYPE) - return lseek64 (fd, offset, origin); -#else - if ((sizeof(off_t) < sizeof(blkid_loff_t)) && - (offset >= ((blkid_loff_t) 1 << ((sizeof(off_t)*8) - 1)))) { - errno = EOVERFLOW; - return -1; - } - return lseek(fd, (off_t) offset, origin); -#endif -} - -#endif /* linux */ - - diff --git a/shlibs/blkid/src/partitions/Makefile.am b/shlibs/blkid/src/partitions/Makefile.am deleted file mode 100644 index f617389d..00000000 --- a/shlibs/blkid/src/partitions/Makefile.am +++ /dev/null @@ -1,22 +0,0 @@ -include $(top_srcdir)/config/include-Makefile.am - -AM_CPPFLAGS += -I$(ul_libblkid_incdir) -I$(ul_libblkid_srcdir) -libblkid_partitions_la_LIBADD = - -noinst_LTLIBRARIES = libblkid_partitions.la -libblkid_partitions_la_SOURCES = partitions.c \ - partitions.h \ - blkid_parttypes.h \ - aix.c \ - aix.h \ - bsd.c \ - unixware.c \ - solaris_x86.c \ - sun.c \ - sgi.c \ - mac.c \ - dos.c \ - dos.h \ - minix.c \ - ultrix.c \ - gpt.c diff --git a/shlibs/blkid/src/partitions/aix.c b/shlibs/blkid/src/partitions/aix.c deleted file mode 100644 index be0ad2b4..00000000 --- a/shlibs/blkid/src/partitions/aix.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * aix partitions - * - * Copyright (C) 2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include - -#include "partitions.h" -#include "aix.h" - -static int probe_aix_pt(blkid_probe pr, const struct blkid_idmag *mag) -{ - blkid_partlist ls; - blkid_parttable tab; - - if (blkid_partitions_need_typeonly(pr)) - /* caller does not ask for details about partitions */ - return 0; - - ls = blkid_probe_get_partlist(pr); - if (!ls) - goto err; - - tab = blkid_partlist_new_parttable(ls, "aix", 0); - if (!tab) - goto err; - - return 0; -err: - return -1; -} - -/* - * We know nothing about AIX on-disk structures. Everything what we know is the - * magic number at begin of the disk. - * - * Note, Linux kernel is tring to be smart and AIX signature is ignored when - * there is a valid DOS partitions table. We don't support such behaviour. All - * fdisk-like programs has to properly wipe the fist sector. Everything other - * is a bug. - */ -const struct blkid_idinfo aix_pt_idinfo = -{ - .name = "aix", - .probefunc = probe_aix_pt, - .magics = - { - { .magic = BLKID_AIX_MAGIC_STRING, .len = BLKID_AIX_MAGIC_STRLEN }, - { NULL } - } -}; - diff --git a/shlibs/blkid/src/partitions/aix.h b/shlibs/blkid/src/partitions/aix.h deleted file mode 100644 index f767c5a3..00000000 --- a/shlibs/blkid/src/partitions/aix.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef BLKID_PARTITIONS_AIX_H -#define BLKID_PARTITIONS_AIX_H - -#define BLKID_AIX_MAGIC_STRING "\xC9\xC2\xD4\xC1" -#define BLKID_AIX_MAGIC_STRLEN (sizeof(BLKID_AIX_MAGIC_STRING) - 1) - -#endif diff --git a/shlibs/blkid/src/partitions/blkid_parttypes.h b/shlibs/blkid/src/partitions/blkid_parttypes.h deleted file mode 100644 index 707e53d9..00000000 --- a/shlibs/blkid/src/partitions/blkid_parttypes.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Partition types - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* Note, _L32M means <32M (less), for example FAT16_L32M */ - -enum { - BLKID_EMPTY_PARTITION = 0x00, - BLKID_FAT12_PARTITION = 0x01, - BLKID_XENIX_ROOT_PARTITION = 0x02, - BLKID_XENIX_USR_PARTITION = 0x03, - BLKID_FAT16_LESS32M_PARTITION = 0x04, - BLKID_DOS_EXTENDED_PARTITION = 0x05, - BLKID_FAT16_PARTITION = 0x06, /* DOS 16-bit >=32M */ - BLKID_HPFS_NTFS_PARTITION = 0x07, /* OS/2 IFS, eg, HPFS or NTFS or QNX */ - BLKID_AIX_PARTITION = 0x08, /* AIX boot (AIX -- PS/2 port) or SplitDrive */ - BLKID_AIX_BOOTABLE_PARTITION = 0x09, /* AIX data or Coherent */ - BLKID_OS2_BOOTMNGR_PARTITION = 0x0a, /* OS/2 Boot Manager */ - BLKID_W95_FAT32_PARTITION = 0x0b, - BLKID_W95_FAT32_LBA_PARTITION = 0x0c, /* LBA really is `Extended Int 13h' */ - BLKID_W95_FAT16_LBA_PARTITION = 0x0e, - BLKID_W95_EXTENDED_PARTITION = 0x0f, - BLKID_OPUS_PARTITION = 0x10, - BLKID_HIDDEN_FAT12_PARTITION = 0x11, - BLKID_COMPAQ_DIAGNOSTICS_PARTITION = 0x12, - BLKID_HIDDEN_FAT16_L32M_PARTITION = 0x14, - BLKID_HIDDEN_FAT16_PARTITION = 0x16, - BLKID_HIDDEN_HPFS_NTFS_PARTITION = 0x17, - BLKID_AST_SMARTSLEEP_PARTITION = 0x18, - BLKID_HIDDEN_W95_FAT32_PARTITION = 0x1b, - BLKID_HIDDEN_W95_FAT32LBA_PARTITION = 0x1c, - BLKID_HIDDEN_W95_FAT16LBA_PARTITION = 0x1e, - BLKID_NEC_DOS_PARTITION = 0x24, - BLKID_PLAN9_PARTITION = 0x39, - BLKID_PARTITIONMAGIC_PARTITION = 0x3c, - BLKID_VENIX80286_PARTITION = 0x40, - BLKID_PPC_PREP_BOOT_PARTITION = 0x41, - BLKID_SFS_PARTITION = 0x42, - BLKID_QNX_4X_PARTITION = 0x4d, - BLKID_QNX_4X_2ND_PARTITION = 0x4e, - BLKID_QNX_4X_3RD_PARTITION = 0x4f, - BLKID_DM_PARTITION = 0x50, - BLKID_DM6_AUX1_PARTITION = 0x51, /* (or Novell) */ - BLKID_CPM_PARTITION = 0x52, /* CP/M or Microport SysV/AT */ - BLKID_DM6_AUX3_PARTITION = 0x53, - BLKID_DM6_PARTITION = 0x54, - BLKID_EZ_DRIVE_PARTITION = 0x55, - BLKID_GOLDEN_BOW_PARTITION = 0x56, - BLKID_PRIAM_EDISK_PARTITION = 0x5c, - BLKID_SPEEDSTOR_PARTITION = 0x61, - BLKID_GNU_HURD_PARTITION = 0x63, /* GNU HURD or Mach or Sys V/386 (such as ISC UNIX) */ - BLKID_UNIXWARE_PARTITION = BLKID_GNU_HURD_PARTITION, - BLKID_NETWARE_286_PARTITION = 0x64, - BLKID_NETWARE_386_PARTITION = 0x65, - BLKID_DISKSECURE_MULTIBOOT_PARTITION = 0x70, - BLKID_PC_IX_PARTITION = 0x75, - BLKID_OLD_MINIX_PARTITION = 0x80, /* Minix 1.4a and earlier */ - BLKID_MINIX_PARTITION = 0x81, /* Minix 1.4b and later */ - BLKID_LINUX_SWAP_PARTITION = 0x82, - BLKID_SOLARIS_X86_PARTITION = BLKID_LINUX_SWAP_PARTITION, - BLKID_LINUX_DATA_PARTITION = 0x83, - BLKID_OS2_HIDDEN_DRIVE_PARTITION = 0x84, - BLKID_LINUX_EXTENDED_PARTITION = 0x85, - BLKID_NTFS_VOL_SET1_PARTITION = 0x86, - BLKID_NTFS_VOL_SET2_PARTITION = 0x87, - BLKID_LINUX_PLAINTEXT_PARTITION = 0x88, - BLKID_LINUX_LVM_PARTITION = 0x8e, - BLKID_AMOEBA_PARTITION = 0x93, - BLKID_AMOEBA_BBT_PARTITION = 0x94, /* (bad block table) */ - BLKID_BSD_OS_PARTITION = 0x9f, /* BSDI */ - BLKID_THINKPAD_HIBERNATION_PARTITION = 0xa0, - BLKID_FREEBSD_PARTITION = 0xa5, /* various BSD flavours */ - BLKID_OPENBSD_PARTITION = 0xa6, - BLKID_NEXTSTEP_PARTITION = 0xa7, - BLKID_DARWIN_UFS_PARTITION = 0xa8, - BLKID_NETBSD_PARTITION = 0xa9, - BLKID_DARWIN_BOOT_PARTITION = 0xab, - BLKID_HFS_HFS_PARTITION = 0xaf, - BLKID_BSDI_FS_PARTITION = 0xb7, - BLKID_BSDI_SWAP_PARTITION = 0xb8, - BLKID_BOOTWIZARD_HIDDEN_PARTITION = 0xbb, - BLKID_SOLARIS_BOOT_PARTITION = 0xbe, - BLKID_SOLARIS_PARTITION = 0xbf, - BLKID_DRDOS_FAT12_PARTITION = 0xc1, - BLKID_DRDOS_FAT16_L32M_PARTITION = 0xc4, - BLKID_DRDOS_FAT16_PARTITION = 0xc6, - BLKID_SYRINX_PARTITION = 0xc7, - BLKID_NONFS_DATA_PARTITION = 0xda, - BLKID_CPM_CTOS_PARTITION = 0xdb, /* CP/M or Concurrent CP/M or Concurrent DOS or CTOS */ - BLKID_DELL_UTILITY_PARTITION = 0xde, /* Dell PowerEdge Server utilities */ - BLKID_BOOTIT_PARTITION = 0xdf, /* BootIt EMBRM */ - BLKID_DOS_ACCESS_PARTITION = 0xe1, /* DOS access or SpeedStor 12-bit FAT extended partition */ - BLKID_DOS_RO_PARTITION = 0xe3, /* DOS R/O or SpeedStor */ - BLKID_SPEEDSTOR_EXTENDED_PARTITION = 0xe4, /* SpeedStor 16-bit FAT extended partition < 1024 cyl. */ - BLKID_BEOS_FS_PARTITION = 0xeb, - BLKID_GPT_PARTITION = 0xee, /* Intel EFI GUID Partition Table */ - BLKID_EFI_SYSTEM_PARTITION = 0xef, /* Intel EFI System Partition */ - BLKID_LINUX_PARISC_BOOT_PARTITION = 0xf0, /* Linux/PA-RISC boot loader */ - BLKID_SPEEDSTOR1_PARTITION = 0xf1, - BLKID_SPEEDSTOR2_PARTITION = 0xf4, /* SpeedStor large partition */ - BLKID_DOS_SECONDARY_PARTITION = 0xf2, /* DOS 3.3+ secondary */ - BLKID_VMWARE_VMFS_PARTITION = 0xfb, - BLKID_VMWARE_VMKCORE_PARTITION = 0xfc, /* VMware kernel dump partition */ - BLKID_LINUX_RAID_PARTITION = 0xfd, /* New (2.2.x) raid partition with autodetect using persistent superblock */ - BLKID_LANSTEP_PARTITION = 0xfe, /* SpeedStor >1024 cyl. or LANstep */ - BLKID_XENIX_BBT_PARTITION = 0xff, /* Xenix Bad Block Table */ -}; diff --git a/shlibs/blkid/src/partitions/bsd.c b/shlibs/blkid/src/partitions/bsd.c deleted file mode 100644 index ee15ad2f..00000000 --- a/shlibs/blkid/src/partitions/bsd.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * BSD/OSF partition parsing code - * - * Copyright (C) 2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * - * Inspired by fdisk, partx, Linux kernel, libparted and openbsd header files. - */ -#include -#include -#include -#include - -#include "partitions.h" - -#define BSD_MAXPARTITIONS 16 -#define BSD_FS_UNUSED 0 - -struct bsd_disklabel { - uint32_t d_magic; /* the magic number */ - int16_t d_type; /* drive type */ - int16_t d_subtype; /* controller/d_type specific */ - char d_typename[16]; /* type name, e.g. "eagle" */ - char d_packname[16]; /* pack identifier */ - - /* disk geometry: */ - uint32_t d_secsize; /* # of bytes per sector */ - uint32_t d_nsectors; /* # of data sectors per track */ - uint32_t d_ntracks; /* # of tracks per cylinder */ - uint32_t d_ncylinders; /* # of data cylinders per unit */ - uint32_t d_secpercyl; /* # of data sectors per cylinder */ - uint32_t d_secperunit; /* # of data sectors per unit */ - - /* - * Spares (bad sector replacements) below - * are not counted in d_nsectors or d_secpercyl. - * Spare sectors are assumed to be physical sectors - * which occupy space at the end of each track and/or cylinder. - */ - uint16_t d_sparespertrack; /* # of spare sectors per track */ - uint16_t d_sparespercyl; /* # of spare sectors per cylinder */ - - /* - * Alternate cylinders include maintenance, replacement, - * configuration description areas, etc. - */ - uint32_t d_acylinders; /* # of alt. cylinders per unit */ - - /* hardware characteristics: */ - /* - * d_interleave, d_trackskew and d_cylskew describe perturbations - * in the media format used to compensate for a slow controller. - * Interleave is physical sector interleave, set up by the formatter - * or controller when formatting. When interleaving is in use, - * logically adjacent sectors are not physically contiguous, - * but instead are separated by some number of sectors. - * It is specified as the ratio of physical sectors traversed - * per logical sector. Thus an interleave of 1:1 implies contiguous - * layout, while 2:1 implies that logical sector 0 is separated - * by one sector from logical sector 1. - * d_trackskew is the offset of sector 0 on track N - * relative to sector 0 on track N-1 on the same cylinder. - * Finally, d_cylskew is the offset of sector 0 on cylinder N - * relative to sector 0 on cylinder N-1. - */ - uint16_t d_rpm; /* rotational speed */ - uint16_t d_interleave; /* hardware sector interleave */ - uint16_t d_trackskew; /* sector 0 skew, per track */ - uint16_t d_cylskew; /* sector 0 skew, per cylinder */ - uint32_t d_headswitch; /* head switch time, usec */ - uint32_t d_trkseek; /* track-to-track seek, usec */ - uint32_t d_flags; /* generic flags */ - uint32_t d_drivedata[5]; /* drive-type specific information */ - uint32_t d_spare[5]; /* reserved for future use */ - uint32_t d_magic2; /* the magic number (again) */ - uint16_t d_checksum; /* xor of data incl. partitions */ - - /* filesystem and partition information: */ - uint16_t d_npartitions; /* number of partitions in following */ - uint32_t d_bbsize; /* size of boot area at sn0, bytes */ - uint32_t d_sbsize; /* max size of fs superblock, bytes */ - - struct bsd_partition { /* the partition table */ - uint32_t p_size; /* number of sectors in partition */ - uint32_t p_offset; /* starting sector */ - uint32_t p_fsize; /* filesystem basic fragment size */ - uint8_t p_fstype; /* filesystem type, see below */ - uint8_t p_frag; /* filesystem fragments per block */ - uint16_t p_cpg; /* filesystem cylinders per group */ - } __attribute__((packed)) d_partitions[BSD_MAXPARTITIONS]; /* actually may be more */ -} __attribute__((packed)); - - -/* Returns 'blkid_idmag' in 512-sectors */ -#define BLKID_MAG_SECTOR(_mag) (((_mag)->kboff * 2) + ((_mag)->sboff >> 9)) - -/* Returns 'blkid_idmag' in bytes */ -#define BLKID_MAG_OFFSET(_mag) ((_mag)->kboff >> 10) + ((_mag)->sboff) - -/* Returns 'blkid_idmag' offset in bytes within the last sector */ -#define BLKID_MAG_LASTOFFSET(_mag) \ - (BLKID_MAG_OFFSET(_mag) - (BLKID_MAG_SECTOR(_mag) << 9)) - -static int probe_bsd_pt(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct bsd_disklabel *l; - struct bsd_partition *p; - const char *name = "bsd" ; - blkid_parttable tab = NULL; - blkid_partition parent; - blkid_partlist ls; - int i, nparts = BSD_MAXPARTITIONS; - unsigned char *data; - - if (blkid_partitions_need_typeonly(pr)) - /* caller does not ask for details about partitions */ - return 0; - - data = blkid_probe_get_sector(pr, BLKID_MAG_SECTOR(mag)); - if (!data) - goto nothing; - - l = (struct bsd_disklabel *) data + BLKID_MAG_LASTOFFSET(mag); - - ls = blkid_probe_get_partlist(pr); - if (!ls) - goto err; - - /* try to determine the real type of BSD system according to - * (parental) primary partition */ - parent = blkid_partlist_get_parent(ls); - if (parent) { - switch(blkid_partition_get_type(parent)) { - case BLKID_FREEBSD_PARTITION: - name = "freebsd"; - break; - case BLKID_NETBSD_PARTITION: - name = "netbsd"; - break; - case BLKID_OPENBSD_PARTITION: - name = "openbsd"; - break; - default: - DBG(DEBUG_LOWPROBE, printf( - "WARNING: BSD label detected on unknown (0x%x) " - "primary partition\n", - blkid_partition_get_type(parent))); - break; - } - } - - tab = blkid_partlist_new_parttable(ls, name, BLKID_MAG_OFFSET(mag)); - if (!tab) - goto err; - - if (le16_to_cpu(l->d_npartitions) < BSD_MAXPARTITIONS) - nparts = le16_to_cpu(l->d_npartitions); - - else if (le16_to_cpu(l->d_npartitions) > BSD_MAXPARTITIONS) - DBG(DEBUG_LOWPROBE, printf( - "WARNING: ignore %d more BSD partitions\n", - le16_to_cpu(l->d_npartitions) - BSD_MAXPARTITIONS)); - - for (i = 0, p = l->d_partitions; i < nparts; i++, p++) { - blkid_partition par; - uint32_t start, size; - - /* TODO: in fdisk-mode returns all non-zero (p_size) partitions */ - if (p->p_fstype == BSD_FS_UNUSED) - continue; - - start = le32_to_cpu(p->p_offset); - size = le32_to_cpu(p->p_size); - - if (parent && !blkid_is_nested_dimension(parent, start, size)) { - DBG(DEBUG_LOWPROBE, printf( - "WARNING: BSD partition (%d) overflow " - "detected, ignore\n", i)); - continue; - } - - par = blkid_partlist_add_partition(ls, tab, start, size); - if (!par) - goto err; - - blkid_partition_set_type(par, p->p_fstype); - } - - return 0; - -nothing: - return 1; -err: - return -1; -} - - -/* - * All BSD variants use the same magic string (little-endian), - * and the same disklabel. - * - * The difference between {Free,Open,...}BSD is in the (parental) - * primary partition type. - * - * See also: http://en.wikipedia.org/wiki/BSD_disklabel - * - * The location of BSD disk label is architecture specific and in defined by - * LABELSECTOR and LABELOFFSET macros in the disklabel.h file. The location - * also depends on BSD variant, FreeBSD uses only one location, NetBSD and - * OpenBSD are more creative... - * - * The basic overview: - * - * arch | LABELSECTOR | LABELOFFSET - * ------------------------+-------------+------------ - * amd64 arm hppa hppa64 | | - * i386, macppc, mvmeppc | 1 | 0 - * sgi, aviion, sh, socppc | | - * ------------------------+-------------+------------ - * alpha luna88k mac68k | 0 | 64 - * sparc(OpenBSD) vax | | - * ------------------------+-------------+------------ - * spark64 sparc(NetBSD) | 0 | 128 - * ------------------------+-------------+------------ - * - * ...and more (see http://fxr.watson.org/fxr/ident?v=NETBSD;i=LABELSECTOR) - * - */ -const struct blkid_idinfo bsd_pt_idinfo = -{ - .name = "bsd", - .probefunc = probe_bsd_pt, - .magics = - { - { .magic = "\x57\x45\x56\x82", .len = 4, .sboff = 512 }, - { .magic = "\x57\x45\x56\x82", .len = 4, .sboff = 64 }, - { .magic = "\x57\x45\x56\x82", .len = 4, .sboff = 128 }, - { NULL } - } -}; - diff --git a/shlibs/blkid/src/partitions/dos.c b/shlibs/blkid/src/partitions/dos.c deleted file mode 100644 index 72ac7788..00000000 --- a/shlibs/blkid/src/partitions/dos.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - * MS-DOS partition parsing code - * - * Copyright (C) 2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * - * Inspired by fdisk, partx, Linux kernel and libparted. - */ -#include -#include -#include -#include - -#include "partitions.h" -#include "dos.h" -#include "aix.h" - -/* see superblocks/vfat.c */ -extern int blkid_probe_is_vfat(blkid_probe pr); - -static const struct dos_subtypes { - unsigned char type; - const struct blkid_idinfo *id; -} dos_nested[] = { - { BLKID_FREEBSD_PARTITION, &bsd_pt_idinfo }, - { BLKID_NETBSD_PARTITION, &bsd_pt_idinfo }, - { BLKID_OPENBSD_PARTITION, &bsd_pt_idinfo }, - { BLKID_UNIXWARE_PARTITION, &unixware_pt_idinfo }, - { BLKID_SOLARIS_X86_PARTITION, &solaris_x86_pt_idinfo }, - { BLKID_MINIX_PARTITION, &minix_pt_idinfo } -}; - -static inline int is_extended(struct dos_partition *p) -{ - return (p->sys_type == BLKID_DOS_EXTENDED_PARTITION || - p->sys_type == BLKID_W95_EXTENDED_PARTITION || - p->sys_type == BLKID_LINUX_EXTENDED_PARTITION); -} - -static int parse_dos_extended(blkid_probe pr, blkid_parttable tab, - uint32_t ex_start, uint32_t ex_size, int ssf) -{ - blkid_partlist ls = blkid_probe_get_partlist(pr); - uint32_t cur_start = ex_start, cur_size = ex_size; - unsigned char *data; - int ct_nodata = 0; /* count ext.partitions without data partitions */ - int i; - - while (1) { - struct dos_partition *p, *p0; - uint32_t start, size; - - if (++ct_nodata > 100) - return 0; - data = blkid_probe_get_sector(pr, cur_start); - if (!data) - goto leave; /* malformed partition? */ - - if (!is_valid_mbr_signature(data)) - goto leave; - - p0 = (struct dos_partition *) (data + BLKID_MSDOS_PT_OFFSET); - - /* Usually, the first entry is the real data partition, - * the 2nd entry is the next extended partition, or empty, - * and the 3rd and 4th entries are unused. - * However, DRDOS sometimes has the extended partition as - * the first entry (when the data partition is empty), - * and OS/2 seems to use all four entries. - * -- Linux kernel fs/partitions/dos.c - * - * See also http://en.wikipedia.org/wiki/Extended_boot_record - */ - - /* Parse data partition */ - for (p = p0, i = 0; i < 4; i++, p++) { - uint32_t abs_start; - blkid_partition par; - - /* the start is relative to the parental ext.partition */ - start = dos_partition_start(p) * ssf; - size = dos_partition_size(p) * ssf; - abs_start = cur_start + start; /* absolute start */ - - if (!size || is_extended(p)) - continue; - if (i >= 2) { - /* extra checks to detect real data on - * 3rd and 4th entries */ - if (start + size > cur_size) - continue; - if (abs_start < ex_start) - continue; - if (abs_start + size > ex_start + ex_size) - continue; - } - - par = blkid_partlist_add_partition(ls, tab, abs_start, size); - if (!par) - goto err; - - blkid_partition_set_type(par, p->sys_type); - blkid_partition_set_flags(par, p->boot_ind); - ct_nodata = 0; - } - /* The first nested ext.partition should be a link to the next - * logical partition. Everything other (recursive ext.partitions) - * is junk. - */ - for (p = p0, i = 0; i < 4; i++, p++) { - start = dos_partition_start(p) * ssf; - size = dos_partition_size(p) * ssf; - - if (size && is_extended(p)) - break; - } - if (i == 4) - goto leave; - - cur_start = ex_start + start; - cur_size = size; - } -leave: - return 0; -err: - return -1; -} - -static int probe_dos_pt(blkid_probe pr, const struct blkid_idmag *mag) -{ - int i; - int ssf; - blkid_parttable tab = NULL; - blkid_partlist ls; - struct dos_partition *p0, *p; - unsigned char *data; - uint32_t start, size; - - data = blkid_probe_get_sector(pr, 0); - if (!data) - goto nothing; - - /* ignore disks with AIX magic number -- for more details see aix.c */ - if (memcmp(data, BLKID_AIX_MAGIC_STRING, BLKID_AIX_MAGIC_STRLEN) == 0) - goto nothing; - - /* - * Now that the 55aa signature is present, this is probably - * either the boot sector of a FAT filesystem or a DOS-type - * partition table. - */ - if (blkid_probe_is_vfat(pr)) { - DBG(DEBUG_LOWPROBE, printf("probably FAT -- ignore\n")); - goto nothing; - } - - p0 = (struct dos_partition *) (data + BLKID_MSDOS_PT_OFFSET); - - /* - * Reject PT where boot indicator is not 0 or 0x80. - */ - for (p = p0, i = 0; i < 4; i++, p++) - if (p->boot_ind != 0 && p->boot_ind != 0x80) { - DBG(DEBUG_LOWPROBE, printf("missing boot indicator -- ignore\n")); - goto nothing; - } - - /* - * GPT uses valid MBR - */ - for (p = p0, i = 0; i < 4; i++, p++) { - if (p->sys_type == BLKID_GPT_PARTITION) { - DBG(DEBUG_LOWPROBE, printf("probably GPT -- ignore\n")); - goto nothing; - } - } - - blkid_probe_use_wiper(pr, BLKID_MSDOS_PT_OFFSET, - 512 - BLKID_MSDOS_PT_OFFSET); - - /* - * Well, all checks pass, it's MS-DOS partiton table - */ - if (blkid_partitions_need_typeonly(pr)) - /* caller does not ask for details about partitions */ - return 0; - - ls = blkid_probe_get_partlist(pr); - - /* sector size factor (the start and size are in the real sectors, but - * we need to convert all sizes to 512 logical sectors - */ - ssf = blkid_probe_get_sectorsize(pr) / 512; - - /* allocate a new partition table */ - tab = blkid_partlist_new_parttable(ls, "dos", BLKID_MSDOS_PT_OFFSET); - if (!tab) - goto err; - - /* Parse primary partitions */ - for (p = p0, i = 0; i < 4; i++, p++) { - blkid_partition par; - - start = dos_partition_start(p) * ssf; - size = dos_partition_size(p) * ssf; - - if (!size) { - /* Linux kernel ignores empty partitions, but partno for - * the empty primary partitions is not reused */ - blkid_partlist_increment_partno(ls); - continue; - } - par = blkid_partlist_add_partition(ls, tab, start, size); - if (!par) - goto err; - - blkid_partition_set_type(par, p->sys_type); - blkid_partition_set_flags(par, p->boot_ind); - } - - /* Linux uses partition numbers greater than 4 - * for all logical partition and all nested partition tables (bsd, ..) - */ - blkid_partlist_set_partno(ls, 5); - - /* Parse logical partitions */ - for (p = p0, i = 0; i < 4; i++, p++) { - start = dos_partition_start(p) * ssf; - size = dos_partition_size(p) * ssf; - - if (!size) - continue; - if (is_extended(p) && - parse_dos_extended(pr, tab, start, size, ssf) == -1) - goto err; - } - - /* Parse subtypes (nested partitions) on large disks */ - if (!blkid_probe_is_tiny(pr)) { - for (p = p0, i = 0; i < 4; i++, p++) { - int n; - - if (!dos_partition_size(p) || is_extended(p)) - continue; - - for (n = 0; n < ARRAY_SIZE(dos_nested); n++) { - if (dos_nested[n].type != p->sys_type) - continue; - - if (blkid_partitions_do_subprobe(pr, - blkid_partlist_get_partition(ls, i), - dos_nested[n].id) == -1) - goto err; - break; - } - } - } - return 0; - -nothing: - return 1; -err: - return -1; -} - - -const struct blkid_idinfo dos_pt_idinfo = -{ - .name = "dos", - .probefunc = probe_dos_pt, - .magics = - { - /* DOS master boot sector: - * - * 0 | Code Area - * 440 | Optional Disk signature - * 446 | Partition table - * 510 | 0x55 - * 511 | 0xAA - */ - { .magic = "\x55\xAA", .len = 2, .sboff = 510 }, - { NULL } - } -}; - diff --git a/shlibs/blkid/src/partitions/dos.h b/shlibs/blkid/src/partitions/dos.h deleted file mode 100644 index 130aa011..00000000 --- a/shlibs/blkid/src/partitions/dos.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef BLKID_PARTITIONS_DOS_H -#define BLKID_PARTITIONS_DOS_H - -struct dos_partition { - unsigned char boot_ind; /* 0x80 - active */ - unsigned char bh, bs, bc; /* begin CHS */ - unsigned char sys_type; - unsigned char eh, es, ec; /* end CHS */ - unsigned char start_sect[4]; - unsigned char nr_sects[4]; -} __attribute__((packed)); - -#define BLKID_MSDOS_PT_OFFSET 0x1be - -/* assemble badly aligned little endian integer */ -static inline unsigned int assemble4le(unsigned char *p) -{ - return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); -} - -static inline unsigned int dos_partition_start(struct dos_partition *p) -{ - return assemble4le(&(p->start_sect[0])); -} - -static inline unsigned int dos_partition_size(struct dos_partition *p) -{ - return assemble4le(&(p->nr_sects[0])); -} - -static inline int is_valid_mbr_signature(const unsigned char *mbr) -{ - return mbr[510] == 0x55 && mbr[511] == 0xaa ? 1 : 0; -} - -#endif /* BLKID_PARTITIONS_DOS_H */ diff --git a/shlibs/blkid/src/partitions/gpt.c b/shlibs/blkid/src/partitions/gpt.c deleted file mode 100644 index 9281a894..00000000 --- a/shlibs/blkid/src/partitions/gpt.c +++ /dev/null @@ -1,401 +0,0 @@ -/* - * EFI GPT partition parsing code - * - * Copyright (C) 2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * - * This code is not copy & past from any other implementation. - * - * For more information about GPT start your study at: - * http://en.wikipedia.org/wiki/GUID_Partition_Table - * http://technet.microsoft.com/en-us/library/cc739412(WS.10).aspx - */ -#include -#include -#include -#include -#include - -#include "partitions.h" -#include "crc32.h" -#include "dos.h" - -#define GPT_PRIMARY_LBA 1 - -/* Signature - “EFI PART” */ -#define GPT_HEADER_SIGNATURE 0x5452415020494645ULL - -/* basic types */ -typedef uint16_t efi_char16_t; - -/* UUID */ -typedef struct { - uint32_t time_low; - uint16_t time_mid; - uint16_t time_hi_and_version; - uint8_t clock_seq_hi; - uint8_t clock_seq_low; - uint8_t node[6]; -} efi_guid_t; - - -#define GPT_UNUSED_ENTRY_GUID \ - ((efi_guid_t) { 0x00000000, 0x0000, 0x0000, 0x00, 0x00, \ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}) -struct gpt_header { - uint64_t signature; /* "EFI PART" */ - uint32_t revision; - uint32_t header_size; /* usualy 92 bytes */ - uint32_t header_crc32; /* checksum of header with this - * field zeroed during calculation */ - uint32_t reserved1; - - uint64_t my_lba; /* location of this header copy */ - uint64_t alternate_lba; /* location of the other header copy */ - uint64_t first_usable_lba; /* lirst usable LBA for partitions */ - uint64_t last_usable_lba; /* last usable LBA for partitions */ - - efi_guid_t disk_guid; /* disk UUID */ - - uint64_t partition_entries_lba; /* always 2 in primary header copy */ - uint32_t num_partition_entries; - uint32_t sizeof_partition_entry; - uint32_t partition_entry_array_crc32; - - /* - * The rest of the block is reserved by UEFI and must be zero. EFI - * standard handles this by: - * - * uint8_t reserved2[ BLKSSZGET - 92 ]; - * - * This definition is useless in practice. It is necessary to read - * whole block from the device rather than sizeof(struct gpt_header) - * only. - */ -} __attribute__ ((packed)); - -/*** not used -struct gpt_entry_attributes { - uint64_t required_to_function:1; - uint64_t reserved:47; - uint64_t type_guid_specific:16; -} __attribute__ ((packed)); -***/ - -struct gpt_entry { - efi_guid_t partition_type_guid; /* type UUID */ - efi_guid_t unique_partition_guid; /* partition UUID */ - uint64_t starting_lba; - uint64_t ending_lba; - - /*struct gpt_entry_attributes attributes;*/ - - uint64_t attributes; - - efi_char16_t partition_name[72 / sizeof(efi_char16_t)]; /* UTF-16LE string*/ -} __attribute__ ((packed)); - - -/* - * EFI uses crc32 with ~0 seed and xor's with ~0 at the end. - */ -static inline uint32_t count_crc32(const unsigned char *buf, size_t len) -{ - return (crc32(~0L, buf, len) ^ ~0L); -} - -static inline unsigned char *get_lba_buffer(blkid_probe pr, - uint64_t lba, size_t bytes) -{ - return blkid_probe_get_buffer(pr, - blkid_probe_get_sectorsize(pr) * lba, bytes); -} - -static inline int guidcmp(efi_guid_t left, efi_guid_t right) -{ - return memcmp(&left, &right, sizeof (efi_guid_t)); -} - -/* - * UUID is traditionaly 16 byte big-endian array, except Intel EFI - * specification where the UUID is a structure of little-endian fields. - */ -static void swap_efi_guid(efi_guid_t *uid) -{ - uid->time_low = swab32(uid->time_low); - uid->time_mid = swab16(uid->time_mid); - uid->time_hi_and_version = swab16(uid->time_hi_and_version); -} - -static int last_lba(blkid_probe pr, uint64_t *lba) -{ - blkid_loff_t sz = blkid_probe_get_size(pr); - if (sz < blkid_probe_get_sectorsize(pr)) - return -1; - - *lba = (sz >> 9) - 1; - return 0; -} - -/* - * Protective (legacy) MBR. - * - * This MBR contains standard DOS partition table with a single partition, type - * of 0xEE. The partition usually encompassing the entire GPT drive - or 2TiB - * for large disks. - * - * Note that Apple uses GPT/MBR hybrid disks, where the DOS partition table is - * synchronized with GPT. This synchronization has many restriction of course - * (due DOS PT limitations). - * - * Note that the PMBR detection is optional (enabled by default) and could be - * disabled by BLKID_PARTS_FOPCE_GPT flag (see also blkid_paertitions_set_flags()). - */ -static int is_pmbr_valid(blkid_probe pr) -{ - int flags = blkid_partitions_get_flags(pr); - unsigned char *data; - struct dos_partition *p; - int i; - - if (flags & BLKID_PARTS_FORCE_GPT) - goto ok; /* skip PMBR check */ - - data = blkid_probe_get_sector(pr, 0); - if (!data) - goto failed; - - if (!is_valid_mbr_signature(data)) - goto failed; - - p = (struct dos_partition *) (data + BLKID_MSDOS_PT_OFFSET); - - for (i = 0; i < 4; i++, p++) { - if (p->sys_type == BLKID_GPT_PARTITION) - goto ok; - } -failed: - return 0; -ok: - return 1; -} - -/* - * Reads GPT header to @hdr and returns a pointer to @hdr or NULL in case of - * error. The function also returns GPT entries in @ents. - * - * Note, this function does not allocate any memory. The GPT header has fixed - * size so we use stack, and @ents returns memory from libblkid buffer (so the - * next blkid_probe_get_buffer() will overwrite this buffer). - * - * This function checks validity of header and entries array. A corrupted - * header is not returned. - */ -static struct gpt_header *get_gpt_header( - blkid_probe pr, struct gpt_header *hdr, - struct gpt_entry **ents, uint64_t lba, - uint64_t lastlba) -{ - struct gpt_header *h; - uint32_t crc, orgcrc; - uint64_t lu, fu; - size_t esz; - uint32_t hsz, ssz; - - ssz = blkid_probe_get_sectorsize(pr); - - /* whole sector is allocated for GPT header */ - h = (struct gpt_header *) get_lba_buffer(pr, lba, ssz); - if (!h) - return NULL; - - if (le64_to_cpu(h->signature) != GPT_HEADER_SIGNATURE) - return NULL; - - hsz = le32_to_cpu(h->header_size); - - /* EFI: The HeaderSize must be greater than 92 and must be less - * than or equal to the logical block size. - */ - if (hsz > ssz || hsz < sizeof(*h)) - return NULL; - - /* Header has to be verified when header_crc32 is zero */ - orgcrc = le32_to_cpu(h->header_crc32); - h->header_crc32 = 0; - - crc = count_crc32((unsigned char *) h, hsz); - if (crc != orgcrc) { - DBG(DEBUG_LOWPROBE, printf("GPT header corrupted\n")); - return NULL; - } - h->header_crc32 = cpu_to_le32(orgcrc); - - /* Valid header has to be at MyLBA */ - if (le64_to_cpu(h->my_lba) != lba) { - DBG(DEBUG_LOWPROBE, printf( - "GPT->MyLBA mismatch with real position\n")); - return NULL; - } - - fu = le64_to_cpu(h->first_usable_lba); - lu = le64_to_cpu(h->last_usable_lba); - - /* Check if First and Last usable LBA makes sense */ - if (lu < fu || fu > lastlba || lu > lastlba) { - DBG(DEBUG_LOWPROBE, printf( - "GPT->{First,Last}UsableLBA out of range\n")); - return NULL; - } - - /* The header has to be outside usable range */ - if (fu < lba && lba < lu) { - DBG(DEBUG_LOWPROBE, printf("GPT header is inside usable area\n")); - return NULL; - } - - /* Size of blocks with GPT entries */ - esz = le32_to_cpu(h->num_partition_entries) * - le32_to_cpu(h->sizeof_partition_entry); - if (!esz) { - DBG(DEBUG_LOWPROBE, printf("GPT entries undefined\n")); - return NULL; - } - - /* The header seems valid, save it - * (we don't care about zeros in hdr->reserved2 area) */ - memcpy(hdr, h, sizeof(*h)); - h = hdr; - - /* Read GPT entries */ - *ents = (struct gpt_entry *) get_lba_buffer(pr, - le64_to_cpu(h->partition_entries_lba), esz); - if (!*ents) { - DBG(DEBUG_LOWPROBE, printf("GPT entries unreadable\n")); - return NULL; - } - - /* Validate entries */ - crc = count_crc32((unsigned char *) *ents, esz); - if (crc != le32_to_cpu(h->partition_entry_array_crc32)) { - DBG(DEBUG_LOWPROBE, printf("GPT entries corrupted\n")); - return NULL; - } - - return h; -} - -static int probe_gpt_pt(blkid_probe pr, const struct blkid_idmag *mag) -{ - uint64_t lastlba = 0, lba; - struct gpt_header hdr, *h; - struct gpt_entry *e; - blkid_parttable tab = NULL; - blkid_partlist ls; - int i; - uint64_t fu, lu; - uint32_t ssf; - - - if (last_lba(pr, &lastlba)) - goto nothing; - - if (!is_pmbr_valid(pr)) - goto nothing; - - h = get_gpt_header(pr, &hdr, &e, (lba = GPT_PRIMARY_LBA), lastlba); - if (!h) - h = get_gpt_header(pr, &hdr, &e, (lba = lastlba), lastlba); - - if (!h) - goto nothing; - - blkid_probe_use_wiper(pr, lba * blkid_probe_get_size(pr), 8); - - if (blkid_partitions_need_typeonly(pr)) - /* caller does not ask for details about partitions */ - return 0; - - ls = blkid_probe_get_partlist(pr); - if (!ls) - goto err; - - tab = blkid_partlist_new_parttable(ls, "gpt", lba << 9); - if (!tab) - goto err; - - ssf = blkid_probe_get_sectorsize(pr) / 512; - - fu = le64_to_cpu(h->first_usable_lba); - lu = le64_to_cpu(h->last_usable_lba); - - for (i = 0; i < le32_to_cpu(h->num_partition_entries); i++, e++) { - - blkid_partition par; - uint64_t start = le64_to_cpu(e->starting_lba); - uint64_t size = le64_to_cpu(e->ending_lba) - - le64_to_cpu(e->starting_lba) + 1ULL; - - /* 00000000-0000-0000-0000-000000000000 entry */ - if (!guidcmp(e->partition_type_guid, GPT_UNUSED_ENTRY_GUID)) { - blkid_partlist_increment_partno(ls); - continue; - } - /* the partition has to inside usable range */ - if (start < fu || start + size - 1 > lu) { - DBG(DEBUG_LOWPROBE, printf( - "GPT entry[%d] overflows usable area - ignore\n", - i)); - blkid_partlist_increment_partno(ls); - continue; - } - - par = blkid_partlist_add_partition(ls, tab, - start * ssf, size * ssf); - if (!par) - goto err; - - blkid_partition_set_utf8name(par, - (unsigned char *) e->partition_name, - sizeof(e->partition_name), BLKID_ENC_UTF16LE); - - swap_efi_guid(&e->unique_partition_guid); - swap_efi_guid(&e->partition_type_guid); - - blkid_partition_set_uuid(par, - (const unsigned char *) &e->unique_partition_guid); - - blkid_partition_set_type_uuid(par, - (const unsigned char *) &e->partition_type_guid); - - blkid_partition_set_flags(par, e->attributes); - } - - return 0; - -nothing: - return 1; -err: - return -1; -} - - -const struct blkid_idinfo gpt_pt_idinfo = -{ - .name = "gpt", - .probefunc = probe_gpt_pt, - .minsz = 1024 * 1440 + 1, /* ignore floppies */ - - /* - * It would be possible to check for DOS signature (0xAA55), but - * unfortunately almost all EFI GPT implemenations allow to optionaly - * skip the legacy MBR. We follows this behavior and MBR is optional. - * See is_valid_pmbr(). - * - * It means we have to always call probe_gpt_pt(). - */ - .magics = BLKID_NONE_MAGIC -}; - diff --git a/shlibs/blkid/src/partitions/mac.c b/shlibs/blkid/src/partitions/mac.c deleted file mode 100644 index 538b2727..00000000 --- a/shlibs/blkid/src/partitions/mac.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * mac partitions parsing code - * - * Copyright (C) 2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * - */ -#include -#include -#include -#include - -#include "partitions.h" - -#define MAC_PARTITION_MAGIC 0x504d -#define MAC_PARTITION_MAGIC_OLD 0x5453 - -/* - * Mac partition entry - * http://developer.apple.com/legacy/mac/library/documentation/mac/Devices/Devices-126.html - */ -struct mac_partition { - uint16_t signature; /* expected to be MAC_PARTITION_MAGIC */ - uint16_t reserved; /* reserved */ - uint32_t map_count; /* # blocks in partition map */ - uint32_t start_block; /* absolute starting block # of partition */ - uint32_t block_count; /* number of blocks in partition */ - char name[32]; /* partition name */ - char type[32]; /* string type description */ - uint32_t data_start; /* rel block # of first data block */ - uint32_t data_count; /* number of data blocks */ - uint32_t status; /* partition status bits */ - uint32_t boot_start; /* first logical block of boot code */ - uint32_t boot_size; /* size of boot code, in bytes */ - uint32_t boot_load; /* boot code load address */ - uint32_t boot_load2; /* reserved */ - uint32_t boot_entry; /* boot code entry point */ - uint32_t boot_entry2; /* reserved */ - uint32_t boot_cksum; /* boot code checksum */ - char processor[16]; /* identifies ISA of boot */ - - /* there is more stuff after this that we don't need */ -} __attribute__((packed)); - -/* - * Driver descriptor structure, in block 0 - * http://developer.apple.com/legacy/mac/library/documentation/mac/Devices/Devices-121.html - */ -struct mac_driver_desc { - uint16_t signature; /* expected to be MAC_DRIVER_MAGIC */ - uint16_t block_size; /* block size of the device */ - uint32_t block_count; /* number of blocks on the device */ - - /* there is more stuff after this that we don't need */ -} __attribute__((packed)); - -static inline unsigned char *get_mac_block( - blkid_probe pr, - struct mac_driver_desc *md, - uint32_t num) -{ - return blkid_probe_get_buffer(pr, - (blkid_loff_t) num * md->block_size, num); -} - -static inline int has_part_signature(struct mac_partition *p) -{ - return be16_to_cpu(p->signature) == MAC_PARTITION_MAGIC || - be16_to_cpu(p->signature) == MAC_PARTITION_MAGIC_OLD; -} - -static int probe_mac_pt(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct mac_driver_desc *md; - struct mac_partition *p; - blkid_parttable tab = NULL; - blkid_partlist ls; - int i; - uint16_t ssf; /* sector size fragment */ - uint32_t nblks; - - - /* The driver descriptor record is always located at physical block 0, - * the first block on the disk. - */ - md = (struct mac_driver_desc *) blkid_probe_get_sector(pr, 0); - if (!md) - goto nothing; - - - /* The partition map always begins at physical block 1, - * the second block on the disk. - */ - p = (struct mac_partition *) get_mac_block(pr, md, 1); - if (!p) - goto nothing; - - /* check the first partition signature */ - if (!has_part_signature(p)) - goto nothing; - - if (blkid_partitions_need_typeonly(pr)) - /* caller does not ask for details about partitions */ - return 0; - - ls = blkid_probe_get_partlist(pr); - if (!ls) - goto err; - - tab = blkid_partlist_new_parttable(ls, "mac", 0); - if (!tab) - goto err; - - ssf = md->block_size / 512; - nblks = be32_to_cpu(p->map_count); - - for (i = 1; i <= nblks; ++i) { - blkid_partition par; - uint32_t start; - uint32_t size; - - p = (struct mac_partition *) get_mac_block(pr, md, i); - if (!p) - goto nothing; - if (!has_part_signature(p)) - goto nothing; - - if (be32_to_cpu(p->map_count) != nblks) { - DBG(DEBUG_LOWPROBE, printf( - "mac: inconsisten map_count in partition map, " - "entry[0]: %d, entry[%d]: %d\n", - nblks, i - 1, - be32_to_cpu(p->map_count))); - } - - /* - * note that libparted ignores some mac partitions according to - * the partition name (e.g. "Apple_Free" or "Apple_Void"). We - * follows Linux kernel and all partitions are visible - */ - - start = be32_to_cpu(p->start_block) * ssf; - size = be32_to_cpu(p->block_count) * ssf; - - par = blkid_partlist_add_partition(ls, tab, start, size); - if (!par) - goto err; - - blkid_partition_set_name(par, (unsigned char *) p->name, - sizeof(p->name)); - - blkid_partition_set_type_string(par, (unsigned char *) p->type, - sizeof(p->type)); - } - - return 0; - -nothing: - return 1; -err: - return -1; -} - -/* - * Mac disk always begin with "Driver Descriptor Record" - * (struct mac_driver_desc) and magic 0x4552. - */ -const struct blkid_idinfo mac_pt_idinfo = -{ - .name = "mac", - .probefunc = probe_mac_pt, - .magics = - { - /* big-endian magic string */ - { .magic = "\x45\x52", .len = 2 }, - { NULL } - } -}; - diff --git a/shlibs/blkid/src/partitions/minix.c b/shlibs/blkid/src/partitions/minix.c deleted file mode 100644 index 0887d1a3..00000000 --- a/shlibs/blkid/src/partitions/minix.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Minix partition parsing code - * - * Copyright (C) 2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include - -#include "partitions.h" -#include "dos.h" - -/* - * Minix subpartitions are always within primary dos partition. - */ -#define MINIX_MAXPARTITIONS 4 - -static int probe_minix_pt(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct dos_partition *p; - blkid_parttable tab = NULL; - blkid_partition parent; - blkid_partlist ls; - unsigned char *data; - int i; - - data = blkid_probe_get_sector(pr, 0); - if (!data) - goto nothing; - - ls = blkid_probe_get_partlist(pr); - if (!ls) - goto err; - - /* Parent is required, because Minix uses the same PT as DOS and - * difference is only in primary partition (parent) type. - */ - parent = blkid_partlist_get_parent(ls); - if (!parent) - goto nothing; - - if (blkid_partition_get_type(parent) != BLKID_MINIX_PARTITION) - goto nothing; - - if (blkid_partitions_need_typeonly(pr)) - /* caller does not ask for details about partitions */ - return 0; - - p = (struct dos_partition *) (data + BLKID_MSDOS_PT_OFFSET); - - tab = blkid_partlist_new_parttable(ls, "minix", BLKID_MSDOS_PT_OFFSET); - if (!tab) - goto err; - - for (i = 0; i < MINIX_MAXPARTITIONS; i++, p++) { - uint32_t start, size; - blkid_partition par; - - if (p->sys_type != BLKID_MINIX_PARTITION) - continue; - - start = dos_partition_start(p); - size = dos_partition_size(p); - - if (parent && !blkid_is_nested_dimension(parent, start, size)) { - DBG(DEBUG_LOWPROBE, printf( - "WARNING: minix partition (%d) overflow " - "detected, ignore\n", i)); - continue; - } - - par = blkid_partlist_add_partition(ls, tab, start, size); - if (!par) - goto err; - - blkid_partition_set_type(par, p->sys_type); - blkid_partition_set_flags(par, p->boot_ind); - } - - return 0; - -nothing: - return 1; -err: - return -1; -} - -/* same as DOS */ -const struct blkid_idinfo minix_pt_idinfo = -{ - .name = "minix", - .probefunc = probe_minix_pt, - .magics = - { - { .magic = "\x55\xAA", .len = 2, .sboff = 510 }, - { NULL } - } -}; - diff --git a/shlibs/blkid/src/partitions/partitions.c b/shlibs/blkid/src/partitions/partitions.c deleted file mode 100644 index 89f05871..00000000 --- a/shlibs/blkid/src/partitions/partitions.c +++ /dev/null @@ -1,1336 +0,0 @@ -/* - * partitions - partition tables parsing - * - * Copyright (C) 2008-2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "partitions.h" -#include "sysfs.h" - -/** - * SECTION:partitions - * @title: Partitions probing - * @short_description: partitions tables detection and parsing - * - * This chain supports binary and NAME=value interfaces, but complete PT - * description is provided by binary interface only. The libblkid prober is - * compatible with kernel partition tables parser. The parser does not return - * empty (size=0) partitions or special hidden partitions. - * - * NAME=value interface, supported tags: - * - * @PTTYPE: partition table type (dos, gpt, etc.). - * - * @PART_ENTRY_SCHEME: partition table type - * - * @PART_ENTRY_NAME: partition name (gpt and mac only) - * - * @PART_ENTRY_UUID: partition UUID (gpt only) - * - * @PART_ENTRY_TYPE: partition type, 0xNN (e.g 0x82) or type UUID (gpt only) or type string (mac) - * - * @PART_ENTRY_FLAGS: partition flags (e.g. boot_ind) or attributes (e.g. gpt attributes) - * - * @PART_ENTRY_NUMBER: partition number - * - * Example: - * - * - * - * blkid_probe pr; - * const char *ptname; - * - * pr = blkid_new_probe_from_filename(devname); - * if (!pr) - * err("%s: faild to open device", devname); - * - * blkid_probe_enable_partitions(pr, TRUE); - * blkid_do_fullprobe(pr); - * - * blkid_probe_lookup_value(pr, "PTTYPE", &ptname, NULL); - * printf("%s partition type detected\n", pttype); - * - * blkid_free_probe(pr); - * - * // don't forget to check return codes in your code! - * - * - * - * Binary interface: - * - * - * - * blkid_probe pr; - * blkid_partlist ls; - * int nparts, i; - * - * pr = blkid_new_probe_from_filename(devname); - * if (!pr) - * err("%s: faild to open device", devname); - * - * ls = blkid_probe_get_partitions(pr); - * nparts = blkid_partlist_numof_partitions(ls); - * - * for (i = 0; i < nparts; i++) { - * blkid_partition par = blkid_partlist_get_partition(ls, i); - * printf("#%d: %llu %llu 0x%x", - * blkid_partition_get_partno(par), - * blkid_partition_get_start(par), - * blkid_partition_get_size(par), - * blkid_partition_get_type(par)); - * } - * - * blkid_free_probe(pr); - * - * // don't forget to check return codes in your code! - * - * - */ - -/* - * Chain driver function - */ -static int partitions_probe(blkid_probe pr, struct blkid_chain *chn); -static void partitions_free_data(blkid_probe pr, void *data); - -/* - * Partitions chain probing functions - */ -static const struct blkid_idinfo *idinfos[] = -{ - &aix_pt_idinfo, - &sgi_pt_idinfo, - &sun_pt_idinfo, - &dos_pt_idinfo, - &gpt_pt_idinfo, - &mac_pt_idinfo, - &ultrix_pt_idinfo, - &bsd_pt_idinfo, - &unixware_pt_idinfo, - &solaris_x86_pt_idinfo, - &minix_pt_idinfo -}; - -/* - * Driver definition - */ -const struct blkid_chaindrv partitions_drv = { - .id = BLKID_CHAIN_PARTS, - .name = "partitions", - .dflt_enabled = FALSE, - .idinfos = idinfos, - .nidinfos = ARRAY_SIZE(idinfos), - .has_fltr = TRUE, - .probe = partitions_probe, - .safeprobe = partitions_probe, - .free_data = partitions_free_data -}; - - -/* - * For compatibility with the rest of libblkid API (with the old high-level - * API) we use completely opaque typedefs for all structs. Don't forget that - * the final blkid_* types are pointers! See blkid.h. - * - * [Just for the record, I hate typedef for pointers --kzak] - */ - -/* exported as opaque type "blkid_parttable" */ -struct blkid_struct_parttable { - const char *type; /* partition table type */ - blkid_loff_t offset; /* begin of the partition table */ - int nparts; /* number of partitions */ - blkid_partition parent; /* parent of nested partition table */ - - struct list_head t_tabs; /* all tables */ -}; - -/* exported as opaque type "blkid_partition" */ -struct blkid_struct_partition { - blkid_loff_t start; /* begin of the partition */ - blkid_loff_t size; /* size of the partitions */ - - int type; /* partition type */ - char typestr[37]; /* partition type string (GPT and Mac) */ - - unsigned long long flags; /* partition flags / attributes */ - - int partno; /* partition number */ - char uuid[37]; /* UUID (when supported by PT), e.g GPT */ - unsigned char name[128]; /* Partition in UTF8 name (when supporte by PT), e.g. Mac */ - - blkid_parttable tab; /* partition table */ -}; - -/* exported as opaque type "blkid_partlist" */ -struct blkid_struct_partlist { - int next_partno; /* next partition number */ - blkid_partition next_parent; /* next parent if parsing nested PT */ - - int nparts; /* number of partitions */ - int nparts_max; /* max.number of partitions */ - blkid_partition parts; /* array of partitions */ - - struct list_head l_tabs; /* list of partition tables */ -}; - -static int blkid_partitions_probe_partition(blkid_probe pr); - -/** - * blkid_probe_enable_partitions: - * @pr: probe - * @enable: TRUE/FALSE - * - * Enables/disables the partitions probing for non-binary interface. - * - * Returns: 0 on success, or -1 in case of error. - */ -int blkid_probe_enable_partitions(blkid_probe pr, int enable) -{ - if (!pr) - return -1; - pr->chains[BLKID_CHAIN_PARTS].enabled = enable; - return 0; -} - -/** - * blkid_probe_set_partitions_flags: - * @pr: prober - * @flags: BLKID_PARTS_* flags - * - * Sets probing flags to the partitions prober. This function is optional. - * - * Returns: 0 on success, or -1 in case of error. - */ -int blkid_probe_set_partitions_flags(blkid_probe pr, int flags) -{ - if (!pr) - return -1; - - pr->chains[BLKID_CHAIN_PARTS].flags = flags; - return 0; -} - -/** - * blkid_probe_reset_partitions_filter: - * @pr: prober - * - * Resets partitions probing filter - * - * Returns: 0 on success, or -1 in case of error. - */ -int blkid_probe_reset_partitions_filter(blkid_probe pr) -{ - return __blkid_probe_reset_filter(pr, BLKID_CHAIN_PARTS); -} - -/** - * blkid_probe_invert_partitions_filter: - * @pr: prober - * - * Inverts partitions probing filter - * - * Returns: 0 on success, or -1 in case of error. - */ -int blkid_probe_invert_partitions_filter(blkid_probe pr) -{ - return __blkid_probe_invert_filter(pr, BLKID_CHAIN_PARTS); -} - -/** - * blkid_probe_filter_partitions_type: - * @pr: prober - * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag - * @names: NULL terminated array of probing function names (e.g. "vfat"). - * - * BLKID_FLTR_NOTIN - probe for all items which are NOT IN @names - * BLKID_FLTR_ONLYIN - probe for items which are IN @names - * - * Returns: 0 on success, or -1 in case of error. - */ -int blkid_probe_filter_partitions_type(blkid_probe pr, int flag, char *names[]) -{ - return __blkid_probe_filter_types(pr, BLKID_CHAIN_PARTS, flag, names); -} - -/** - * blkid_probe_get_partitions: - * @pr: probe - * - * This is a binary interface for partitions. See also blkid_partlist_* - * functions. - * - * This function is independent on blkid_do_[safe,full]probe() and - * blkid_probe_enable_partitions() calls. - * - * WARNING: the returned object will be overwritten by the next - * blkid_probe_get_partitions() call for the same @pr. If you want to - * use more blkid_partlist objects in the same time you have to create - * more blkid_probe handlers (see blkid_new_probe()). - * - * Returns: list of partitions, or NULL in case of error. - */ -blkid_partlist blkid_probe_get_partitions(blkid_probe pr) -{ - return (blkid_partlist) blkid_probe_get_binary_data(pr, - &pr->chains[BLKID_CHAIN_PARTS]); -} - -/* for internal usage only */ -blkid_partlist blkid_probe_get_partlist(blkid_probe pr) -{ - return (blkid_partlist) pr->chains[BLKID_CHAIN_PARTS].data; -} - -static void blkid_probe_set_partlist(blkid_probe pr, blkid_partlist ls) -{ - pr->chains[BLKID_CHAIN_PARTS].data = ls; -} - -static void ref_parttable(blkid_parttable tab) -{ - tab->nparts++; -} - -static void unref_parttable(blkid_parttable tab) -{ - tab->nparts--; - - if (tab->nparts <= 0) { - list_del(&tab->t_tabs); - free(tab); - } -} - -/* free all allocated parttables */ -static void free_parttables(blkid_partlist ls) -{ - if (!ls || !ls->l_tabs.next) - return; - - /* remove unassigned partition tables */ - while (!list_empty(&ls->l_tabs)) { - blkid_parttable tab = list_entry(ls->l_tabs.next, - struct blkid_struct_parttable, t_tabs); - unref_parttable(tab); - } -} - -static void reset_partlist(blkid_probe pr, blkid_partlist ls) -{ - if (!ls) - return; - - free_parttables(ls); - - if (ls->next_partno) { - /* already initialized - reset */ - int tmp_nparts = ls->nparts_max; - blkid_partition tmp_parts = ls->parts; - - memset(ls, 0, sizeof(struct blkid_struct_partlist)); - - ls->nparts_max = tmp_nparts; - ls->parts = tmp_parts; - } - - ls->nparts = 0; - ls->next_partno = 1; - INIT_LIST_HEAD(&ls->l_tabs); - - DBG(DEBUG_LOWPROBE, printf("partlist reseted\n")); -} - -static blkid_partlist partitions_init_data(blkid_probe pr, struct blkid_chain *chn) -{ - blkid_partlist ls; - - if (chn->data) - ls = (blkid_partlist) chn->data; - else { - /* allocate the new list of partitions */ - ls = calloc(1, sizeof(struct blkid_struct_partlist)); - if (!ls) - return NULL; - chn->data = (void *) ls; - } - - reset_partlist(pr, ls); - - DBG(DEBUG_LOWPROBE, - printf("parts: initialized partitions list (%p, size=%d)\n", - ls, ls->nparts_max)); - return ls; -} - -static void partitions_free_data(blkid_probe pr, void *data) -{ - blkid_partlist ls = (blkid_partlist) data; - - if (!ls) - return; - - free_parttables(ls); - - /* deallocate partitions and partlist */ - free(ls->parts); - free(ls); -} - -blkid_parttable blkid_partlist_new_parttable(blkid_partlist ls, - const char *type, blkid_loff_t offset) -{ - blkid_parttable tab; - - tab = calloc(1, sizeof(struct blkid_struct_parttable)); - if (!tab) - return NULL; - tab->type = type; - tab->offset = offset; - tab->parent = ls->next_parent; - - INIT_LIST_HEAD(&tab->t_tabs); - list_add_tail(&tab->t_tabs, &ls->l_tabs); - - DBG(DEBUG_LOWPROBE, - printf("parts: create a new partition table " - "(%p, type=%s, offset=%"PRId64")\n", tab, type, offset)); - return tab; -} - -static blkid_partition new_partition(blkid_partlist ls, blkid_parttable tab) -{ - blkid_partition par; - - if (ls->nparts + 1 > ls->nparts_max) { - /* Linux kernel has DISK_MAX_PARTS=256, but it's too much for - * generic Linux machine -- let start with 32 partititions. - */ - ls->parts = realloc(ls->parts, (ls->nparts_max + 32) * - sizeof(struct blkid_struct_partition)); - if (!ls->parts) - return NULL; - ls->nparts_max += 32; - } - - par = &ls->parts[ls->nparts++]; - memset(par, 0, sizeof(struct blkid_struct_partition)); - - ref_parttable(tab); - par->tab = tab; - par->partno = blkid_partlist_increment_partno(ls); - - return par; -} - -blkid_partition blkid_partlist_add_partition(blkid_partlist ls, - blkid_parttable tab, - blkid_loff_t start, blkid_loff_t size) -{ - blkid_partition par = new_partition(ls, tab); - - if (!par) - return NULL; - - par->start = start; - par->size = size; - - DBG(DEBUG_LOWPROBE, - printf("parts: add partition (%p start=%" - PRId64 ", size=%" PRId64 ", table=%p)\n", - par, par->start, par->size, tab)); - return par; -} - -/* allows to modify used partitions numbers (for example for logical partitions) */ -int blkid_partlist_set_partno(blkid_partlist ls, int partno) -{ - if (!ls) - return -1; - ls->next_partno = partno; - return 0; -} - -int blkid_partlist_increment_partno(blkid_partlist ls) -{ - return ls ? ls->next_partno++ : -1; -} - -/* allows to set "parent" for the next nested partition */ -int blkid_partlist_set_parent(blkid_partlist ls, blkid_partition par) -{ - if (!ls) - return -1; - ls->next_parent = par; - return 0; -} - -blkid_partition blkid_partlist_get_parent(blkid_partlist ls) -{ - if (!ls) - return NULL; - return ls->next_parent; -} - -int blkid_partitions_need_typeonly(blkid_probe pr) -{ - struct blkid_chain *chn = blkid_probe_get_chain(pr); - - return chn && chn->data && chn->binary ? FALSE : TRUE; -} - -/* get private chain flags */ -int blkid_partitions_get_flags(blkid_probe pr) -{ - struct blkid_chain *chn = blkid_probe_get_chain(pr); - - return chn ? chn->flags : 0; -} - -/* check if @start and @size are within @par partition */ -int blkid_is_nested_dimension(blkid_partition par, - blkid_loff_t start, blkid_loff_t size) -{ - blkid_loff_t pstart; - blkid_loff_t psize; - - if (!par) - return 0; - - pstart = blkid_partition_get_start(par); - psize = blkid_partition_get_size(par); - - if (start < pstart || start + size > pstart + psize) - return 0; - - return 1; -} - -static int idinfo_probe(blkid_probe pr, const struct blkid_idinfo *id) -{ - const struct blkid_idmag *mag; - int rc = 1; /* = nothing detected */ - - if (pr->size <= 0 || (id->minsz && id->minsz > pr->size)) - goto nothing; /* the device is too small */ - - if (blkid_probe_get_idmag(pr, id, NULL, &mag)) - goto nothing; - - /* final check by probing function */ - if (id->probefunc) { - DBG(DEBUG_LOWPROBE, printf( - "%s: ---> call probefunc()\n", id->name)); - rc = id->probefunc(pr, mag); - if (rc == -1) { - /* reset after error */ - reset_partlist(pr, blkid_probe_get_partlist(pr)); - DBG(DEBUG_LOWPROBE, printf( - "%s probefunc failed\n", id->name)); - } - DBG(DEBUG_LOWPROBE, printf( - "%s: <--- (rc = %d)\n", id->name, rc)); - } - -nothing: - return rc; -} - -/* - * The blkid_do_probe() backend. - */ -static int partitions_probe(blkid_probe pr, struct blkid_chain *chn) -{ - int i = 0, rc = 1; - - if (!pr || chn->idx < -1) - return -1; - blkid_probe_chain_reset_vals(pr, chn); - - if (chn->binary) - partitions_init_data(pr, chn); - - if (!pr->wipe_size && (pr->prob_flags & BLKID_PROBE_FL_IGNORE_PT)) - goto details_only; - - DBG(DEBUG_LOWPROBE, - printf("--> starting probing loop [PARTS idx=%d]\n", - chn->idx)); - - i = chn->idx + 1; - - for ( ; i < ARRAY_SIZE(idinfos); i++) { - const char *name; - - chn->idx = i; - - /* apply filter */ - if (chn->fltr && blkid_bmp_get_item(chn->fltr, i)) - continue; - - /* apply checks from idinfo */ - if (idinfo_probe(pr, idinfos[i]) != 0) - continue; - - name = idinfos[i]->name; - - /* all checks passed */ - if (!chn->binary) - blkid_probe_set_value(pr, "PTTYPE", - (unsigned char *) name, - strlen(name) + 1); - DBG(DEBUG_LOWPROBE, - printf("<-- leaving probing loop (type=%s) [PARTS idx=%d]\n", - name, chn->idx)); - rc = 0; - break; - } - - if (rc == 1) { - DBG(DEBUG_LOWPROBE, - printf("<-- leaving probing loop (failed) [PARTS idx=%d]\n", - chn->idx)); - } - -details_only: - /* - * Gather PART_ENTRY_* values if the current device is a partition. - */ - if (!chn->binary && - (blkid_partitions_get_flags(pr) & BLKID_PARTS_ENTRY_DETAILS)) { - - if (!blkid_partitions_probe_partition(pr)) - rc = 0; - } - - return rc; -} - -/* Probe for nested partition table within the parental partition */ -int blkid_partitions_do_subprobe(blkid_probe pr, blkid_partition parent, - const struct blkid_idinfo *id) -{ - blkid_probe prc; - int rc = 1; - blkid_partlist ls; - blkid_loff_t sz, off; - - DBG(DEBUG_LOWPROBE, printf( - "parts: ----> %s subprobe requested (parent=%p)\n", - id->name, parent)); - - if (!pr || !parent || !parent->size) - return -1; - - /* range defined by parent */ - sz = ((blkid_loff_t) parent->size) << 9; - off = ((blkid_loff_t) parent->start) << 9; - - if (off < pr->off || pr->off + pr->size < off + sz) { - DBG(DEBUG_LOWPROBE, printf( - "ERROR: parts: <---- '%s' subprobe: overflow detected.\n", - id->name)); - return -1; - } - - /* create private prober */ - prc = blkid_clone_probe(pr); - if (!prc) - return -1; - - blkid_probe_set_dimension(prc, off, sz); - - /* clone is always with reseted chain, fix it */ - prc->cur_chain = blkid_probe_get_chain(pr); - - /* - * Set 'parent' to the current list of the partitions and use the list - * in cloned prober (so the cloned prober will extend the current list - * of partitions rather than create a new). - */ - ls = blkid_probe_get_partlist(pr); - blkid_partlist_set_parent(ls, parent); - - blkid_probe_set_partlist(prc, ls); - - rc = idinfo_probe(prc, id); - - blkid_probe_set_partlist(prc, NULL); - blkid_partlist_set_parent(ls, NULL); - - blkid_free_probe(prc); /* free cloned prober */ - - DBG(DEBUG_LOWPROBE, printf( - "parts: <---- %s subprobe done (parent=%p, rc=%d)\n", - id->name, parent, rc)); - - return rc; -} - -static int blkid_partitions_probe_partition(blkid_probe pr) -{ - int rc = 1; - blkid_probe disk_pr = NULL; - blkid_partlist ls; - blkid_partition par; - dev_t devno; - - devno = blkid_probe_get_devno(pr); - if (!devno) - goto nothing; - - disk_pr = blkid_probe_get_wholedisk_probe(pr); - if (!disk_pr) - goto nothing; - - /* parse PT */ - ls = blkid_probe_get_partitions(disk_pr); - if (!ls) - goto nothing; - - par = blkid_partlist_devno_to_partition(ls, devno); - if (par) { - const char *v; - blkid_parttable tab = blkid_partition_get_table(par); - dev_t disk = blkid_probe_get_devno(disk_pr); - - if (tab) { - v = blkid_parttable_get_type(tab); - if (v) - blkid_probe_set_value(pr, "PART_ENTRY_SCHEME", - (unsigned char *) v, strlen(v) + 1); - } - - v = blkid_partition_get_name(par); - if (v) - blkid_probe_set_value(pr, "PART_ENTRY_NAME", - (unsigned char *) v, strlen(v) + 1); - - v = blkid_partition_get_uuid(par); - if (v) - blkid_probe_set_value(pr, "PART_ENTRY_UUID", - (unsigned char *) v, strlen(v) + 1); - - /* type */ - v = blkid_partition_get_type_string(par); - if (v) - blkid_probe_set_value(pr, "PART_ENTRY_TYPE", - (unsigned char *) v, strlen(v) + 1); - else - blkid_probe_sprintf_value(pr, "PART_ENTRY_TYPE", - "0x%x", blkid_partition_get_type(par)); - - if (blkid_partition_get_flags(par)) - blkid_probe_sprintf_value(pr, "PART_ENTRY_FLAGS", - "0x%llx", blkid_partition_get_flags(par)); - - blkid_probe_sprintf_value(pr, "PART_ENTRY_NUMBER", - "%d", blkid_partition_get_partno(par)); - - blkid_probe_sprintf_value(pr, "PART_ENTRY_OFFSET", "%jd", - blkid_partition_get_start(par)); - blkid_probe_sprintf_value(pr, "PART_ENTRY_SIZE", "%jd", - blkid_partition_get_size(par)); - - blkid_probe_sprintf_value(pr, "PART_ENTRY_DISK", "%u:%u", - major(disk), minor(disk)); - } - rc = 0; -nothing: - return rc; -} - -/* - * Returns 1 if the device is whole-disk and the area specified by @offset and - * @size is covered by any partition. - */ -int blkid_probe_is_covered_by_pt(blkid_probe pr, - blkid_loff_t offset, blkid_loff_t size) -{ - blkid_probe prc; - blkid_partlist ls = NULL; - blkid_loff_t start, end; - int nparts, i, rc = 0; - - DBG(DEBUG_LOWPROBE, printf( - "=> checking if off=%jd size=%jd covered by PT\n", - offset, size)); - - prc = blkid_clone_probe(pr); - if (!prc) - goto done; - - ls = blkid_probe_get_partitions(prc); - if (!ls) - goto done; - - nparts = blkid_partlist_numof_partitions(ls); - if (!nparts) - goto done; - - end = (offset + size) >> 9; - start = offset >> 9; - - /* check if the partition table fits into the device */ - for (i = 0; i < nparts; i++) { - blkid_partition par = &ls->parts[i]; - - if (par->start + par->size > (pr->size >> 9)) { - DBG(DEBUG_LOWPROBE, printf("partition #%d overflows " - "device (off=%" PRId64 " size=%" PRId64 ")\n", - par->partno, par->start, par->size)); - goto done; - } - } - - /* check if the requested area is covered by PT */ - for (i = 0; i < nparts; i++) { - blkid_partition par = &ls->parts[i]; - - if (start >= par->start && end <= par->start + par->size) { - rc = 1; - break; - } - } -done: - blkid_free_probe(prc); - - DBG(DEBUG_LOWPROBE, printf("<= %s covered by PT\n", rc ? "IS" : "NOT")); - return rc; -} - -/** - * blkid_known_pttype: - * @pttype: partiton name - * - * Returns: 1 for known or 0 for unknown partition type. - */ -int blkid_known_pttype(const char *pttype) -{ - int i; - - if (!pttype) - return 0; - - for (i = 0; i < ARRAY_SIZE(idinfos); i++) { - const struct blkid_idinfo *id = idinfos[i]; - if (strcmp(id->name, pttype) == 0) - return 1; - } - return 0; -} - -/** - * blkid_partlist_numof_partitions: - * @ls: partitions list - * - * Returns: number of partitions in the list or -1 in case of error. - */ -int blkid_partlist_numof_partitions(blkid_partlist ls) -{ - return ls ? ls->nparts : -1; -} - -/** - * blkid_partlist_get_table: - * - * Returns top-level partition table or NULL of there is not a partition table - * on the device. - */ -blkid_parttable blkid_partlist_get_table(blkid_partlist ls) -{ - if (!ls || list_empty(&ls->l_tabs)) - return NULL; - - return list_entry(ls->l_tabs.next, - struct blkid_struct_parttable, t_tabs); -} - - -/** - * blkid_partlist_get_partition: - * @ls: partitions list - * @n: partition number in range 0..N, where 'N' is blkid_partlist_numof_partitions(). - * - * It's possible that the list of partitions is *empty*, but there is a valid - * partition table on the disk. This happen when on-disk details about - * partitions are unknown or the partition table is empty. - * - * See also blkid_partlist_get_table(). - * - * Returns: partition object or NULL in case or error. - */ -blkid_partition blkid_partlist_get_partition(blkid_partlist ls, int n) -{ - if (!ls || n < 0 || n >= ls->nparts) - return NULL; - - return &ls->parts[n]; -} - -/** - * blkid_partlist_devno_to_partition: - * @ls: partitions list - * @devno: requested partition - * - * This function tries to get start and size for @devno from sysfs and - * returns a partition from @ls which matches with the values from sysfs. - * - * This funtion is necessary when you want to make a relation between an entry - * in the partition table (@ls) and block devices in your system. - * - * Returns: partition object or NULL in case or error. - */ -blkid_partition blkid_partlist_devno_to_partition(blkid_partlist ls, dev_t devno) -{ - struct sysfs_cxt sysfs; - uint64_t start, size; - int i, rc, partno = 0; - - DBG(DEBUG_LOWPROBE, - printf("triyng to convert devno 0x%llx to partition\n", - (long long) devno)); - - if (sysfs_init(&sysfs, devno, NULL)) { - DBG(DEBUG_LOWPROBE, printf("failed t init sysfs context\n")); - return NULL; - } - rc = sysfs_read_u64(&sysfs, "size", &size); - if (!rc) { - rc = sysfs_read_u64(&sysfs, "start", &start); - if (rc) { - /* try to get partition number from DM uuid. - */ - char *uuid = sysfs_strdup(&sysfs, "dm/uuid"); - char *tmp = uuid; - char *prefix = uuid ? strsep(&tmp, "-") : NULL; - - if (prefix && strncasecmp(prefix, "part", 4) == 0) { - char *end = NULL; - - partno = strtol(prefix + 4, &end, 10); - if (prefix == end || (end && *end)) - partno = 0; - else - rc = 0; /* success */ - } - free(uuid); - } - } - - sysfs_deinit(&sysfs); - - if (rc) - return NULL; - - if (partno) { - DBG(DEBUG_LOWPROBE, printf("mapped by DM, using partno %d\n", partno)); - - /* - * Partition mapped by kpartx does not provide "start" offset - * in /sys, but if we know partno and size of the partition - * that we can probably make the releation bettween the device - * and an entry in partition table. - */ - for (i = 0; i < ls->nparts; i++) { - blkid_partition par = &ls->parts[i]; - - if (partno != blkid_partition_get_partno(par)) - continue; - - if (size == blkid_partition_get_size(par) || - (blkid_partition_is_extended(par) && size <= 1024)) - return par; - - } - return NULL; - } - - DBG(DEBUG_LOWPROBE, printf("searching by offset/size\n")); - - for (i = 0; i < ls->nparts; i++) { - blkid_partition par = &ls->parts[i]; - - if (blkid_partition_get_start(par) == start && - blkid_partition_get_size(par) == size) - return par; - - /* exception for extended dos partitions */ - if (blkid_partition_get_start(par) == start && - blkid_partition_is_extended(par) && size <= 1024) - return par; - - } - - DBG(DEBUG_LOWPROBE, printf("not found partition for device\n")); - return NULL; -} - -int blkid_partition_set_type(blkid_partition par, int type) -{ - if (!par) - return -1; - par->type = type; - return 0; -} - -/** - * blkid_parttable_get_type: - * @tab: partition table - * - * Returns: partition table type (type name, e.g. "dos", "gpt", ...) - */ -const char *blkid_parttable_get_type(blkid_parttable tab) -{ - return tab ? tab->type : NULL; -} - -/** - * blkid_parttable_get_parent: - * @tab: partition table - * - * Returns: parent for nexted partitition tables or NULL. - */ -blkid_partition blkid_parttable_get_parent(blkid_parttable tab) -{ - return tab ? tab->parent : NULL; -} - -/** - * blkid_parttable_get_offset: - * @tab: partition table - * - * Returns: position (in bytes) of the partition table or -1 in case of error. - * - * Note the position is relative to begin of the device as defined by - * blkid_probe_set_device() for primary partition table, and relative - * to parental partition for nested patition tables. - * - * - * - * off_t offset; - * blkid_partition parent = blkid_parttable_get_parent(tab); - * - * offset = blkid_parttable_get_offset(tab); - * - * if (parent) - * / * 'tab' is nested partition table * / - * offset += blkid_partition_get_start(parent); - * - * - */ -blkid_loff_t blkid_parttable_get_offset(blkid_parttable tab) -{ - return tab ? tab->offset : -1; -} - -/** - * blkid_partition_get_table: - * @par: partition - * - * The "parttable" describes partition table. The table is usually the same for - * all partitions -- except nested partition tables. - * - * For example bsd, solaris, etc. use a nested partition table within - * standard primary dos partition: - * - * - * - * - * -- dos partition table - * 0: sda1 dos primary partition - * 1: sda2 dos primary partition - * -- bsd partition table (with in sda2) - * 2: sda5 bds partition - * 3: sda6 bds partition - * - * - * - * - * The library does not to use a separate partition table object for dos logical - * partitions (partitions within extended partition). It's possible to - * differentiate between logical, extended and primary partitions by - * - * blkid_partition_is_{extended,primary,logical}(). - * - * Returns: partition table object or NULL in case of error. - */ -blkid_parttable blkid_partition_get_table(blkid_partition par) -{ - return par ? par->tab : NULL; -} - -static int partition_get_logical_type(blkid_partition par) -{ - blkid_parttable tab; - - if (!par) - return -1; - - tab = blkid_partition_get_table(par); - if (!tab || !tab->type) - return -1; - - if (tab->parent) - return 'L'; /* report nested partitions as logical */ - - if (!strcmp(tab->type, "dos")) { - if (par->partno > 4) - return 'L'; /* logical */ - - if(par->type == BLKID_DOS_EXTENDED_PARTITION || - par->type == BLKID_W95_EXTENDED_PARTITION || - par->type == BLKID_LINUX_EXTENDED_PARTITION) - return 'E'; - } - return 'P'; -} - -/** - * blkid_partition_is_primary: - * @par: partition - * - * Note, this function returns FALSE for DOS extended partitions and - * all partitions in nested partition tables. - * - * Returns: 1 if the partitions is primary partition or 0 if not. - */ -int blkid_partition_is_primary(blkid_partition par) -{ - return partition_get_logical_type(par) == 'P' ? TRUE : FALSE; -} - -/** - * blkid_partition_is_extended: - * @par: partition - * - * Returns: 1 if the partitions is extended (dos, windows or linux) - * partition or 0 if not. - */ -int blkid_partition_is_extended(blkid_partition par) -{ - return partition_get_logical_type(par) == 'E' ? TRUE : FALSE; -} - -/** - * blkid_partition_is_logical: - * @par: partition - * - * Note that this function returns TRUE for all partitions in all - * nested partition tables (e.g. BSD labels). - * - * Returns: 1 if the partitions is logical partition or 0 if not. - */ -int blkid_partition_is_logical(blkid_partition par) -{ - return partition_get_logical_type(par) == 'L' ? TRUE : FALSE; -} - -static void set_string(unsigned char *item, size_t max, - const unsigned char *data, size_t len) -{ - if (len >= max) - len = max - 1; - - memcpy(item, data, len); - item[len] = '\0'; - - blkid_rtrim_whitespace(item); -} - -int blkid_partition_set_name(blkid_partition par, - const unsigned char *name, size_t len) -{ - if (!par) - return -1; - - set_string(par->name, sizeof(par->name), name, len); - return 0; -} - -int blkid_partition_set_utf8name(blkid_partition par, const unsigned char *name, - size_t len, int enc) -{ - if (!par) - return -1; - - blkid_encode_to_utf8(enc, par->name, sizeof(par->name), name, len); - blkid_rtrim_whitespace(par->name); - return 0; -} - -int blkid_partition_set_uuid(blkid_partition par, const unsigned char *uuid) -{ - if (!par) - return -1; - - blkid_unparse_uuid(uuid, par->uuid, sizeof(par->uuid)); - return 0; -} - -/** - * blkid_partition_get_name: - * @par: partition - * - * Returns: partition name string if supported by PT (e.g. Mac) or NULL. - */ -const char *blkid_partition_get_name(blkid_partition par) -{ - return par && *par->name ? (char *) par->name : NULL; -} - -/** - * blkid_partition_get_uuid: - * @par: partition - * - * Returns: partition UUID string if supported by PT (e.g. GPT) or NULL. - */ -const char *blkid_partition_get_uuid(blkid_partition par) -{ - return par && *par->uuid ? par->uuid : NULL; -} - -/** - * blkid_partition_get_partno: - * @par: partition - * - * Returns: proposed partitin number (e.g. 'N' from sda'N') or -1 in case of - * error. Note that the number is generate by library independenly on your OS. - */ -int blkid_partition_get_partno(blkid_partition par) -{ - return par ? par->partno : -1; -} - -/** - * blkid_partition_get_start: - * @par: partition - * - * Be careful if you _not_ probe whole disk: - * - * 1) the offset is usully relative to begin of the disk -- but if you probe a - * fragment of the disk only -- then the offset could be still relative to - * the begin of the disk rather that relative to the fragment. - * - * 2) the offset for nested partitions could be releative to parent (e.g. Solaris) - * _or_ relative to the begin of the whole disk (e.g. bsd). - * - * You don't have to care about such details if you proble whole disk. In such - * a case libblkid always returns the offset relative to the begin of the disk. - * - * Returns: start of the partition (in 512-sectors). - */ -blkid_loff_t blkid_partition_get_start(blkid_partition par) -{ - return par ? par->start : -1; -} - -/** - * blkid_partition_get_size: - * @par: partition - * - * WARNING: be very careful when you work with MS-DOS extended partitions. The - * library always returns full size of the partition. If you want add - * the partition to the Linux system (BLKPG_ADD_PARTITION ioctl) you - * need to reduce the size of the partition to 1 or 2 blocks. The - * rest of the partition has to be unaccessible for mkfs or mkswap - * programs, we need a small space for boot loaders only. - * - * For some unknown reason this (safe) practice is not to used for - * nested BSD, Solaris, ..., partition tables in Linux kernel. - * - * Returns: size of the partition (in 512-sectors). - */ -blkid_loff_t blkid_partition_get_size(blkid_partition par) -{ - return par ? par->size : -1; -} - -/** - * blkid_partition_get_type: - * @par: partition - * - * Returns: partition type. - */ -int blkid_partition_get_type(blkid_partition par) -{ - return par ? par->type : 0; -} - -/* Sets partition 'type' for PT where the type is defined by string rather - * than by number - */ -int blkid_partition_set_type_string(blkid_partition par, - const unsigned char *type, size_t len) -{ - if (!par) - return -1; - - set_string((unsigned char *) par->typestr, - sizeof(par->typestr), type, len); - return 0; -} - -/* Sets partition 'type' for PT where the type is defined by UUIDrather - * than by number - */ -int blkid_partition_set_type_uuid(blkid_partition par, const unsigned char *uuid) -{ - if (!par) - return -1; - - blkid_unparse_uuid(uuid, par->typestr, sizeof(par->typestr)); - return 0; -} - -/** - * blkid_partition_get_type_string: - * @par: partition - * - * The type string is supported by a small subset of partition tables (e.g Mac - * and EFI GPT). Note that GPT uses type UUID and this function returns this - * UUID as string. - * - * Returns: partition type string or NULL. - */ -const char *blkid_partition_get_type_string(blkid_partition par) -{ - return par && *par->typestr ? par->typestr : NULL; -} - - -int blkid_partition_set_flags(blkid_partition par, unsigned long long flags) -{ - if (!par) - return -1; - par->flags = flags; - return 0; -} - -/** - * blkid_partition_get_flags - * @par: partition - * - * Returns: partition flags (or attributes for gpt). - */ -unsigned long long blkid_partition_get_flags(blkid_partition par) -{ - return par ? par->flags : 0; -} - diff --git a/shlibs/blkid/src/partitions/partitions.h b/shlibs/blkid/src/partitions/partitions.h deleted file mode 100644 index c4ccd3b6..00000000 --- a/shlibs/blkid/src/partitions/partitions.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef BLKID_PARTITIONS_H -#define BLKID_PARTITIONS_H - -#include "blkidP.h" -#include "blkid_parttypes.h" - -extern int blkid_partitions_get_flags(blkid_probe pr); - -extern blkid_parttable blkid_partlist_new_parttable(blkid_partlist ls, - const char *type, blkid_loff_t offset); - -extern blkid_partition blkid_partlist_add_partition(blkid_partlist ls, - blkid_parttable tab, - blkid_loff_t start, blkid_loff_t size); - -extern int blkid_partlist_set_partno(blkid_partlist ls, int partno); -extern int blkid_partlist_increment_partno(blkid_partlist ls); - -extern blkid_partition blkid_partlist_get_parent(blkid_partlist ls); - -extern int blkid_partitions_do_subprobe(blkid_probe pr, - blkid_partition parent, const struct blkid_idinfo *id); - -extern int blkid_partitions_need_typeonly(blkid_probe pr); -extern int blkid_is_nested_dimension(blkid_partition par, - blkid_loff_t start, blkid_loff_t size); - -extern int blkid_partition_set_name(blkid_partition par, - const unsigned char *name, size_t len); - -extern int blkid_partition_set_utf8name(blkid_partition par, - const unsigned char *name, size_t len, int enc); - -extern int blkid_partition_set_uuid(blkid_partition par, - const unsigned char *uuid); - -extern int blkid_partition_set_type(blkid_partition par, int type); - -extern int blkid_partition_set_type_string(blkid_partition par, - const unsigned char *type, size_t len); - -extern int blkid_partition_set_type_uuid(blkid_partition par, - const unsigned char *uuid); - -extern int blkid_partition_set_flags(blkid_partition par, unsigned long long flags); - -/* - * partition probers - */ -extern const struct blkid_idinfo aix_pt_idinfo; -extern const struct blkid_idinfo bsd_pt_idinfo; -extern const struct blkid_idinfo unixware_pt_idinfo; -extern const struct blkid_idinfo solaris_x86_pt_idinfo; -extern const struct blkid_idinfo sun_pt_idinfo; -extern const struct blkid_idinfo sgi_pt_idinfo; -extern const struct blkid_idinfo mac_pt_idinfo; -extern const struct blkid_idinfo dos_pt_idinfo; -extern const struct blkid_idinfo minix_pt_idinfo; -extern const struct blkid_idinfo gpt_pt_idinfo; -extern const struct blkid_idinfo ultrix_pt_idinfo; - -#endif /* BLKID_PARTITIONS_H */ diff --git a/shlibs/blkid/src/partitions/sgi.c b/shlibs/blkid/src/partitions/sgi.c deleted file mode 100644 index 945ead54..00000000 --- a/shlibs/blkid/src/partitions/sgi.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * sgi partition parsing code - * - * Copyright (C) 2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * - */ -#include -#include -#include -#include - -#include "partitions.h" - -#define SGI_MAXPARTITIONS 16 - -/* partition type */ -#define SGI_TYPE_VOLHDR 0x00 -#define SGI_TYPE_VOLULME 0x06 /* entire disk */ - -struct sgi_device_parameter { - unsigned char skew; - unsigned char gap1; - unsigned char gap2; - unsigned char sparecyl; - - uint16_t pcylcount; - uint16_t head_vol0; - uint16_t ntrks; /* tracks in cyl 0 or vol 0 */ - - unsigned char cmd_tag_queue_depth; - unsigned char unused0; - - uint16_t unused1; - uint16_t nsect; /* sectors/tracks in cyl 0 or vol 0 */ - uint16_t bytes; - uint16_t ilfact; - uint32_t flags; /* controller flags */ - uint32_t datarate; - uint32_t retries_on_error; - uint32_t ms_per_word; - uint16_t xylogics_gap1; - uint16_t xylogics_syncdelay; - uint16_t xylogics_readdelay; - uint16_t xylogics_gap2; - uint16_t xylogics_readgate; - uint16_t xylogics_writecont; -} __attribute__((packed)); - -struct sgi_disklabel { - uint32_t magic; /* magic number */ - uint16_t root_part_num; /* # root partition */ - uint16_t swap_part_num; /* # swap partition */ - unsigned char boot_file[16]; /* name of boot file */ - - struct sgi_device_parameter devparam; /* not used now */ - - struct sgi_volume { - unsigned char name[8]; /* name of volume */ - uint32_t block_num; /* logical block number */ - uint32_t num_bytes; /* how big, in bytes */ - } __attribute__((packed)) volume[15]; - - struct sgi_partition { - uint32_t num_blocks; /* size in logical blocks */ - uint32_t first_block; /* first logical block */ - uint32_t type; /* type of this partition */ - } __attribute__((packed)) partitions[SGI_MAXPARTITIONS]; - - /* checksum is the 32bit 2's complement sum of the disklabel */ - uint32_t csum; /* disk label checksum */ - uint32_t padding; /* padding */ -} __attribute__((packed)); - -static uint32_t count_checksum(struct sgi_disklabel *label) -{ - int i; - uint32_t *ptr = (uint32_t *) label; - uint32_t sum = 0; - - i = sizeof(*label) / sizeof(*ptr); - - while (i--) - sum += be32_to_cpu(ptr[i]); - - return sum; -} - - -static int probe_sgi_pt(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct sgi_disklabel *l; - struct sgi_partition *p; - blkid_parttable tab = NULL; - blkid_partlist ls; - int i; - - l = (struct sgi_disklabel *) blkid_probe_get_sector(pr, 0); - if (!l) - goto nothing; - - if (count_checksum(l)) { - DBG(DEBUG_LOWPROBE, printf( - "detected corrupted sgi disk label -- ignore\n")); - goto nothing; - } - - if (blkid_partitions_need_typeonly(pr)) - /* caller does not ask for details about partitions */ - return 0; - - ls = blkid_probe_get_partlist(pr); - if (!ls) - goto err; - - tab = blkid_partlist_new_parttable(ls, "sgi", 0); - if (!tab) - goto err; - - for(i = 0, p = &l->partitions[0]; i < SGI_MAXPARTITIONS; i++, p++) { - uint32_t size = be32_to_cpu(p->num_blocks); - uint32_t start = be32_to_cpu(p->first_block); - uint32_t type = be32_to_cpu(p->type); - blkid_partition par; - - if (size == 0 || type == SGI_TYPE_VOLULME || - type == SGI_TYPE_VOLHDR) { - blkid_partlist_increment_partno(ls); - continue; - } - par = blkid_partlist_add_partition(ls, tab, start, size); - if (!par) - goto err; - - blkid_partition_set_type(par, type); - } - - return 0; - -nothing: - return 1; -err: - return -1; -} - -const struct blkid_idinfo sgi_pt_idinfo = -{ - .name = "sgi", - .probefunc = probe_sgi_pt, - .magics = - { - { .magic = "\x0B\xE5\xA9\x41", .len = 4 }, - { NULL } - } -}; - diff --git a/shlibs/blkid/src/partitions/solaris_x86.c b/shlibs/blkid/src/partitions/solaris_x86.c deleted file mode 100644 index ce102bd8..00000000 --- a/shlibs/blkid/src/partitions/solaris_x86.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Solaris x86 partition parsing code - * - * Copyright (C) 2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include - -#include "partitions.h" - -/* - * Solaris-x86 is always within primary dos partition (nested PT table). The - * solaris-x86 vtoc allows to split the entire partition to "slices". The - * offset (start) of the slice is always relatively to the primary dos - * partition. - * - * Note that Solaris-SPARC uses entire disk with a different partitionning - * scheme. - */ - -/* some other implementation than Linux kernel assume 8 partitions only */ -#define SOLARIS_MAXPARTITIONS 16 - -/* disklabel (vtoc) location */ -#define SOLARIS_SECTOR 1 /* in 512-sectors */ -#define SOLARIS_OFFSET (SOLARIS_SECTOR << 9) /* in bytes */ -#define SOLARIS_MAGICOFFSET (SOLARIS_OFFSET + 12) /* v_sanity offset in bytes */ - -/* slice tags */ -#define SOLARIS_TAG_WHOLEDISK 5 - -struct solaris_slice { - uint16_t s_tag; /* ID tag of partition */ - uint16_t s_flag; /* permission flags */ - uint32_t s_start; /* start sector no of partition */ - uint32_t s_size; /* # of blocks in partition */ -} __attribute__((packed)); - -struct solaris_vtoc { - unsigned int v_bootinfo[3]; /* info needed by mboot (unsupported) */ - - uint32_t v_sanity; /* to verify vtoc sanity */ - uint32_t v_version; /* layout version */ - char v_volume[8]; /* volume name */ - uint16_t v_sectorsz; /* sector size in bytes */ - uint16_t v_nparts; /* number of partitions */ - unsigned int v_reserved[10]; /* free space */ - - struct solaris_slice v_slice[SOLARIS_MAXPARTITIONS]; /* slices */ - - unsigned int timestamp[SOLARIS_MAXPARTITIONS]; /* timestamp (unsupported) */ - char v_asciilabel[128]; /* for compatibility */ -} __attribute__((packed)); - -static int probe_solaris_pt(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct solaris_vtoc *l; /* disk label */ - struct solaris_slice *p; /* partitsion */ - blkid_parttable tab = NULL; - blkid_partition parent; - blkid_partlist ls; - int i; - uint16_t nparts; - - l = (struct solaris_vtoc *) blkid_probe_get_sector(pr, SOLARIS_SECTOR); - if (!l) - goto nothing; - - if (le32_to_cpu(l->v_version) != 1) { - DBG(DEBUG_LOWPROBE, printf( - "WARNING: unsupported solaris x86 version %d, ignore\n", - le32_to_cpu(l->v_version))); - goto nothing; - } - - if (blkid_partitions_need_typeonly(pr)) - /* caller does not ask for details about partitions */ - return 0; - - ls = blkid_probe_get_partlist(pr); - if (!ls) - goto err; - - parent = blkid_partlist_get_parent(ls); - - tab = blkid_partlist_new_parttable(ls, "solaris", SOLARIS_OFFSET); - if (!tab) - goto err; - - nparts = le16_to_cpu(l->v_nparts); - if (nparts > SOLARIS_MAXPARTITIONS) - nparts = SOLARIS_MAXPARTITIONS; - - for (i = 1, p = &l->v_slice[0]; i < nparts; i++, p++) { - - uint32_t start = le32_to_cpu(p->s_start); - uint32_t size = le32_to_cpu(p->s_size); - blkid_partition par; - - if (size == 0 || le16_to_cpu(p->s_tag) == SOLARIS_TAG_WHOLEDISK) - continue; - - if (parent) - /* Solaris slices are relative to the parent (primary - * DOS partition) */ - start += blkid_partition_get_start(parent); - - if (parent && !blkid_is_nested_dimension(parent, start, size)) { - DBG(DEBUG_LOWPROBE, printf( - "WARNING: solaris partition (%d) overflow " - "detected, ignore\n", i)); - continue; - } - - par = blkid_partlist_add_partition(ls, tab, start, size); - if (!par) - goto err; - - blkid_partition_set_type(par, le16_to_cpu(p->s_tag)); - blkid_partition_set_flags(par, le16_to_cpu(p->s_flag)); - } - - return 0; - -nothing: - return 1; -err: - return -1; -} - -const struct blkid_idinfo solaris_x86_pt_idinfo = -{ - .name = "solaris", - .probefunc = probe_solaris_pt, - .magics = - { - { - .magic = "\xEE\xDE\x0D\x60", /* little-endian magic string */ - .len = 4, /* v_sanity size in bytes */ - .sboff = SOLARIS_MAGICOFFSET /* offset of v_sanity */ - }, - { NULL } - } -}; - diff --git a/shlibs/blkid/src/partitions/sun.c b/shlibs/blkid/src/partitions/sun.c deleted file mode 100644 index dffab24c..00000000 --- a/shlibs/blkid/src/partitions/sun.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * sun (solaris-sparc) partition parsing code - * - * Copyright (C) 2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include - -#include "partitions.h" - -/* Supported VTOC setting */ -#define SUN_VTOC_SANITY 0x600DDEEE /* magic number */ -#define SUN_VTOC_VERSION 1 - -#define SUN_MAXPARTITIONS 8 - -/* Partition IDs */ -#define SUN_TAG_WHOLEDISK 0x05 - -struct sun_disklabel { - unsigned char info[128]; /* Informative text string */ - - struct sun_vtoc { - uint32_t version; /* version */ - char volume[8]; /* volume name */ - uint16_t nparts; /* num of partitions */ - - struct sun_info { /* partition information */ - uint16_t id; /* tag */ - uint16_t flags; - } __attribute__ ((packed)) infos[8]; - - uint16_t padding; /* padding */ - uint32_t bootinfo[3]; /* info needed by mboot */ - uint32_t sanity; /* magic number */ - uint32_t reserved[10]; /* padding */ - uint32_t timestamp[8]; /* partition timestamp */ - } __attribute__ ((packed)) vtoc; - - uint32_t write_reinstruct; /* sectors to skip, writes */ - uint32_t read_reinstruct; /* sectors to skip, reads */ - unsigned char spare[148]; /* padding */ - uint16_t rspeed; /* disk rotational speed */ - uint16_t pcylcount; /* physical cylinder count */ - uint16_t sparecyl; /* extra sects per cylinder */ - uint16_t obs1; - uint16_t obs2; - uint16_t ilfact; /* interleave factor */ - uint16_t ncyl; /* data cylinder count */ - uint16_t nacyl; /* alt. cylinder count */ - uint16_t ntrks; /* tracks per cylinder <---- */ - uint16_t nsect; /* sectors per track <---- */ - uint16_t obs3; - uint16_t obs4; - - struct sun_partition { /* partitions */ - uint32_t start_cylinder; - uint32_t num_sectors; - } __attribute__ ((packed)) partitions[8]; - - uint16_t magic; /* magic number */ - uint16_t csum; /* label xor'd checksum */ -} __attribute__ ((packed)); - - -uint16_t count_checksum(struct sun_disklabel *label) -{ - uint16_t *ptr = ((uint16_t *) (label + 1)) - 1; - uint16_t sum; - - for (sum = 0; ptr >= ((uint16_t *) label);) - sum ^= *ptr--; - - return sum; -} - -static int probe_sun_pt(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct sun_disklabel *l; - struct sun_partition *p; - blkid_parttable tab = NULL; - blkid_partlist ls; - uint16_t nparts; - blkid_loff_t spc; - int i, use_vtoc; - - l = (struct sun_disklabel *) blkid_probe_get_sector(pr, 0); - if (!l) - goto nothing; - - if (count_checksum(l)) { - DBG(DEBUG_LOWPROBE, printf( - "detected corrupted sun disk label -- ignore\n")); - goto nothing; - } - - if (blkid_partitions_need_typeonly(pr)) - /* caller does not ask for details about partitions */ - return 0; - - ls = blkid_probe_get_partlist(pr); - if (!ls) - goto err; - - tab = blkid_partlist_new_parttable(ls, "sun", 0); - if (!tab) - goto err; - - /* sectors per cylinder (partition offset is in cylinders...) */ - spc = be16_to_cpu(l->ntrks) * be16_to_cpu(l->nsect); - - DBG(DEBUG_LOWPROBE, - printf("Sun VTOC sanity=%u version=%u nparts=%u\n", - be32_to_cpu(l->vtoc.sanity), - be32_to_cpu(l->vtoc.version), - be16_to_cpu(l->vtoc.nparts))); - - /* Check to see if we can use the VTOC table */ - use_vtoc = ((be32_to_cpu(l->vtoc.sanity) == SUN_VTOC_SANITY) && - (be32_to_cpu(l->vtoc.version) == SUN_VTOC_VERSION) && - (be16_to_cpu(l->vtoc.nparts) <= SUN_MAXPARTITIONS)); - - /* Use 8 partition entries if not specified in validated VTOC */ - nparts = use_vtoc ? be16_to_cpu(l->vtoc.nparts) : SUN_MAXPARTITIONS; - - /* - * So that old Linux-Sun partitions continue to work, - * alow the VTOC to be used under the additional condition ... - */ - use_vtoc = use_vtoc || !(l->vtoc.sanity || l->vtoc.version || l->vtoc.nparts); - - for (i = 0, p = l->partitions; i < nparts; i++, p++) { - - blkid_loff_t start, size; - uint16_t type = 0, flags = 0; - blkid_partition par; - - start = be32_to_cpu(p->start_cylinder) * spc; - size = be32_to_cpu(p->num_sectors); - if (use_vtoc) { - type = be16_to_cpu(l->vtoc.infos[i].id); - flags = be16_to_cpu(l->vtoc.infos[i].flags); - } - - if (type == SUN_TAG_WHOLEDISK || !size) { - blkid_partlist_increment_partno(ls); - continue; - } - par = blkid_partlist_add_partition(ls, tab, start, size); - if (!par) - goto err; - - if (type) - blkid_partition_set_type(par, type); - if (flags) - blkid_partition_set_flags(par, flags); - } - return 0; - -nothing: - return 1; -err: - return -1; -} - - -const struct blkid_idinfo sun_pt_idinfo = -{ - .name = "sun", - .probefunc = probe_sun_pt, - .magics = - { - { - .magic = "\xDA\xBE", /* big-endian magic string */ - .len = 2, - .sboff = offsetof(struct sun_disklabel, magic) - }, - { NULL } - } -}; - diff --git a/shlibs/blkid/src/partitions/ultrix.c b/shlibs/blkid/src/partitions/ultrix.c deleted file mode 100644 index cc848d0a..00000000 --- a/shlibs/blkid/src/partitions/ultrix.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * uktrix partition parsing code - * - * Copyright (C) 2010 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * - */ -#include -#include -#include -#include - -#include "partitions.h" - -#define ULTRIX_MAXPARTITIONS 8 -#define ULTRIX_MAGIC 0x032957 - -/* sector with partition table */ -#define ULTRIX_SECTOR ((16384 - sizeof(struct ultrix_disklabel)) >> 9) -/* position of partition table within ULTRIX_SECTOR */ -#define ULTRIX_OFFSET (512 - sizeof(struct ultrix_disklabel)) - -struct ultrix_disklabel { - int32_t pt_magic; /* magic no. indicating part. info exits */ - int32_t pt_valid; /* set by driver if pt is current */ - struct pt_info { - int32_t pi_nblocks; /* no. of sectors */ - uint32_t pi_blkoff; /* block offset for start */ - } pt_part[ULTRIX_MAXPARTITIONS]; -} __attribute__((packed)); - - -static int probe_ultrix_pt(blkid_probe pr, const struct blkid_idmag *mag) -{ - unsigned char *data; - struct ultrix_disklabel *l; - blkid_parttable tab = NULL; - blkid_partlist ls; - int i; - - data = blkid_probe_get_sector(pr, ULTRIX_SECTOR); - if (!data) - goto nothing; - - l = (struct ultrix_disklabel *) (data + ULTRIX_OFFSET); - - if (l->pt_magic != ULTRIX_MAGIC || l->pt_valid != 1) - goto nothing; - - if (blkid_partitions_need_typeonly(pr)) - /* caller does not ask for details about partitions */ - return 0; - - ls = blkid_probe_get_partlist(pr); - if (!ls) - goto err; - - tab = blkid_partlist_new_parttable(ls, "ultrix", 0); - if (!tab) - goto err; - - for (i = 0; i < ULTRIX_MAXPARTITIONS; i++) { - if (!l->pt_part[i].pi_nblocks) - blkid_partlist_increment_partno(ls); - else { - if (!blkid_partlist_add_partition(ls, tab, - l->pt_part[i].pi_blkoff, - l->pt_part[i].pi_nblocks)) - goto err; - } - } - - return 0; -nothing: - return 1; -err: - return -1; -} - -const struct blkid_idinfo ultrix_pt_idinfo = -{ - .name = "ultrix", - .probefunc = probe_ultrix_pt, - .magics = BLKID_NONE_MAGIC -}; - diff --git a/shlibs/blkid/src/partitions/unixware.c b/shlibs/blkid/src/partitions/unixware.c deleted file mode 100644 index ac11a46d..00000000 --- a/shlibs/blkid/src/partitions/unixware.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * unixware partition parsing code - * - * Copyright (C) 2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * - * - * The intersting information about unixware PT: - * - Linux kernel / partx - * - vtoc(7) SCO UNIX command man page - * - evms source code (http://evms.sourceforge.net/) - * - vxtools source code (http://martin.hinner.info/fs/vxfs/) - */ -#include -#include -#include -#include - -#include "partitions.h" - -/* disklabel location */ -#define UNIXWARE_SECTOR 29 -#define UNIXWARE_OFFSET (UNIXWARE_SECTOR << 9) /* offset in bytes */ -#define UNIXWARE_KBOFFSET (UNIXWARE_OFFSET >> 10) /* offset in 1024-blocks */ - -/* disklabel->d_magic offset within the last 1024 block */ -#define UNIXWARE_MAGICOFFSET (UNIXWARE_OFFSET - UNIXWARE_KBOFFSET + 4) - -#define UNIXWARE_VTOCMAGIC 0x600DDEEEUL -#define UNIXWARE_MAXPARTITIONS 16 - -/* unixware_partition->s_label flags */ -#define UNIXWARE_TAG_UNUSED 0x0000 /* unused partition */ -#define UNIXWARE_TAG_BOOT 0x0001 /* boot fs */ -#define UNIXWARE_TAG_ROOT 0x0002 /* root fs */ -#define UNIXWARE_TAG_SWAP 0x0003 /* swap fs */ -#define UNIXWARE_TAG_USER 0x0004 /* user fs */ -#define UNIXWARE_TAG_ENTIRE_DISK 0x0005 /* whole disk */ -#define UNIXWARE_TAG_ALT_S 0x0006 /* alternate sector space */ -#define UNIXWARE_TAG_OTHER 0x0007 /* non unix */ -#define UNIXWARE_TAG_ALT_T 0x0008 /* alternate track space */ -#define UNIXWARE_TAG_STAND 0x0009 /* stand partition */ -#define UNIXWARE_TAG_VAR 0x000a /* var partition */ -#define UNIXWARE_TAG_HOME 0x000b /* home partition */ -#define UNIXWARE_TAG_DUMP 0x000c /* dump partition */ -#define UNIXWARE_TAG_ALT_ST 0x000d /* alternate sector track */ -#define UNIXWARE_TAG_VM_PUBLIC 0x000e /* volume mgt public partition */ -#define UNIXWARE_TAG_VM_PRIVATE 0x000f /* volume mgt private partition */ - - -/* unixware_partition->s_flags flags */ -#define UNIXWARE_FLAG_VALID 0x0200 - -struct unixware_partition { - uint16_t s_label; /* partition label (tag) */ - uint16_t s_flags; /* permission flags */ - uint32_t start_sect; /* starting sector */ - uint32_t nr_sects; /* number of sectors */ -} __attribute__((packed)); - -struct unixware_disklabel { - uint32_t d_type; /* drive type */ - uint32_t d_magic; /* the magic number */ - uint32_t d_version; /* version number */ - char d_serial[12]; /* serial number of the device */ - uint32_t d_ncylinders; /* # of data cylinders per device */ - uint32_t d_ntracks; /* # of tracks per cylinder */ - uint32_t d_nsectors; /* # of data sectors per track */ - uint32_t d_secsize; /* # of bytes per sector */ - uint32_t d_part_start; /* # of first sector of this partition */ - uint32_t d_unknown1[12]; /* ? */ - uint32_t d_alt_tbl; /* byte offset of alternate table */ - uint32_t d_alt_len; /* byte length of alternate table */ - uint32_t d_phys_cyl; /* # of physical cylinders per device */ - uint32_t d_phys_trk; /* # of physical tracks per cylinder */ - uint32_t d_phys_sec; /* # of physical sectors per track */ - uint32_t d_phys_bytes; /* # of physical bytes per sector */ - uint32_t d_unknown2; /* ? */ - uint32_t d_unknown3; /* ? */ - uint32_t d_pad[8]; /* pad */ - - struct unixware_vtoc { - uint32_t v_magic; /* the magic number */ - uint32_t v_version; /* version number */ - char v_name[8]; /* volume name */ - uint16_t v_nslices; /* # of partitions */ - uint16_t v_unknown1; /* ? */ - uint32_t v_reserved[10]; /* reserved */ - - struct unixware_partition - v_slice[UNIXWARE_MAXPARTITIONS]; /* partition */ - } __attribute__((packed)) vtoc; -}; - -static int probe_unixware_pt(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct unixware_disklabel *l; - struct unixware_partition *p; - blkid_parttable tab = NULL; - blkid_partition parent; - blkid_partlist ls; - int i; - - l = (struct unixware_disklabel *) - blkid_probe_get_sector(pr, UNIXWARE_SECTOR); - if (!l) - goto nothing; - - if (le32_to_cpu(l->vtoc.v_magic) != UNIXWARE_VTOCMAGIC) - goto nothing; - - if (blkid_partitions_need_typeonly(pr)) - /* caller does not ask for details about partitions */ - return 0; - - ls = blkid_probe_get_partlist(pr); - if (!ls) - goto err; - - parent = blkid_partlist_get_parent(ls); - - tab = blkid_partlist_new_parttable(ls, "unixware", UNIXWARE_OFFSET); - if (!tab) - goto err; - - /* Skip the first partition that describe whole disk - */ - for (i = 1, p = &l->vtoc.v_slice[1]; - i < UNIXWARE_MAXPARTITIONS; i++, p++) { - - uint32_t start, size; - uint16_t tag, flg; - blkid_partition par; - - tag = le16_to_cpu(p->s_label); - flg = le16_to_cpu(p->s_flags); - - if (tag == UNIXWARE_TAG_UNUSED || - tag == UNIXWARE_TAG_ENTIRE_DISK || - flg != UNIXWARE_FLAG_VALID) - continue; - - start = le32_to_cpu(p->start_sect); - size = le32_to_cpu(p->nr_sects); - - if (parent && !blkid_is_nested_dimension(parent, start, size)) { - DBG(DEBUG_LOWPROBE, printf( - "WARNING: unixware partition (%d) overflow " - "detected, ignore\n", i)); - continue; - } - - par = blkid_partlist_add_partition(ls, tab, start, size); - if (!par) - goto err; - - blkid_partition_set_type(par, tag); - blkid_partition_set_flags(par, flg); - } - - return 0; - -nothing: - return 1; -err: - return -1; -} - - -/* - * The unixware partition table is within primary DOS partition. The PT is - * located on 29 sector, PT magic string is d_magic member of 'struct - * unixware_disklabel'. - */ -const struct blkid_idinfo unixware_pt_idinfo = -{ - .name = "unixware", - .probefunc = probe_unixware_pt, - .minsz = 1024 * 1440 + 1, /* ignore floppies */ - .magics = - { - { - .magic = "\x0D\x60\xE5\xCA", /* little-endian magic string */ - .len = 4, /* d_magic size in bytes */ - .kboff = UNIXWARE_KBOFFSET, - .sboff = UNIXWARE_MAGICOFFSET - }, - { NULL } - } -}; - diff --git a/shlibs/blkid/src/probe.c b/shlibs/blkid/src/probe.c deleted file mode 100644 index 85db814f..00000000 --- a/shlibs/blkid/src/probe.c +++ /dev/null @@ -1,1509 +0,0 @@ -/* - * Low-level libblkid probing API - * - * Copyright (C) 2008-2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -/** - * SECTION: lowprobe - * @title: Low-level probing - * @short_description: low-level prober initialization - * - * The low-level probing routines always and directly read information from - * the selected (see blkid_probe_set_device()) device. - * - * The probing routines are grouped together into separate chains. Currently, - * the library provides superblocks, partitions and topology chains. - * - * The probing routines is possible to filter (enable/disable) by type (e.g. - * fstype "vfat" or partype "gpt") or by usage flags (e.g. BLKID_USAGE_RAID). - * These filters are per-chain. Note that always when you touch the chain - * filter the current probing position is reseted and probing starts from - * scratch. It means that the chain filter should not be modified during - * probing, for example in loop where you call blkid_do_probe(). - * - * For more details see the chain specific documentation. - * - * The low-level API provides two ways how access to probing results. - * - * 1. The NAME=value (tag) interface. This interface is older and returns all data - * as strings. This interface is generic for all chains. - * - * 2. The binary interfaces. These interfaces return data in the native formats. - * The interface is always specific to the probing chain. - * - * Note that the previous probing result (binary or NAME=value) is always - * zeroized when a chain probing function is called. For example - * - * - * - * blkid_probe_enable_partitions(pr, TRUE); - * blkid_probe_enable_superblocks(pr, FALSE); - * - * blkid_do_safeprobe(pr); - * - * - * - * overwrites the previous probing result for the partitions chain, the superblocks - * result is not modified. - */ - -/** - * SECTION: lowprobe-tags - * @title: Low-level tags - * @short_description: generic NAME=value interface. - * - * The probing routines inside the chain are mutually exclusive by default -- - * only few probing routines are marked as "tolerant". The "tolerant" probing - * routines are used for filesystem which can share the same device with any - * other filesystem. The blkid_do_safeprobe() checks for the "tolerant" flag. - * - * The SUPERBLOCKS chain is enabled by default. The all others chains is - * necessary to enable by blkid_probe_enable_'CHAINNAME'(). See chains specific - * documentation. - * - * The blkid_do_probe() function returns a result from only one probing - * routine, and the next call from the next probing routine. It means you need - * to call the function in loop, for example: - * - * - * - * while((blkid_do_probe(pr) == 0) - * ... use result ... - * - * - * - * The blkid_do_safeprobe() is the same as blkid_do_probe(), but returns only - * first probing result for every enabled chain. This function checks for - * ambivalent results (e.g. more "intolerant" filesystems superblocks on the - * device). - * - * The probing result is set of NAME=value pairs (the NAME is always unique). - */ - -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_LINUX_CDROM_H -#include -#endif -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#include -#include -#include - -#ifdef HAVE_LIBUUID -# include -#endif - -#include "blkidP.h" - -/* chains */ -extern const struct blkid_chaindrv superblocks_drv; -extern const struct blkid_chaindrv topology_drv; -extern const struct blkid_chaindrv partitions_drv; - -/* - * All supported chains - */ -static const struct blkid_chaindrv *chains_drvs[] = { - [BLKID_CHAIN_SUBLKS] = &superblocks_drv, - [BLKID_CHAIN_TOPLGY] = &topology_drv, - [BLKID_CHAIN_PARTS] = &partitions_drv -}; - -static void blkid_probe_reset_vals(blkid_probe pr); -static void blkid_probe_reset_buffer(blkid_probe pr); - -/** - * blkid_new_probe: - * - * Returns: a pointer to the newly allocated probe struct. - */ -blkid_probe blkid_new_probe(void) -{ - int i; - blkid_probe pr; - - blkid_init_debug(0); - pr = calloc(1, sizeof(struct blkid_struct_probe)); - if (!pr) - return NULL; - - DBG(DEBUG_LOWPROBE, printf("allocate a new probe %p\n", pr)); - - /* initialize chains */ - for (i = 0; i < BLKID_NCHAINS; i++) { - pr->chains[i].driver = chains_drvs[i]; - pr->chains[i].flags = chains_drvs[i]->dflt_flags; - pr->chains[i].enabled = chains_drvs[i]->dflt_enabled; - } - INIT_LIST_HEAD(&pr->buffers); - return pr; -} - -/* - * Clone @parent, the new clone shares all, but except: - * - * - probing result - * - bufferes if another device (or offset) is set to the prober - */ -blkid_probe blkid_clone_probe(blkid_probe parent) -{ - blkid_probe pr; - - if (!parent) - return NULL; - - DBG(DEBUG_LOWPROBE, printf("allocate a probe clone\n")); - - pr = blkid_new_probe(); - if (!pr) - return NULL; - - pr->fd = parent->fd; - pr->off = parent->off; - pr->size = parent->size; - pr->devno = parent->devno; - pr->disk_devno = parent->disk_devno; - pr->blkssz = parent->blkssz; - pr->flags = parent->flags; - pr->parent = parent; - - return pr; -} - - - -/** - * blkid_new_probe_from_filename: - * @filename: device or regular file - * - * This function is same as call open(filename), blkid_new_probe() and - * blkid_probe_set_device(pr, fd, 0, 0). - * - * The @filename is closed by blkid_free_probe() or by the - * blkid_probe_set_device() call. - * - * Returns: a pointer to the newly allocated probe struct or NULL in case of - * error. - */ -blkid_probe blkid_new_probe_from_filename(const char *filename) -{ - int fd = -1; - blkid_probe pr = NULL; - - if (!filename) - return NULL; - - fd = open(filename, O_RDONLY); - if (fd < 0) - return NULL; - - pr = blkid_new_probe(); - if (!pr) - goto err; - - if (blkid_probe_set_device(pr, fd, 0, 0)) - goto err; - - pr->flags |= BLKID_FL_PRIVATE_FD; - return pr; -err: - if (fd >= 0) - close(fd); - blkid_free_probe(pr); - return NULL; -} - -/** - * blkid_free_probe: - * @pr: probe - * - * Deallocates the probe struct, buffers and all allocated - * data that are associated with this probing control struct. - */ -void blkid_free_probe(blkid_probe pr) -{ - int i; - - if (!pr) - return; - - for (i = 0; i < BLKID_NCHAINS; i++) { - struct blkid_chain *ch = &pr->chains[i]; - - if (ch->driver->free_data) - ch->driver->free_data(pr, ch->data); - free(ch->fltr); - } - - if ((pr->flags & BLKID_FL_PRIVATE_FD) && pr->fd >= 0) - close(pr->fd); - blkid_probe_reset_buffer(pr); - blkid_free_probe(pr->disk_probe); - - DBG(DEBUG_LOWPROBE, printf("free probe %p\n", pr)); - free(pr); -} - - -/* - * Removes chain values from probing result. - */ -void blkid_probe_chain_reset_vals(blkid_probe pr, struct blkid_chain *chn) -{ - int nvals = pr->nvals; - int i, x; - - for (x = 0, i = 0; i < pr->nvals; i++) { - struct blkid_prval *v = &pr->vals[i]; - - if (v->chain != chn && x == i) { - x++; - continue; - } - if (v->chain == chn) { - --nvals; - continue; - } - memcpy(&pr->vals[x++], v, sizeof(struct blkid_prval)); - } - pr->nvals = nvals; -} - -static void blkid_probe_chain_reset_position(struct blkid_chain *chn) -{ - if (chn) - chn->idx = -1; -} - -/* - * Copies chain values from probing result to @vals, the max size of @vals is - * @nvals and returns real number of values. - */ -int blkid_probe_chain_copy_vals(blkid_probe pr, struct blkid_chain *chn, - struct blkid_prval *vals, int nvals) -{ - int i, x; - - for (x = 0, i = 0; i < pr->nvals && x < nvals; i++) { - struct blkid_prval *v = &pr->vals[i]; - - if (v->chain != chn) - continue; - memcpy(&vals[x++], v, sizeof(struct blkid_prval)); - } - return x; -} - -/* - * Appends values from @vals to the probing result - */ -void blkid_probe_append_vals(blkid_probe pr, struct blkid_prval *vals, int nvals) -{ - int i = 0; - - while (i < nvals && pr->nvals < BLKID_NVALS) { - memcpy(&pr->vals[pr->nvals++], &vals[i++], - sizeof(struct blkid_prval)); - } -} - -static void blkid_probe_reset_vals(blkid_probe pr) -{ - memset(pr->vals, 0, sizeof(pr->vals)); - pr->nvals = 0; -} - -struct blkid_chain *blkid_probe_get_chain(blkid_probe pr) -{ - return pr->cur_chain; -} - -void *blkid_probe_get_binary_data(blkid_probe pr, struct blkid_chain *chn) -{ - int rc, org_prob_flags; - struct blkid_chain *org_chn; - - if (!pr || !chn) - return NULL; - - /* save the current setting -- the binary API has to be completely - * independent on the current probing status - */ - org_chn = pr->cur_chain; - org_prob_flags = pr->prob_flags; - - pr->cur_chain = chn; - pr->prob_flags = 0; - chn->binary = TRUE; - blkid_probe_chain_reset_position(chn); - - rc = chn->driver->probe(pr, chn); - - chn->binary = FALSE; - blkid_probe_chain_reset_position(chn); - - /* restore the original setting - */ - pr->cur_chain = org_chn; - pr->prob_flags = org_prob_flags; - - if (rc != 0) - return NULL; - - DBG(DEBUG_LOWPROBE, - printf("returning %s binary data\n", chn->driver->name)); - return chn->data; -} - - -/** - * blkid_reset_probe: - * @pr: probe - * - * Zeroize probing results and resets the current probing (this has impact to - * blkid_do_probe() only). This function does not touch probing filters and - * keeps assigned device. - */ -void blkid_reset_probe(blkid_probe pr) -{ - int i; - - if (!pr) - return; - - blkid_probe_reset_vals(pr); - - pr->cur_chain = NULL; - - for (i = 0; i < BLKID_NCHAINS; i++) - blkid_probe_chain_reset_position(&pr->chains[i]); -} - -/*** -static int blkid_probe_dump_filter(blkid_probe pr, int chain) -{ - struct blkid_chain *chn; - int i; - - if (!pr || chain < 0 || chain >= BLKID_NCHAINS) - return -1; - - chn = &pr->chains[chain]; - - if (!chn->fltr) - return -1; - - for (i = 0; i < chn->driver->nidinfos; i++) { - const struct blkid_idinfo *id = chn->driver->idinfos[i]; - - DBG(DEBUG_LOWPROBE, printf("%d: %s: %s\n", - i, - id->name, - blkid_bmp_get_item(chn->fltr, i) - ? "disabled" : "enabled <--")); - } - return 0; -} -***/ - -/* - * Returns properly initialized chain filter - */ -unsigned long *blkid_probe_get_filter(blkid_probe pr, int chain, int create) -{ - struct blkid_chain *chn; - - if (!pr || chain < 0 || chain >= BLKID_NCHAINS) - return NULL; - - chn = &pr->chains[chain]; - - /* always when you touch the chain filter all indexes are reseted and - * probing starts from scratch - */ - blkid_probe_chain_reset_position(chn); - pr->cur_chain = NULL; - - if (!chn->driver->has_fltr || (!chn->fltr && !create)) - return NULL; - - if (!chn->fltr) - chn->fltr = calloc(1, blkid_bmp_nbytes(chn->driver->nidinfos)); - else - memset(chn->fltr, 0, blkid_bmp_nbytes(chn->driver->nidinfos)); - - /* blkid_probe_dump_filter(pr, chain); */ - return chn->fltr; -} - -/* - * Generic private functions for filter setting - */ -int __blkid_probe_invert_filter(blkid_probe pr, int chain) -{ - int i; - struct blkid_chain *chn; - - chn = &pr->chains[chain]; - - if (!chn->driver->has_fltr || !chn->fltr) - return -1; - - for (i = 0; i < blkid_bmp_nwords(chn->driver->nidinfos); i++) - chn->fltr[i] = ~chn->fltr[i]; - - DBG(DEBUG_LOWPROBE, printf("probing filter inverted\n")); - /* blkid_probe_dump_filter(pr, chain); */ - return 0; -} - -int __blkid_probe_reset_filter(blkid_probe pr, int chain) -{ - return blkid_probe_get_filter(pr, chain, FALSE) ? 0 : -1; -} - -int __blkid_probe_filter_types(blkid_probe pr, int chain, int flag, char *names[]) -{ - unsigned long *fltr; - struct blkid_chain *chn; - int i; - - fltr = blkid_probe_get_filter(pr, chain, TRUE); - if (!fltr) - return -1; - - chn = &pr->chains[chain]; - - for (i = 0; i < chn->driver->nidinfos; i++) { - int has = 0; - const struct blkid_idinfo *id = chn->driver->idinfos[i]; - char **n; - - for (n = names; *n; n++) { - if (!strcmp(id->name, *n)) { - has = 1; - break; - } - } - if (flag & BLKID_FLTR_ONLYIN) { - if (!has) - blkid_bmp_set_item(fltr, i); - } else if (flag & BLKID_FLTR_NOTIN) { - if (has) - blkid_bmp_set_item(fltr, i); - } - } - - DBG(DEBUG_LOWPROBE, - printf("%s: a new probing type-filter initialized\n", - chn->driver->name)); - /* blkid_probe_dump_filter(pr, chain); */ - return 0; -} - -unsigned char *blkid_probe_get_buffer(blkid_probe pr, - blkid_loff_t off, blkid_loff_t len) -{ - struct list_head *p; - struct blkid_bufinfo *bf = NULL; - - if (pr->size <= 0) - return NULL; - - if (pr->parent && - pr->parent->devno == pr->devno && - pr->parent->off <= pr->off && - pr->parent->off + pr->parent->size >= pr->off + pr->size) { - /* - * This is a cloned prober and points to the same area as - * parent. Let's use parent's buffers. - * - * Note that pr->off (and pr->parent->off) is always from the - * beginig of the device. - */ - return blkid_probe_get_buffer(pr->parent, - pr->off + off - pr->parent->off, len); - } - - list_for_each(p, &pr->buffers) { - struct blkid_bufinfo *x = - list_entry(p, struct blkid_bufinfo, bufs); - - if (x->off <= off && off + len <= x->off + x->len) { - DBG(DEBUG_LOWPROBE, - printf("\treuse buffer: off=%jd len=%jd pr=%p\n", - x->off, x->len, pr)); - bf = x; - break; - } - } - if (!bf) { - ssize_t ret; - - if (blkid_llseek(pr->fd, pr->off + off, SEEK_SET) < 0) - return NULL; - - /* allocate info and space for data by why call */ - bf = calloc(1, sizeof(struct blkid_bufinfo) + len); - if (!bf) - return NULL; - - bf->data = ((unsigned char *) bf) + sizeof(struct blkid_bufinfo); - bf->len = len; - bf->off = off; - INIT_LIST_HEAD(&bf->bufs); - - DBG(DEBUG_LOWPROBE, - printf("\tbuffer read: off=%jd len=%jd pr=%p\n", - off, len, pr)); - - ret = read(pr->fd, bf->data, len); - if (ret != (ssize_t) len) { - free(bf); - return NULL; - } - list_add_tail(&bf->bufs, &pr->buffers); - } - - return off ? bf->data + (off - bf->off) : bf->data; -} - - -static void blkid_probe_reset_buffer(blkid_probe pr) -{ - uint64_t read_ct = 0, len_ct = 0; - - if (!pr || list_empty(&pr->buffers)) - return; - - DBG(DEBUG_LOWPROBE, printf("reseting probing buffers pr=%p\n", pr)); - - while (!list_empty(&pr->buffers)) { - struct blkid_bufinfo *bf = list_entry(pr->buffers.next, - struct blkid_bufinfo, bufs); - read_ct++; - len_ct += bf->len; - list_del(&bf->bufs); - free(bf); - } - - DBG(DEBUG_LOWPROBE, - printf("buffers summary: %"PRIu64" bytes " - "by %"PRIu64" read() call(s)\n", - len_ct, read_ct)); - - INIT_LIST_HEAD(&pr->buffers); -} - -/* - * Small devices need a special care. - */ -int blkid_probe_is_tiny(blkid_probe pr) -{ - return pr && (pr->flags & BLKID_FL_TINY_DEV); -} - -/* - * CDROMs may fail when probed for RAID (last sector problem) - */ -int blkid_probe_is_cdrom(blkid_probe pr) -{ - return pr && (pr->flags & BLKID_FL_CDROM_DEV); -} - -/** - * blkid_probe_set_device: - * @pr: probe - * @fd: device file descriptor - * @off: begin of probing area - * @size: size of probing area (zero means whole device/file) - * - * Assigns the device to probe control struct, resets internal buffers and - * resets the current probing. - * - * Returns: -1 in case of failure, or 0 on success. - */ -int blkid_probe_set_device(blkid_probe pr, int fd, - blkid_loff_t off, blkid_loff_t size) -{ - struct stat sb; - - if (!pr) - return -1; - - blkid_reset_probe(pr); - blkid_probe_reset_buffer(pr); - - if ((pr->flags & BLKID_FL_PRIVATE_FD) && pr->fd >= 0) - close(pr->fd); - - pr->flags &= ~BLKID_FL_PRIVATE_FD; - pr->flags &= ~BLKID_FL_TINY_DEV; - pr->flags &= ~BLKID_FL_CDROM_DEV; - pr->prob_flags = 0; - pr->fd = fd; - pr->off = off; - pr->size = 0; - pr->devno = 0; - pr->disk_devno = 0; - pr->mode = 0; - pr->blkssz = 0; - pr->wipe_off = 0; - pr->wipe_size = 0; - pr->wipe_chain = NULL; - -#if defined(POSIX_FADV_RANDOM) && defined(HAVE_POSIX_FADVISE) - /* Disable read-ahead */ - posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM); -#endif - if (fstat(fd, &sb)) - goto err; - - if (!S_ISBLK(sb.st_mode) && !S_ISCHR(sb.st_mode) && !S_ISREG(sb.st_mode)) - goto err; - - pr->mode = sb.st_mode; - if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) - pr->devno = sb.st_rdev; - - if (size) - pr->size = size; - else { - if (S_ISBLK(sb.st_mode)) { - if (blkdev_get_size(fd, (unsigned long long *) &pr->size)) { - DBG(DEBUG_LOWPROBE, printf( - "failed to get device size\n")); - goto err; - } - } else if (S_ISCHR(sb.st_mode)) - pr->size = 1; /* UBI devices are char... */ - else if (S_ISREG(sb.st_mode)) - pr->size = sb.st_size; /* regular file */ - - if (pr->off > pr->size) - goto err; - - /* The probing area cannot be larger than whole device, pr->off - * is offset within the device */ - pr->size -= pr->off; - } - - if (pr->size <= 1440 * 1024 && !S_ISCHR(sb.st_mode)) - pr->flags |= BLKID_FL_TINY_DEV; - -#ifdef CDROM_GET_CAPABILITY - if (S_ISBLK(sb.st_mode) && ioctl(fd, CDROM_GET_CAPABILITY, NULL) >= 0) - pr->flags |= BLKID_FL_CDROM_DEV; -#endif - - DBG(DEBUG_LOWPROBE, printf("ready for low-probing, offset=%jd, size=%jd\n", - pr->off, pr->size)); - DBG(DEBUG_LOWPROBE, printf("whole-disk: %s, regfile: %s\n", - blkid_probe_is_wholedisk(pr) ?"YES" : "NO", - S_ISREG(pr->mode) ? "YES" : "NO")); - - return 0; -err: - DBG(DEBUG_LOWPROBE, - printf("failed to prepare a device for low-probing\n")); - return -1; - -} - -int blkid_probe_get_dimension(blkid_probe pr, - blkid_loff_t *off, blkid_loff_t *size) -{ - if (!pr) - return -1; - - *off = pr->off; - *size = pr->size; - return 0; -} - -int blkid_probe_set_dimension(blkid_probe pr, - blkid_loff_t off, blkid_loff_t size) -{ - if (!pr) - return -1; - - DBG(DEBUG_LOWPROBE, printf( - "changing probing area pr=%p: size=%llu, off=%llu " - "-to-> size=%llu, off=%llu\n", - pr, - (unsigned long long) pr->size, - (unsigned long long) pr->off, - (unsigned long long) size, - (unsigned long long) off)); - - pr->off = off; - pr->size = size; - pr->flags &= ~BLKID_FL_TINY_DEV; - - if (pr->size <= 1440 * 1024 && !S_ISCHR(pr->mode)) - pr->flags |= BLKID_FL_TINY_DEV; - - blkid_probe_reset_buffer(pr); - - return 0; -} - -int blkid_probe_get_idmag(blkid_probe pr, const struct blkid_idinfo *id, - blkid_loff_t *offset, const struct blkid_idmag **res) -{ - const struct blkid_idmag *mag = NULL; - blkid_loff_t off = 0; - - if (id) - mag = id->magics ? &id->magics[0] : NULL; - if (res) - *res = NULL; - - /* try to detect by magic string */ - while(mag && mag->magic) { - unsigned char *buf; - - off = (mag->kboff + (mag->sboff >> 10)) << 10; - buf = blkid_probe_get_buffer(pr, off, 1024); - - if (buf && !memcmp(mag->magic, - buf + (mag->sboff & 0x3ff), mag->len)) { - DBG(DEBUG_LOWPROBE, printf( - "\tmagic sboff=%u, kboff=%ld\n", - mag->sboff, mag->kboff)); - if (offset) - *offset = off + (mag->sboff & 0x3ff); - if (res) - *res = mag; - return 0; - } - mag++; - } - - if (id->magics && id->magics[0].magic) - /* magic string(s) defined, but not found */ - return 1; - - return 0; -} - -static inline void blkid_probe_start(blkid_probe pr) -{ - if (pr) { - pr->cur_chain = NULL; - pr->prob_flags = 0; - blkid_probe_set_wiper(pr, 0, 0); - } -} - -static inline void blkid_probe_end(blkid_probe pr) -{ - if (pr) { - pr->cur_chain = NULL; - pr->prob_flags = 0; - blkid_probe_set_wiper(pr, 0, 0); - } -} - -/** - * blkid_do_probe: - * @pr: prober - * - * Calls probing functions in all enabled chains. The superblocks chain is - * enabled by default. The blkid_do_probe() stores result from only one - * probing function. It's necessary to call this routine in a loop to get - * results from all probing functions in all chains. The probing is reseted - * by blkid_reset_probe() or by filter functions. - * - * This is string-based NAME=value interface only. - * - * - * basic case - use the first result only - * - * - * if (blkid_do_probe(pr) == 0) { - * int nvals = blkid_probe_numof_values(pr); - * for (n = 0; n < nvals; n++) { - * if (blkid_probe_get_value(pr, n, &name, &data, &len) == 0) - * printf("%s = %s\n", name, data); - * } - * } - * - * - * - * - * advanced case - probe for all signatures - * - * - * while (blkid_do_probe(pr) == 0) { - * int nvals = blkid_probe_numof_values(pr); - * ... - * } - * - * - * - * See also blkid_reset_probe(). - * - * Returns: 0 on success, 1 when probing is done and -1 in case of error. - */ -int blkid_do_probe(blkid_probe pr) -{ - int rc = 1; - - if (!pr) - return -1; - - do { - struct blkid_chain *chn = pr->cur_chain; - - if (!chn) { - blkid_probe_start(pr); - chn = pr->cur_chain = &pr->chains[0]; - } - /* we go to the next chain only when the previous probing - * result was nothing (rc == 1) and when the current chain is - * disabled or we are at end of the current chain (chain->idx + - * 1 == sizeof chain) or the current chain bailed out right at - * the start (chain->idx == -1) - */ - else if (rc == 1 && (chn->enabled == FALSE || - chn->idx + 1 == chn->driver->nidinfos || - chn->idx == -1)) { - - int idx = chn->driver->id + 1; - - if (idx < BLKID_NCHAINS) - chn = pr->cur_chain = &pr->chains[idx]; - else { - blkid_probe_end(pr); - return 1; /* all chains already probed */ - } - } - - chn->binary = FALSE; /* for sure... */ - - DBG(DEBUG_LOWPROBE, printf("chain probe %s %s (idx=%d)\n", - chn->driver->name, - chn->enabled? "ENABLED" : "DISABLED", - chn->idx)); - - if (!chn->enabled) - continue; - - /* rc: -1 = error, 0 = success, 1 = no result */ - rc = chn->driver->probe(pr, chn); - - } while (rc == 1); - - return rc; -} - -/** - * blkid_do_safeprobe: - * @pr: prober - * - * This function gathers probing results from all enabled chains and checks - * for ambivalent results (e.g. more filesystems on the device). - * - * This is string-based NAME=value interface only. - * - * Note about suberblocks chain -- the function does not check for filesystems - * when a RAID signature is detected. The function also does not check for - * collision between RAIDs. The first detected RAID is returned. The function - * checks for collision between partition table and RAID signature -- it's - * recommended to enable partitions chain together with superblocks chain. - * - * Returns: 0 on success, 1 if nothing is detected, -2 if ambivalen result is - * detected and -1 on case of error. - */ -int blkid_do_safeprobe(blkid_probe pr) -{ - int i, count = 0, rc = 0; - - if (!pr) - return -1; - - blkid_probe_start(pr); - - for (i = 0; i < BLKID_NCHAINS; i++) { - struct blkid_chain *chn; - - chn = pr->cur_chain = &pr->chains[i]; - chn->binary = FALSE; /* for sure... */ - - DBG(DEBUG_LOWPROBE, printf("chain safeprobe %s %s\n", - chn->driver->name, - chn->enabled? "ENABLED" : "DISABLED")); - - if (!chn->enabled) - continue; - - blkid_probe_chain_reset_position(chn); - - rc = chn->driver->safeprobe(pr, chn); - - blkid_probe_chain_reset_position(chn); - - /* rc: -2 ambivalent, -1 = error, 0 = success, 1 = no result */ - if (rc < 0) - goto done; /* error */ - if (rc == 0) - count++; /* success */ - } - -done: - blkid_probe_end(pr); - if (rc < 0) - return rc; - return count ? 0 : 1; -} - -/** - * blkid_do_fullprobe: - * @pr: prober - * - * This function gathers probing results from all enabled chains. Same as - * blkid_so_safeprobe() but does not check for collision between probing - * result. - * - * This is string-based NAME=value interface only. - * - * Returns: 0 on success, 1 if nothing is detected or -1 on case of error. - */ -int blkid_do_fullprobe(blkid_probe pr) -{ - int i, count = 0, rc = 0; - - if (!pr) - return -1; - - blkid_probe_start(pr); - - for (i = 0; i < BLKID_NCHAINS; i++) { - int rc; - struct blkid_chain *chn; - - chn = pr->cur_chain = &pr->chains[i]; - chn->binary = FALSE; /* for sure... */ - - DBG(DEBUG_LOWPROBE, printf("chain fullprobe %s: %s\n", - chn->driver->name, - chn->enabled? "ENABLED" : "DISABLED")); - - if (!chn->enabled) - continue; - - blkid_probe_chain_reset_position(chn); - - rc = chn->driver->probe(pr, chn); - - blkid_probe_chain_reset_position(chn); - - /* rc: -1 = error, 0 = success, 1 = no result */ - if (rc < 0) - goto done; /* error */ - if (rc == 0) - count++; /* success */ - } - -done: - blkid_probe_end(pr); - if (rc < 0) - return rc; - return count ? 0 : 1; -} - -/* same sa blkid_probe_get_buffer() but works with 512-sectors */ -unsigned char *blkid_probe_get_sector(blkid_probe pr, unsigned int sector) -{ - return pr ? blkid_probe_get_buffer(pr, - ((blkid_loff_t) sector) << 9, 0x200) : NULL; -} - -struct blkid_prval *blkid_probe_assign_value( - blkid_probe pr, const char *name) -{ - struct blkid_prval *v; - - if (!name) - return NULL; - if (pr->nvals >= BLKID_NVALS) - return NULL; - - v = &pr->vals[pr->nvals]; - v->name = name; - v->chain = pr->cur_chain; - pr->nvals++; - - DBG(DEBUG_LOWPROBE, - printf("assigning %s [%s]\n", name, v->chain->driver->name)); - return v; -} - -int blkid_probe_reset_last_value(blkid_probe pr) -{ - struct blkid_prval *v; - - if (pr == NULL || pr->nvals == 0) - return -1; - - v = &pr->vals[pr->nvals - 1]; - - DBG(DEBUG_LOWPROBE, - printf("un-assigning %s [%s]\n", v->name, v->chain->driver->name)); - - memset(v, 0, sizeof(struct blkid_prval)); - pr->nvals--; - - return 0; - -} - -int blkid_probe_set_value(blkid_probe pr, const char *name, - unsigned char *data, size_t len) -{ - struct blkid_prval *v; - - if (len > BLKID_PROBVAL_BUFSIZ) - len = BLKID_PROBVAL_BUFSIZ; - - v = blkid_probe_assign_value(pr, name); - if (!v) - return -1; - - memcpy(v->data, data, len); - v->len = len; - return 0; -} - -int blkid_probe_vsprintf_value(blkid_probe pr, const char *name, - const char *fmt, va_list ap) -{ - struct blkid_prval *v; - size_t len; - - v = blkid_probe_assign_value(pr, name); - if (!v) - return -1; - - len = vsnprintf((char *) v->data, sizeof(v->data), fmt, ap); - - if (len <= 0) { - blkid_probe_reset_last_value(pr); - return -1; - } - v->len = len + 1; - return 0; -} - -int blkid_probe_sprintf_value(blkid_probe pr, const char *name, - const char *fmt, ...) -{ - int rc; - va_list ap; - - va_start(ap, fmt); - rc = blkid_probe_vsprintf_value(pr, name, fmt, ap); - va_end(ap); - - return rc; -} - -/** - * blkid_probe_get_devno: - * @pr: probe - * - * Returns: block device number, or 0 for regilar files. - */ -dev_t blkid_probe_get_devno(blkid_probe pr) -{ - return pr->devno; -} - -/** - * blkid_probe_get_wholedisk_devno: - * @pr: probe - * - * Returns: device number of the wholedisk, or 0 for regilar files. - */ -dev_t blkid_probe_get_wholedisk_devno(blkid_probe pr) -{ - if (!pr->disk_devno) { - dev_t devno, disk_devno = 0; - - devno = blkid_probe_get_devno(pr); - if (!devno) - return 0; - - if (blkid_devno_to_wholedisk(devno, NULL, 0, &disk_devno) == 0) - pr->disk_devno = disk_devno; - } - return pr->disk_devno; -} - -/** - * blkid_probe_is_wholedisk: - * @pr: probe - * - * Returns: 1 if the device is whole-disk or 0. - */ -int blkid_probe_is_wholedisk(blkid_probe pr) -{ - dev_t devno, disk_devno; - - devno = blkid_probe_get_devno(pr); - if (!devno) - return 0; - - disk_devno = blkid_probe_get_wholedisk_devno(pr); - if (!disk_devno) - return 0; - - return devno == disk_devno; -} - -blkid_probe blkid_probe_get_wholedisk_probe(blkid_probe pr) -{ - dev_t disk; - - if (blkid_probe_is_wholedisk(pr)) - return NULL; /* this is not partition */ - - if (pr->parent) - /* this is cloned blkid_probe, use parent's stuff */ - return blkid_probe_get_wholedisk_probe(pr->parent); - - disk = blkid_probe_get_wholedisk_devno(pr); - - if (pr->disk_probe && pr->disk_probe->devno != disk) { - /* we have disk prober, but for another disk... close it */ - blkid_free_probe(pr->disk_probe); - pr->disk_probe = NULL; - } - - if (!pr->disk_probe) { - /* Open a new disk prober */ - char *disk_path = blkid_devno_to_devname(disk); - - if (!disk_path) - return NULL; - - DBG(DEBUG_LOWPROBE, printf("allocate a wholedisk probe\n")); - - pr->disk_probe = blkid_new_probe_from_filename(disk_path); - if (!pr->disk_probe) - return NULL; /* ENOMEM? */ - } - - return pr->disk_probe; -} - -/** - * blkid_probe_get_size: - * @pr: probe - * - * This function returns size of probing area as defined by blkid_probe_set_device(). - * If the size of the probing area is unrestricted then this function returns - * the real size of device. See also blkid_get_dev_size(). - * - * Returns: size in bytes or -1 in case of error. - */ -blkid_loff_t blkid_probe_get_size(blkid_probe pr) -{ - return pr ? pr->size : -1; -} - -/** - * blkid_probe_get_offset: - * @pr: probe - * - * This function returns offset of probing area as defined by blkid_probe_set_device(). - * - * Returns: offset in bytes or -1 in case of error. - */ -blkid_loff_t blkid_probe_get_offset(blkid_probe pr) -{ - return pr ? pr->off : -1; -} - -/** - * blkid_probe_get_fd: - * @pr: probe - * - * Returns: file descriptor for assigned device/file. - */ -int blkid_probe_get_fd(blkid_probe pr) -{ - return pr ? pr->fd : -1; -} - -/** - * blkid_probe_get_sectorsize: - * @pr: probe or NULL (for NULL returns 512) - * - * Returns: block device logical sector size (BLKSSZGET ioctl, default 512). - */ -unsigned int blkid_probe_get_sectorsize(blkid_probe pr) -{ - if (!pr) - return DEFAULT_SECTOR_SIZE; /*... and good luck! */ - - if (pr->blkssz) - return pr->blkssz; - - if (S_ISBLK(pr->mode) && - blkdev_get_sector_size(pr->fd, (int *) &pr->blkssz) == 0) - return pr->blkssz; - - pr->blkssz = DEFAULT_SECTOR_SIZE; - return pr->blkssz; -} - -/** - * blkid_probe_get_sectors: - * @pr: probe - * - * Returns: 512-byte sector count or -1 in case of error. - */ -blkid_loff_t blkid_probe_get_sectors(blkid_probe pr) -{ - return pr ? pr->size >> 9 : -1; -} - -/** - * blkid_probe_numof_values: - * @pr: probe - * - * Returns: number of values in probing result or -1 in case of error. - */ -int blkid_probe_numof_values(blkid_probe pr) -{ - if (!pr) - return -1; - return pr->nvals; -} - -/** - * blkid_probe_get_value: - * @pr: probe - * @num: wanted value in range 0..N, where N is blkid_probe_numof_values() - 1 - * @name: pointer to return value name or NULL - * @data: pointer to return value data or NULL - * @len: pointer to return value length or NULL - * - * Note, the @len returns length of the @data, including the terminating - * '\0' character. - * - * Returns: 0 on success, or -1 in case of error. - */ -int blkid_probe_get_value(blkid_probe pr, int num, const char **name, - const char **data, size_t *len) -{ - struct blkid_prval *v = __blkid_probe_get_value(pr, num); - - if (!v) - return -1; - if (name) - *name = v->name; - if (data) - *data = (char *) v->data; - if (len) - *len = v->len; - - DBG(DEBUG_LOWPROBE, printf("returning %s value\n", v->name)); - return 0; -} - -/** - * blkid_probe_lookup_value: - * @pr: probe - * @name: name of value - * @data: pointer to return value data or NULL - * @len: pointer to return value length or NULL - * - * Note, the @len returns length of the @data, including the terminating - * '\0' character. - * - * Returns: 0 on success, or -1 in case of error. - */ -int blkid_probe_lookup_value(blkid_probe pr, const char *name, - const char **data, size_t *len) -{ - struct blkid_prval *v = __blkid_probe_lookup_value(pr, name); - - if (!v) - return -1; - if (data) - *data = (char *) v->data; - if (len) - *len = v->len; - return 0; -} - -/** - * blkid_probe_has_value: - * @pr: probe - * @name: name of value - * - * Returns: 1 if value exist in probing result, otherwise 0. - */ -int blkid_probe_has_value(blkid_probe pr, const char *name) -{ - if (blkid_probe_lookup_value(pr, name, NULL, NULL) == 0) - return 1; - return 0; -} - -struct blkid_prval *__blkid_probe_get_value(blkid_probe pr, int num) -{ - if (pr == NULL || num < 0 || num >= pr->nvals) - return NULL; - - return &pr->vals[num]; -} - -struct blkid_prval *__blkid_probe_lookup_value(blkid_probe pr, const char *name) -{ - int i; - - if (pr == NULL || pr->nvals == 0 || name == NULL) - return NULL; - - for (i = 0; i < pr->nvals; i++) { - struct blkid_prval *v = &pr->vals[i]; - - if (v->name && strcmp(name, v->name) == 0) { - DBG(DEBUG_LOWPROBE, printf("returning %s value\n", v->name)); - return v; - } - } - return NULL; -} - - -/* converts DCE UUID (uuid[16]) to human readable string - * - the @len should be always 37 */ -void blkid_unparse_uuid(const unsigned char *uuid, char *str, size_t len) -{ -#ifdef HAVE_LIBUUID - uuid_unparse(uuid, str); -#else - snprintf(str, len, - "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", - uuid[0], uuid[1], uuid[2], uuid[3], - uuid[4], uuid[5], - uuid[6], uuid[7], - uuid[8], uuid[9], - uuid[10], uuid[11], uuid[12], uuid[13], uuid[14],uuid[15]); -#endif -} - - -/* Removes whitespace from the right-hand side of a string (trailing - * whitespace). - * - * Returns size of the new string (without \0). - */ -size_t blkid_rtrim_whitespace(unsigned char *str) -{ - size_t i = strlen((char *) str); - - while (i--) { - if (!isspace(str[i])) - break; - } - str[++i] = '\0'; - return i; -} - -/* - * Some mkfs-like utils wipe some parts (usually begin) of the device. - * For example LVM (pvcreate) or mkswap(8). This information could be used - * for later resolution to conflicts between superblocks. - * - * For example we found valid LVM superblock, LVM wipes 8KiB at the begin of - * the device. If we found another signature (for example MBR) this wiped area - * then the signature has been added later and LVM superblock should be ignore. - * - * Note that this heuristic is not 100% reliable, for example "pvcreate --zero - * n" allows to keep the begin of the device unmodified. It's probably better - * to use this heuristic for conflicts between superblocks and partition tables - * than for conflicts between filesystem superblocks -- existence of unwanted - * partition table is very unusual, because PT is pretty visible (parsed and - * interpreted by kernel). - */ -void blkid_probe_set_wiper(blkid_probe pr, blkid_loff_t off, blkid_loff_t size) -{ - struct blkid_chain *chn; - - if (!pr) - return; - - if (!size) { - DBG(DEBUG_LOWPROBE, printf("zeroize wiper\n")); - pr->wipe_size = pr->wipe_off = 0; - pr->wipe_chain = NULL; - return; - } - - chn = pr->cur_chain; - - if (!chn || !chn->driver || - chn->idx < 0 || chn->idx >= chn->driver->nidinfos) - return; - - pr->wipe_size = size; - pr->wipe_off = off; - pr->wipe_chain = chn; - - DBG(DEBUG_LOWPROBE, - printf("wiper set to %s::%s off=%jd size=%jd\n", - chn->driver->name, - chn->driver->idinfos[chn->idx]->name, - pr->wipe_off, pr->wipe_size)); - return; -} - -/* - * Returns 1 if the <@off,@size> area was wiped - */ -int blkid_probe_is_wiped(blkid_probe pr, struct blkid_chain **chn, - blkid_loff_t off, blkid_loff_t size) -{ - if (!pr || !size) - return 0; - - if (pr->wipe_off <= off && off + size <= pr->wipe_off + pr->wipe_size) { - if (chn) - *chn = pr->wipe_chain; - return 1; - } - return 0; -} - -void blkid_probe_use_wiper(blkid_probe pr, blkid_loff_t off, blkid_loff_t size) -{ - struct blkid_chain *chn = NULL; - - if (blkid_probe_is_wiped(pr, &chn, off, size) && chn) { - DBG(DEBUG_LOWPROBE, printf("wiped area detected -- ignore previous results\n")); - blkid_probe_set_wiper(pr, 0, 0); - blkid_probe_chain_reset_vals(pr, chn); - } -} - diff --git a/shlibs/blkid/src/read.c b/shlibs/blkid/src/read.c deleted file mode 100644 index c404bb01..00000000 --- a/shlibs/blkid/src/read.c +++ /dev/null @@ -1,498 +0,0 @@ -/* - * read.c - read the blkid cache from disk, to avoid scanning all devices - * - * Copyright (C) 2001, 2003 Theodore Y. Ts'o - * Copyright (C) 2001 Andreas Dilger - * - * %Begin-Header% - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * %End-Header% - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#if HAVE_ERRNO_H -#include -#endif - -#include "blkidP.h" - -#if HAVE_STDLIB_H -# ifndef _XOPEN_SOURCE -# define _XOPEN_SOURCE 600 /* for inclusion of strtoull */ -# endif -# include -#endif - -#ifdef HAVE_STRTOULL -#define STRTOULL strtoull /* defined in stdlib.h if you try hard enough */ -#else -/* FIXME: need to support real strtoull here */ -#define STRTOULL strtoul -#endif - -#ifdef TEST_PROGRAM -#define blkid_debug_dump_dev(dev) (debug_dump_dev(dev)) -static void debug_dump_dev(blkid_dev dev); -#endif - -/* - * File format: - * - * ...]>device_name - * - * The following tags are required for each entry: - * unique (within this file) ID number of this device - * (time_t and suseconds_t) time this entry was last - * read from disk - * (detected) type of filesystem/data for this partition - * - * The following tags may be present, depending on the device contents - * (user supplied) label (volume name, etc) - * (generated) universally unique identifier (serial no) - */ - -static char *skip_over_blank(char *cp) -{ - while (*cp && isspace(*cp)) - cp++; - return cp; -} - -static char *skip_over_word(char *cp) -{ - char ch; - - while ((ch = *cp)) { - /* If we see a backslash, skip the next character */ - if (ch == '\\') { - cp++; - if (*cp == '\0') - break; - cp++; - continue; - } - if (isspace(ch) || ch == '<' || ch == '>') - break; - cp++; - } - return cp; -} - -static char *strip_line(char *line) -{ - char *p; - - line = skip_over_blank(line); - - p = line + strlen(line) - 1; - - while (*line) { - if (isspace(*p)) - *p-- = '\0'; - else - break; - } - - return line; -} - -#if 0 -static char *parse_word(char **buf) -{ - char *word, *next; - - word = *buf; - if (*word == '\0') - return NULL; - - word = skip_over_blank(word); - next = skip_over_word(word); - if (*next) { - char *end = next - 1; - if (*end == '"' || *end == '\'') - *end = '\0'; - *next++ = '\0'; - } - *buf = next; - - if (*word == '"' || *word == '\'') - word++; - return word; -} -#endif - -/* - * Start parsing a new line from the cache. - * - * line starts with " continue parsing line - * line starts with " skip line - * line starts with other, return -BLKID_ERR_CACHE -> error - */ -static int parse_start(char **cp) -{ - char *p; - - p = strip_line(*cp); - - /* Skip comment or blank lines. We can't just NUL the first '#' char, - * in case it is inside quotes, or escaped. - */ - if (*p == '\0' || *p == '#') - return 0; - - if (!strncmp(p, "", 9)) { - DBG(DEBUG_READ, printf("found device trailer %9s\n", *cp)); - *cp += 9; - return 0; - } - - return -BLKID_ERR_CACHE; -} - -/* - * Allocate a new device struct with device name filled in. Will handle - * finding the device on lines of the form: - * devname - * devnamebar - */ -static int parse_dev(blkid_cache cache, blkid_dev *dev, char **cp) -{ - char *start, *tmp, *end, *name; - int ret; - - if ((ret = parse_start(cp)) <= 0) - return ret; - - start = tmp = strchr(*cp, '>'); - if (!start) { - DBG(DEBUG_READ, - printf("blkid: short line parsing dev: %s\n", *cp)); - return -BLKID_ERR_CACHE; - } - start = skip_over_blank(start + 1); - end = skip_over_word(start); - - DBG(DEBUG_READ, printf("device should be %*s\n", - (int)(end - start), start)); - - if (**cp == '>') - *cp = end; - else - (*cp)++; - - *tmp = '\0'; - - if (!(tmp = strrchr(end, '<')) || parse_end(&tmp) < 0) { - DBG(DEBUG_READ, - printf("blkid: missing ending: %s\n", end)); - } else if (tmp) - *tmp = '\0'; - - if (end - start <= 1) { - DBG(DEBUG_READ, printf("blkid: empty device name: %s\n", *cp)); - return -BLKID_ERR_CACHE; - } - - name = blkid_strndup(start, end-start); - if (name == NULL) - return -BLKID_ERR_MEM; - - DBG(DEBUG_READ, printf("found dev %s\n", name)); - - if (!(*dev = blkid_get_dev(cache, name, BLKID_DEV_CREATE))) { - free(name); - return -BLKID_ERR_MEM; - } - - free(name); - return 1; -} - -/* - * Extract a tag of the form NAME="value" from the line. - */ -static int parse_token(char **name, char **value, char **cp) -{ - char *end; - - if (!name || !value || !cp) - return -BLKID_ERR_PARAM; - - if (!(*value = strchr(*cp, '='))) - return 0; - - **value = '\0'; - *name = strip_line(*cp); - *value = skip_over_blank(*value + 1); - - if (**value == '"') { - end = strchr(*value + 1, '"'); - if (!end) { - DBG(DEBUG_READ, - printf("unbalanced quotes at: %s\n", *value)); - *cp = *value; - return -BLKID_ERR_CACHE; - } - (*value)++; - *end = '\0'; - end++; - } else { - end = skip_over_word(*value); - if (*end) { - *end = '\0'; - end++; - } - } - *cp = end; - - return 1; -} - -/* - * Extract a tag of the form value from the line. - */ -/* -static int parse_xml(char **name, char **value, char **cp) -{ - char *end; - - if (!name || !value || !cp) - return -BLKID_ERR_PARAM; - - *name = strip_line(*cp); - - if ((*name)[0] != '<' || (*name)[1] == '/') - return 0; - - FIXME: finish this. -} -*/ - -/* - * Extract a tag from the line. - * - * Return 1 if a valid tag was found. - * Return 0 if no tag found. - * Return -ve error code. - */ -static int parse_tag(blkid_cache cache, blkid_dev dev, char **cp) -{ - char *name = NULL; - char *value = NULL; - int ret; - - if (!cache || !dev) - return -BLKID_ERR_PARAM; - - if ((ret = parse_token(&name, &value, cp)) <= 0 /* && - (ret = parse_xml(&name, &value, cp)) <= 0 */) - return ret; - - /* Some tags are stored directly in the device struct */ - if (!strcmp(name, "DEVNO")) - dev->bid_devno = STRTOULL(value, 0, 0); - else if (!strcmp(name, "PRI")) - dev->bid_pri = strtol(value, 0, 0); - else if (!strcmp(name, "TIME")) { - char *end = NULL; - dev->bid_time = STRTOULL(value, &end, 0); - if (end && *end == '.') - dev->bid_utime = STRTOULL(end + 1, 0, 0); - } else - ret = blkid_set_tag(dev, name, value, strlen(value)); - - DBG(DEBUG_READ, printf(" tag: %s=\"%s\"\n", name, value)); - - return ret < 0 ? ret : 1; -} - -/* - * Parse a single line of data, and return a newly allocated dev struct. - * Add the new device to the cache struct, if one was read. - * - * Lines are of the form /dev/foo - * - * Returns -ve value on error. - * Returns 0 otherwise. - * If a valid device was read, *dev_p is non-NULL, otherwise it is NULL - * (e.g. comment lines, unknown XML content, etc). - */ -static int blkid_parse_line(blkid_cache cache, blkid_dev *dev_p, char *cp) -{ - blkid_dev dev; - int ret; - - if (!cache || !dev_p) - return -BLKID_ERR_PARAM; - - *dev_p = NULL; - - DBG(DEBUG_READ, printf("line: %s\n", cp)); - - if ((ret = parse_dev(cache, dev_p, &cp)) <= 0) - return ret; - - dev = *dev_p; - - while ((ret = parse_tag(cache, dev, &cp)) > 0) { - ; - } - - if (dev->bid_type == NULL) { - DBG(DEBUG_READ, - printf("blkid: device %s has no TYPE\n",dev->bid_name)); - blkid_free_dev(dev); - } - - DBG(DEBUG_READ, blkid_debug_dump_dev(dev)); - - return ret; -} - -/* - * Parse the specified filename, and return the data in the supplied or - * a newly allocated cache struct. If the file doesn't exist, return a - * new empty cache struct. - */ -void blkid_read_cache(blkid_cache cache) -{ - FILE *file; - char buf[4096]; - int fd, lineno = 0; - struct stat st; - - if (!cache) - return; - - /* - * If the file doesn't exist, then we just return an empty - * struct so that the cache can be populated. - */ - if ((fd = open(cache->bic_filename, O_RDONLY)) < 0) - return; - if (fstat(fd, &st) < 0) - goto errout; - if ((st.st_mtime == cache->bic_ftime) || - (cache->bic_flags & BLKID_BIC_FL_CHANGED)) { - DBG(DEBUG_CACHE, printf("skipping re-read of %s\n", - cache->bic_filename)); - goto errout; - } - - DBG(DEBUG_CACHE, printf("reading cache file %s\n", - cache->bic_filename)); - - file = fdopen(fd, "r"); - if (!file) - goto errout; - - while (fgets(buf, sizeof(buf), file)) { - blkid_dev dev; - unsigned int end; - - lineno++; - if (buf[0] == 0) - continue; - end = strlen(buf) - 1; - /* Continue reading next line if it ends with a backslash */ - while (buf[end] == '\\' && end < sizeof(buf) - 2 && - fgets(buf + end, sizeof(buf) - end, file)) { - end = strlen(buf) - 1; - lineno++; - } - - if (blkid_parse_line(cache, &dev, buf) < 0) { - DBG(DEBUG_READ, - printf("blkid: bad format on line %d\n", lineno)); - continue; - } - } - fclose(file); - - /* - * Initially we do not need to write out the cache file. - */ - cache->bic_flags &= ~BLKID_BIC_FL_CHANGED; - cache->bic_ftime = st.st_mtime; - - return; -errout: - close(fd); - return; -} - -#ifdef TEST_PROGRAM -static void debug_dump_dev(blkid_dev dev) -{ - struct list_head *p; - - if (!dev) { - printf(" dev: NULL\n"); - return; - } - - printf(" dev: name = %s\n", dev->bid_name); - printf(" dev: DEVNO=\"0x%0llx\"\n", (long long)dev->bid_devno); - printf(" dev: TIME=\"%ld.%ld\"\n", (long)dev->bid_time, (long)dev->bid_utime); - printf(" dev: PRI=\"%d\"\n", dev->bid_pri); - printf(" dev: flags = 0x%08X\n", dev->bid_flags); - - list_for_each(p, &dev->bid_tags) { - blkid_tag tag = list_entry(p, struct blkid_struct_tag, bit_tags); - if (tag) - printf(" tag: %s=\"%s\"\n", tag->bit_name, - tag->bit_val); - else - printf(" tag: NULL\n"); - } - printf("\n"); -} - -int main(int argc, char**argv) -{ - blkid_cache cache = NULL; - int ret; - - blkid_init_debug(DEBUG_ALL); - if (argc > 2) { - fprintf(stderr, "Usage: %s [filename]\n" - "Test parsing of the cache (filename)\n", argv[0]); - exit(1); - } - if ((ret = blkid_get_cache(&cache, argv[1])) < 0) - fprintf(stderr, "error %d reading cache file %s\n", ret, - argv[1] ? argv[1] : BLKID_CACHE_FILE); - - blkid_put_cache(cache); - - return ret; -} -#endif diff --git a/shlibs/blkid/src/resolve.c b/shlibs/blkid/src/resolve.c deleted file mode 100644 index bf13b864..00000000 --- a/shlibs/blkid/src/resolve.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * resolve.c - resolve names and tags into specific devices - * - * Copyright (C) 2001, 2003 Theodore Ts'o. - * Copyright (C) 2001 Andreas Dilger - * - * %Begin-Header% - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * %End-Header% - */ - -#include -#if HAVE_UNISTD_H -#include -#endif -#include -#include -#include -#include -#include -#include "blkidP.h" - -/* - * Find a tagname (e.g. LABEL or UUID) on a specific device. - */ -char *blkid_get_tag_value(blkid_cache cache, const char *tagname, - const char *devname) -{ - blkid_tag found; - blkid_dev dev; - blkid_cache c = cache; - char *ret = NULL; - - DBG(DEBUG_RESOLVE, printf("looking for %s on %s\n", tagname, devname)); - - if (!devname) - return NULL; - - if (!cache) { - if (blkid_get_cache(&c, NULL) < 0) - return NULL; - } - - if ((dev = blkid_get_dev(c, devname, BLKID_DEV_NORMAL)) && - (found = blkid_find_tag_dev(dev, tagname))) - ret = blkid_strdup(found->bit_val); - - if (!cache) - blkid_put_cache(c); - - return ret; -} - -/* - * Locate a device name from a token (NAME=value string), or (name, value) - * pair. In the case of a token, value is ignored. If the "token" is not - * of the form "NAME=value" and there is no value given, then it is assumed - * to be the actual devname and a copy is returned. - */ -char *blkid_get_devname(blkid_cache cache, const char *token, - const char *value) -{ - blkid_dev dev; - blkid_cache c = cache; - char *t = 0, *v = 0; - char *ret = NULL; - - if (!token) - return NULL; - - if (!cache) { - if (blkid_get_cache(&c, NULL) < 0) - return NULL; - } - - DBG(DEBUG_RESOLVE, - printf("looking for %s%s%s %s\n", token, value ? "=" : "", - value ? value : "", cache ? "in cache" : "from disk")); - - if (!value) { - if (!strchr(token, '=')) { - ret = blkid_strdup(token); - goto out; - } - blkid_parse_tag_string(token, &t, &v); - if (!t || !v) - goto out; - token = t; - value = v; - } - - dev = blkid_find_dev_with_tag(c, token, value); - if (!dev) - goto out; - - ret = blkid_strdup(blkid_dev_devname(dev)); - -out: - free(t); - free(v); - if (!cache) { - blkid_put_cache(c); - } - return (ret); -} - -#ifdef TEST_PROGRAM -int main(int argc, char **argv) -{ - char *value; - blkid_cache cache; - - blkid_init_debug(DEBUG_ALL); - if (argc != 2 && argc != 3) { - fprintf(stderr, "Usage:\t%s tagname=value\n" - "\t%s tagname devname\n" - "Find which device holds a given token or\n" - "Find what the value of a tag is in a device\n", - argv[0], argv[0]); - exit(1); - } - if (blkid_get_cache(&cache, "/dev/null") < 0) { - fprintf(stderr, "Couldn't get blkid cache\n"); - exit(1); - } - - if (argv[2]) { - value = blkid_get_tag_value(cache, argv[1], argv[2]); - printf("%s has tag %s=%s\n", argv[2], argv[1], - value ? value : ""); - } else { - value = blkid_get_devname(cache, argv[1], NULL); - printf("%s has tag %s\n", value ? value : "", argv[1]); - } - blkid_put_cache(cache); - return value ? 0 : 1; -} -#endif diff --git a/shlibs/blkid/src/save.c b/shlibs/blkid/src/save.c deleted file mode 100644 index a71b0687..00000000 --- a/shlibs/blkid/src/save.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * save.c - write the cache struct to disk - * - * Copyright (C) 2001 by Andreas Dilger - * Copyright (C) 2003 Theodore Ts'o - * - * %Begin-Header% - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * %End-Header% - */ - -#include -#include -#include -#include -#include -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#include "blkidP.h" - -static int save_dev(blkid_dev dev, FILE *file) -{ - struct list_head *p; - - if (!dev || dev->bid_name[0] != '/') - return 0; - - DBG(DEBUG_SAVE, - printf("device %s, type %s\n", dev->bid_name, dev->bid_type ? - dev->bid_type : "(null)")); - - fprintf(file, "bid_devno, - (long) dev->bid_time, - (long) dev->bid_utime); - - if (dev->bid_pri) - fprintf(file, " PRI=\"%d\"", dev->bid_pri); - list_for_each(p, &dev->bid_tags) { - blkid_tag tag = list_entry(p, struct blkid_struct_tag, bit_tags); - fprintf(file, " %s=\"%s\"", tag->bit_name,tag->bit_val); - } - fprintf(file, ">%s\n", dev->bid_name); - - return 0; -} - -/* - * Write out the cache struct to the cache file on disk. - */ -int blkid_flush_cache(blkid_cache cache) -{ - struct list_head *p; - char *tmp = NULL; - const char *opened = NULL; - const char *filename; - FILE *file = NULL; - int fd, ret = 0; - struct stat st; - - if (!cache) - return -BLKID_ERR_PARAM; - - if (list_empty(&cache->bic_devs) || - !(cache->bic_flags & BLKID_BIC_FL_CHANGED)) { - DBG(DEBUG_SAVE, printf("skipping cache file write\n")); - return 0; - } - - filename = cache->bic_filename ? cache->bic_filename: BLKID_CACHE_FILE; - - /* If we can't write to the cache file, then don't even try */ - if (((ret = stat(filename, &st)) < 0 && errno != ENOENT) || - (ret == 0 && access(filename, W_OK) < 0)) { - DBG(DEBUG_SAVE, - printf("can't write to cache file %s\n", filename)); - return 0; - } - - /* - * Try and create a temporary file in the same directory so - * that in case of error we don't overwrite the cache file. - * If the cache file doesn't yet exist, it isn't a regular - * file (e.g. /dev/null or a socket), or we couldn't create - * a temporary file then we open it directly. - */ - if (ret == 0 && S_ISREG(st.st_mode)) { - tmp = malloc(strlen(filename) + 8); - if (tmp) { - sprintf(tmp, "%s-XXXXXX", filename); - fd = mkstemp(tmp); - if (fd >= 0) { - file = fdopen(fd, "w"); - opened = tmp; - } - fchmod(fd, 0644); - } - } - - if (!file) { - file = fopen(filename, "w"); - opened = filename; - } - - DBG(DEBUG_SAVE, - printf("writing cache file %s (really %s)\n", - filename, opened)); - - if (!file) { - ret = errno; - goto errout; - } - - list_for_each(p, &cache->bic_devs) { - blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs); - if (!dev->bid_type || (dev->bid_flags & BLKID_BID_FL_REMOVABLE)) - continue; - if ((ret = save_dev(dev, file)) < 0) - break; - } - - if (ret >= 0) { - cache->bic_flags &= ~BLKID_BIC_FL_CHANGED; - ret = 1; - } - - fclose(file); - if (opened != filename) { - if (ret < 0) { - unlink(opened); - DBG(DEBUG_SAVE, - printf("unlinked temp cache %s\n", opened)); - } else { - char *backup; - - backup = malloc(strlen(filename) + 5); - if (backup) { - sprintf(backup, "%s.old", filename); - unlink(backup); - if (link(filename, backup)) { - DBG(DEBUG_SAVE, - printf("can't link %s to %s\n", - filename, backup)); - } - free(backup); - } - rename(opened, filename); - DBG(DEBUG_SAVE, - printf("moved temp cache %s\n", opened)); - } - } - -errout: - free(tmp); - return ret; -} - -#ifdef TEST_PROGRAM -int main(int argc, char **argv) -{ - blkid_cache cache = NULL; - int ret; - - blkid_init_debug(DEBUG_ALL); - if (argc > 2) { - fprintf(stderr, "Usage: %s [filename]\n" - "Test loading/saving a cache (filename)\n", argv[0]); - exit(1); - } - - if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) { - fprintf(stderr, "%s: error creating cache (%d)\n", - argv[0], ret); - exit(1); - } - if ((ret = blkid_probe_all(cache)) < 0) { - fprintf(stderr, "error (%d) probing devices\n", ret); - exit(1); - } - cache->bic_filename = blkid_strdup(argv[1]); - - if ((ret = blkid_flush_cache(cache)) < 0) { - fprintf(stderr, "error (%d) saving cache\n", ret); - exit(1); - } - - blkid_put_cache(cache); - - return ret; -} -#endif diff --git a/shlibs/blkid/src/superblocks/Makefile.am b/shlibs/blkid/src/superblocks/Makefile.am deleted file mode 100644 index 1501fab1..00000000 --- a/shlibs/blkid/src/superblocks/Makefile.am +++ /dev/null @@ -1,51 +0,0 @@ -include $(top_srcdir)/config/include-Makefile.am - -AM_CPPFLAGS += -I$(ul_libblkid_incdir) -I$(ul_libblkid_srcdir) - -noinst_LTLIBRARIES = libblkid_superblocks.la -libblkid_superblocks_la_SOURCES = \ - superblocks.h \ - superblocks.c \ - cramfs.c \ - swap.c \ - adaptec_raid.c \ - ddf_raid.c \ - isw_raid.c \ - jmicron_raid.c \ - lsi_raid.c \ - nvidia_raid.c \ - promise_raid.c \ - silicon_raid.c \ - via_raid.c \ - linux_raid.c \ - jfs.c \ - xfs.c \ - ext.c \ - gfs.c \ - ocfs.c \ - reiserfs.c \ - romfs.c \ - ntfs.c \ - hfs.c \ - iso9660.c \ - udf.c \ - vfat.c \ - luks.c \ - highpoint_raid.c \ - vxfs.c \ - minix.c \ - ufs.c \ - hpfs.c \ - squashfs.c \ - netware.c \ - sysv.c \ - btrfs.c \ - lvm.c \ - zfs.c \ - ubifs.c \ - bfs.c \ - drbd.c \ - vmfs.c \ - befs.c \ - nilfs.c \ - exfat.c diff --git a/shlibs/blkid/src/superblocks/adaptec_raid.c b/shlibs/blkid/src/superblocks/adaptec_raid.c deleted file mode 100644 index 570e75e9..00000000 --- a/shlibs/blkid/src/superblocks/adaptec_raid.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2008 Karel Zak - * - * Inspired by libvolume_id by - * Kay Sievers - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include - -#include "superblocks.h" - -struct adaptec_metadata { - - 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]; - uint32_t smagic; - uint32_t raidtbl; - uint16_t raidline; - uint8_t res9[0xF6]; -} __attribute__((packed)); - -#define AD_SIGNATURE 0x4450544D /* "DPTM" */ -#define AD_MAGIC 0x37FC4D1E - -static int probe_adraid(blkid_probe pr, const struct blkid_idmag *mag) -{ - uint64_t off; - struct adaptec_metadata *ad; - - if (pr->size < 0x10000) - return -1; - - if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) - return -1; - - off = ((pr->size / 0x200)-1) * 0x200; - ad = (struct adaptec_metadata *) - blkid_probe_get_buffer(pr, - off, - sizeof(struct adaptec_metadata)); - if (!ad) - return -1; - if (ad->smagic != be32_to_cpu(AD_SIGNATURE)) - return -1; - if (ad->b0idcode != be32_to_cpu(AD_MAGIC)) - return -1; - if (blkid_probe_sprintf_version(pr, "%u", ad->resver) != 0) - return -1; - if (blkid_probe_set_magic(pr, off, sizeof(ad->b0idcode), - (unsigned char *) &ad->b0idcode)) - return -1; - return 0; -} - -const struct blkid_idinfo adraid_idinfo = { - .name = "adaptec_raid_member", - .usage = BLKID_USAGE_RAID, - .probefunc = probe_adraid, - .magics = BLKID_NONE_MAGIC -}; - - diff --git a/shlibs/blkid/src/superblocks/befs.c b/shlibs/blkid/src/superblocks/befs.c deleted file mode 100644 index c78dc208..00000000 --- a/shlibs/blkid/src/superblocks/befs.c +++ /dev/null @@ -1,470 +0,0 @@ -/* - * Copyright (C) 2010 Jeroen Oortwijn - * - * Partly based on the Haiku BFS driver by - * Axel Dörfler - * - * Also inspired by the Linux BeFS driver by - * Will Dyson , et al. - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include - -#include "superblocks.h" - -#define B_OS_NAME_LENGTH 0x20 -#define SUPER_BLOCK_MAGIC1 0x42465331 /* BFS1 */ -#define SUPER_BLOCK_MAGIC2 0xdd121031 -#define SUPER_BLOCK_MAGIC3 0x15b6830e -#define SUPER_BLOCK_FS_ENDIAN 0x42494745 /* BIGE */ -#define INODE_MAGIC1 0x3bbe0ad9 -#define BPLUSTREE_MAGIC 0x69f6c2e8 -#define BPLUSTREE_NULL -1LL -#define NUM_DIRECT_BLOCKS 12 -#define B_UINT64_TYPE 0x554c4c47 /* ULLG */ -#define KEY_NAME "be:volume_id" -#define KEY_SIZE 8 - -#define FS16_TO_CPU(value, fs_is_le) (fs_is_le ? le16_to_cpu(value) \ - : be16_to_cpu(value)) -#define FS32_TO_CPU(value, fs_is_le) (fs_is_le ? le32_to_cpu(value) \ - : be32_to_cpu(value)) -#define FS64_TO_CPU(value, fs_is_le) (fs_is_le ? le64_to_cpu(value) \ - : be64_to_cpu(value)) - -typedef struct block_run { - int32_t allocation_group; - uint16_t start; - uint16_t len; -} __attribute__((packed)) block_run, inode_addr; - -struct befs_super_block { - char name[B_OS_NAME_LENGTH]; - int32_t magic1; - int32_t fs_byte_order; - uint32_t block_size; - uint32_t block_shift; - int64_t num_blocks; - int64_t used_blocks; - int32_t inode_size; - int32_t magic2; - int32_t blocks_per_ag; - int32_t ag_shift; - int32_t num_ags; - int32_t flags; - block_run log_blocks; - int64_t log_start; - int64_t log_end; - int32_t magic3; - inode_addr root_dir; - inode_addr indices; - int32_t pad[8]; -} __attribute__((packed)); - -typedef struct data_stream { - block_run direct[NUM_DIRECT_BLOCKS]; - int64_t max_direct_range; - block_run indirect; - int64_t max_indirect_range; - block_run double_indirect; - int64_t max_double_indirect_range; - int64_t size; -} __attribute__((packed)) data_stream; - -struct befs_inode { - int32_t magic1; - inode_addr inode_num; - int32_t uid; - int32_t gid; - int32_t mode; - int32_t flags; - int64_t create_time; - int64_t last_modified_time; - inode_addr parent; - inode_addr attributes; - uint32_t type; - int32_t inode_size; - uint32_t etc; - data_stream data; - int32_t pad[4]; - int32_t small_data[0]; -} __attribute__((packed)); - -struct small_data { - uint32_t type; - uint16_t name_size; - uint16_t data_size; - char name[0]; -} __attribute__((packed)); - -struct bplustree_header { - uint32_t magic; - uint32_t node_size; - uint32_t max_number_of_levels; - uint32_t data_type; - int64_t root_node_pointer; - int64_t free_node_pointer; - int64_t maximum_size; -} __attribute__((packed)); - -struct bplustree_node { - int64_t left_link; - int64_t right_link; - int64_t overflow_link; - uint16_t all_key_count; - uint16_t all_key_length; - char name[0]; -} __attribute__((packed)); - -unsigned char *get_block_run(blkid_probe pr, const struct befs_super_block *bs, - const struct block_run *br, int fs_le) -{ - return blkid_probe_get_buffer(pr, - ((blkid_loff_t) FS32_TO_CPU(br->allocation_group, fs_le) - << FS32_TO_CPU(bs->ag_shift, fs_le) - << FS32_TO_CPU(bs->block_shift, fs_le)) - + ((blkid_loff_t) FS16_TO_CPU(br->start, fs_le) - << FS32_TO_CPU(bs->block_shift, fs_le)), - (blkid_loff_t) FS16_TO_CPU(br->len, fs_le) - << FS32_TO_CPU(bs->block_shift, fs_le)); -} - -unsigned char *get_custom_block_run(blkid_probe pr, - const struct befs_super_block *bs, - const struct block_run *br, - int64_t offset, uint32_t length, int fs_le) -{ - if (offset + length > (int64_t) FS16_TO_CPU(br->len, fs_le) - << FS32_TO_CPU(bs->block_shift, fs_le)) - return NULL; - - return blkid_probe_get_buffer(pr, - ((blkid_loff_t) FS32_TO_CPU(br->allocation_group, fs_le) - << FS32_TO_CPU(bs->ag_shift, fs_le) - << FS32_TO_CPU(bs->block_shift, fs_le)) - + ((blkid_loff_t) FS16_TO_CPU(br->start, fs_le) - << FS32_TO_CPU(bs->block_shift, fs_le)) - + offset, - length); -} - -unsigned char *get_tree_node(blkid_probe pr, const struct befs_super_block *bs, - const struct data_stream *ds, - int64_t start, uint32_t length, int fs_le) -{ - if (start < FS64_TO_CPU(ds->max_direct_range, fs_le)) { - int64_t br_len; - int i; - - for (i = 0; i < NUM_DIRECT_BLOCKS; i++) { - br_len = (int64_t) FS16_TO_CPU(ds->direct[i].len, fs_le) - << FS32_TO_CPU(bs->block_shift, fs_le); - if (start < br_len) - return get_custom_block_run(pr, bs, - &ds->direct[i], - start, length, fs_le); - else - start -= br_len; - } - } else if (start < FS64_TO_CPU(ds->max_indirect_range, fs_le)) { - struct block_run *br; - int64_t max_br, br_len, i; - - start -= FS64_TO_CPU(ds->max_direct_range, fs_le); - max_br = ((int64_t) FS16_TO_CPU(ds->indirect.len, fs_le) - << FS32_TO_CPU(bs->block_shift, fs_le)) - / sizeof(struct block_run); - - br = (struct block_run *) get_block_run(pr, bs, &ds->indirect, - fs_le); - if (!br) - return NULL; - - for (i = 0; i < max_br; i++) { - br_len = (int64_t) FS16_TO_CPU(br[i].len, fs_le) - << FS32_TO_CPU(bs->block_shift, fs_le); - if (start < br_len) - return get_custom_block_run(pr, bs, &br[i], - start, length, fs_le); - else - start -= br_len; - } - } else if (start < FS64_TO_CPU(ds->max_double_indirect_range, fs_le)) { - struct block_run *br; - int64_t di_br_size, br_per_di_br, di_index, i_index; - - start -= FS64_TO_CPU(ds->max_indirect_range, fs_le); - di_br_size = (int64_t) FS16_TO_CPU(ds->double_indirect.len, - fs_le) << FS32_TO_CPU(bs->block_shift, fs_le); - br_per_di_br = di_br_size / sizeof(struct block_run); - di_index = start / (br_per_di_br * di_br_size); - i_index = (start % (br_per_di_br * di_br_size)) / di_br_size; - start = (start % (br_per_di_br * di_br_size)) % di_br_size; - - br = (struct block_run *) get_block_run(pr, bs, - &ds->double_indirect, fs_le); - if (!br) - return NULL; - - br = (struct block_run *) get_block_run(pr, bs, &br[di_index], - fs_le); - if (!br) - return NULL; - - return get_custom_block_run(pr, bs, &br[i_index], start, length, - fs_le); - } - return NULL; -} - -int32_t compare_keys(const char keys1[], uint16_t keylengths1[], int32_t index, - const char *key2, uint16_t keylength2, int fs_le) -{ - const char *key1; - uint16_t keylength1; - int32_t result; - - key1 = &keys1[index == 0 ? 0 : FS16_TO_CPU(keylengths1[index - 1], - fs_le)]; - keylength1 = FS16_TO_CPU(keylengths1[index], fs_le) - - (index == 0 ? 0 : FS16_TO_CPU(keylengths1[index - 1], - fs_le)); - - result = strncmp(key1, key2, min(keylength1, keylength2)); - - if (result == 0) - return keylength1 - keylength2; - - return result; -} - -int64_t get_key_value(blkid_probe pr, const struct befs_super_block *bs, - const struct befs_inode *bi, const char *key, int fs_le) -{ - struct bplustree_header *bh; - struct bplustree_node *bn; - uint16_t *keylengths; - int64_t *values; - int64_t node_pointer; - int32_t first, last, mid, cmp; - - bh = (struct bplustree_header *) get_tree_node(pr, bs, &bi->data, 0, - sizeof(struct bplustree_header), fs_le); - if (!bh) - return -1; - - if (FS32_TO_CPU(bh->magic, fs_le) != BPLUSTREE_MAGIC) - return -1; - - node_pointer = FS64_TO_CPU(bh->root_node_pointer, fs_le); - - do { - bn = (struct bplustree_node *) get_tree_node(pr, bs, &bi->data, - node_pointer, FS32_TO_CPU(bh->node_size, fs_le), fs_le); - if (!bn) - return -1; - - keylengths = (uint16_t *) ((uint8_t *) bn - + ((sizeof(struct bplustree_node) - + FS16_TO_CPU(bn->all_key_length, fs_le) - + sizeof(int64_t) - 1) - & ~(sizeof(int64_t) - 1))); - values = (int64_t *) ((uint8_t *) keylengths - + FS16_TO_CPU(bn->all_key_count, fs_le) - * sizeof(uint16_t)); - first = 0; - mid = 0; - last = FS16_TO_CPU(bn->all_key_count, fs_le) - 1; - - cmp = compare_keys(bn->name, keylengths, last, key, strlen(key), - fs_le); - if (cmp == 0) { - if (FS64_TO_CPU(bn->overflow_link, fs_le) - == BPLUSTREE_NULL) - return FS64_TO_CPU(values[last], fs_le); - else - node_pointer = FS64_TO_CPU(values[last], fs_le); - } else if (cmp < 0) - node_pointer = FS64_TO_CPU(bn->overflow_link, fs_le); - else { - while (first <= last) { - mid = (first + last) / 2; - - cmp = compare_keys(bn->name, keylengths, mid, - key, strlen(key), fs_le); - if (cmp == 0) { - if (FS64_TO_CPU(bn->overflow_link, - fs_le) == BPLUSTREE_NULL) - return FS64_TO_CPU(values[mid], - fs_le); - else - break; - } else if (cmp < 0) - first = mid + 1; - else - last = mid - 1; - } - if (cmp < 0) - node_pointer = FS64_TO_CPU(values[mid + 1], - fs_le); - else - node_pointer = FS64_TO_CPU(values[mid], fs_le); - } - } while (FS64_TO_CPU(bn->overflow_link, fs_le) != BPLUSTREE_NULL); - return 0; -} - -int get_uuid(blkid_probe pr, const struct befs_super_block *bs, - uint64_t * const uuid, int fs_le) -{ - struct befs_inode *bi; - struct small_data *sd; - - bi = (struct befs_inode *) get_block_run(pr, bs, &bs->root_dir, fs_le); - if (!bi) - return -1; - - if (FS32_TO_CPU(bi->magic1, fs_le) != INODE_MAGIC1) - return -1; - - sd = (struct small_data *) bi->small_data; - - do { - if (FS32_TO_CPU(sd->type, fs_le) == B_UINT64_TYPE - && FS16_TO_CPU(sd->name_size, fs_le) == strlen(KEY_NAME) - && FS16_TO_CPU(sd->data_size, fs_le) == KEY_SIZE - && strcmp(sd->name, KEY_NAME) == 0) { - *uuid = *(uint64_t *) ((uint8_t *) sd->name - + FS16_TO_CPU(sd->name_size, fs_le) - + 3); - break; - } else if (FS32_TO_CPU(sd->type, fs_le) == 0 - && FS16_TO_CPU(sd->name_size, fs_le) == 0 - && FS16_TO_CPU(sd->data_size, fs_le) == 0) - break; - - sd = (struct small_data *) ((uint8_t *) sd - + sizeof(struct small_data) - + FS16_TO_CPU(sd->name_size, fs_le) + 3 - + FS16_TO_CPU(sd->data_size, fs_le) + 1); - - } while ((intptr_t) sd < (intptr_t) bi - + FS32_TO_CPU(bi->inode_size, fs_le) - - sizeof(struct small_data)); - if (*uuid == 0 - && (FS32_TO_CPU(bi->attributes.allocation_group, fs_le) != 0 - || FS16_TO_CPU(bi->attributes.start, fs_le) != 0 - || FS16_TO_CPU(bi->attributes.len, fs_le) != 0)) { - int64_t value; - - bi = (struct befs_inode *) get_block_run(pr, bs, - &bi->attributes, fs_le); - if (!bi) - return -1; - - if (FS32_TO_CPU(bi->magic1, fs_le) != INODE_MAGIC1) - return -1; - - value = get_key_value(pr, bs, bi, KEY_NAME, fs_le); - - if (value < 0) - return value; - else if (value > 0) { - bi = (struct befs_inode *) blkid_probe_get_buffer(pr, - value << FS32_TO_CPU(bs->block_shift, fs_le), - FS32_TO_CPU(bs->block_size, fs_le)); - if (!bi) - return -1; - - if (FS32_TO_CPU(bi->magic1, fs_le) != INODE_MAGIC1) - return -1; - - if (FS32_TO_CPU(bi->type, fs_le) == B_UINT64_TYPE - && FS64_TO_CPU(bi->data.size, fs_le) == KEY_SIZE - && FS16_TO_CPU(bi->data.direct[0].len, fs_le) - == 1) { - uint64_t *attr_data; - - attr_data = (uint64_t *) get_block_run(pr, bs, - &bi->data.direct[0], fs_le); - if (!attr_data) - return -1; - - *uuid = *attr_data; - } - } - } - return 0; -} - -static int probe_befs(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct befs_super_block *bs; - const char *version = NULL; - uint64_t volume_id = 0; - int fs_le, ret; - - bs = (struct befs_super_block *) blkid_probe_get_buffer(pr, - mag->sboff - B_OS_NAME_LENGTH, - sizeof(struct befs_super_block)); - if (!bs) - return -1; - - if (le32_to_cpu(bs->magic1) == SUPER_BLOCK_MAGIC1 - && le32_to_cpu(bs->magic2) == SUPER_BLOCK_MAGIC2 - && le32_to_cpu(bs->magic3) == SUPER_BLOCK_MAGIC3 - && le32_to_cpu(bs->fs_byte_order) == SUPER_BLOCK_FS_ENDIAN) { - fs_le = 1; - version = "little-endian"; - } else if (be32_to_cpu(bs->magic1) == SUPER_BLOCK_MAGIC1 - && be32_to_cpu(bs->magic2) == SUPER_BLOCK_MAGIC2 - && be32_to_cpu(bs->magic3) == SUPER_BLOCK_MAGIC3 - && be32_to_cpu(bs->fs_byte_order) == SUPER_BLOCK_FS_ENDIAN) { - fs_le = 0; - version = "big-endian"; - } else - return -1; - - ret = get_uuid(pr, bs, &volume_id, fs_le); - - if (ret < 0) - return ret; - - /* - * all checks pass, set LABEL, VERSION and UUID - */ - if (strlen(bs->name)) - blkid_probe_set_label(pr, (unsigned char *) bs->name, - sizeof(bs->name)); - if (version) - blkid_probe_set_version(pr, version); - - if (volume_id) - blkid_probe_sprintf_uuid(pr, (unsigned char *) &volume_id, - sizeof(volume_id), "%016" PRIx64, - FS64_TO_CPU(volume_id, fs_le)); - return 0; -} - -const struct blkid_idinfo befs_idinfo = -{ - .name = "befs", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_befs, - .minsz = 1024 * 1440, - .magics = { - { .magic = "BFS1", .len = 4, .sboff = B_OS_NAME_LENGTH }, - { .magic = "1SFB", .len = 4, .sboff = B_OS_NAME_LENGTH }, - { .magic = "BFS1", .len = 4, .sboff = 0x200 + - B_OS_NAME_LENGTH }, - { .magic = "1SFB", .len = 4, .sboff = 0x200 + - B_OS_NAME_LENGTH }, - { NULL } - } -}; diff --git a/shlibs/blkid/src/superblocks/bfs.c b/shlibs/blkid/src/superblocks/bfs.c deleted file mode 100644 index 8a34c583..00000000 --- a/shlibs/blkid/src/superblocks/bfs.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2009 Red Hat, Inc. - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -#include "superblocks.h" - -/* - * BFS actually has two different labels in the superblock, each - * of them only 6 bytes long. Until we find out what their use - * we just ignore them. - */ -const struct blkid_idinfo bfs_idinfo = -{ - .name = "bfs", - .usage = BLKID_USAGE_FILESYSTEM, - .magics = { - { .magic = "\xce\xfa\xad\x1b", .len = 4 }, - { NULL } - } -}; diff --git a/shlibs/blkid/src/superblocks/btrfs.c b/shlibs/blkid/src/superblocks/btrfs.c deleted file mode 100644 index 51bbadc7..00000000 --- a/shlibs/blkid/src/superblocks/btrfs.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include - -#include "superblocks.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]; - } __attribute__ ((__packed__)) dev_item; - uint8_t label[256]; -} __attribute__ ((__packed__)); - -static int probe_btrfs(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct btrfs_super_block *bfs; - - bfs = blkid_probe_get_sb(pr, mag, struct btrfs_super_block); - if (!bfs) - return -1; - - if (*bfs->label) - blkid_probe_set_label(pr, - (unsigned char *) bfs->label, - sizeof(bfs->label)); - - blkid_probe_set_uuid(pr, bfs->fsid); - blkid_probe_set_uuid_as(pr, bfs->dev_item.uuid, "UUID_SUB"); - - return 0; -} - -const struct blkid_idinfo btrfs_idinfo = -{ - .name = "btrfs", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_btrfs, - .minsz = 256 * 1024 * 1024, - .magics = - { - { .magic = "_BHRfS_M", .len = 8, .kboff = 64, .sboff = 0x40 }, - { NULL } - } -}; - diff --git a/shlibs/blkid/src/superblocks/cramfs.c b/shlibs/blkid/src/superblocks/cramfs.c deleted file mode 100644 index b58ed08c..00000000 --- a/shlibs/blkid/src/superblocks/cramfs.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 1999 by Andries Brouwer - * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o - * Copyright (C) 2001 by Andreas Dilger - * Copyright (C) 2004 Kay Sievers - * Copyright (C) 2008 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -#include -#include -#include -#include -#include - -#include "superblocks.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; - } __attribute__((packed)) info; - uint8_t name[16]; -} __attribute__((packed)); - -static int probe_cramfs(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct cramfs_super *cs; - - cs = blkid_probe_get_sb(pr, mag, struct cramfs_super); - if (!cs) - return -1; - - blkid_probe_set_label(pr, cs->name, sizeof(cs->name)); - return 0; -} - -const struct blkid_idinfo cramfs_idinfo = -{ - .name = "cramfs", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_cramfs, - .magics = - { - { "\x45\x3d\xcd\x28", 4, 0, 0 }, - { "\x28\xcd\x3d\x45", 4, 0, 0 }, - { NULL } - } -}; - - diff --git a/shlibs/blkid/src/superblocks/ddf_raid.c b/shlibs/blkid/src/superblocks/ddf_raid.c deleted file mode 100644 index c0ba3351..00000000 --- a/shlibs/blkid/src/superblocks/ddf_raid.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2008 Karel Zak - * - * Inspired by libvolume_id by - * Kay Sievers - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include - -#include "superblocks.h" - -/* http://www.snia.org/standards/home */ -#define DDF_GUID_LENGTH 24 -#define DDF_REV_LENGTH 8 -#define DDF_MAGIC 0xDE11DE11 - - -struct ddf_header { - uint32_t signature; - uint32_t crc; - uint8_t guid[DDF_GUID_LENGTH]; - char ddf_rev[8]; /* 01.02.00 */ - uint32_t seq; /* starts at '1' */ - uint32_t timestamp; - uint8_t openflag; - uint8_t foreignflag; - uint8_t enforcegroups; - uint8_t pad0; /* 0xff */ - uint8_t pad1[12]; /* 12 * 0xff */ - /* 64 bytes so far */ - uint8_t header_ext[32]; /* reserved: fill with 0xff */ - uint64_t primary_lba; - uint64_t secondary_lba; - uint8_t type; - uint8_t pad2[3]; /* 0xff */ - uint32_t workspace_len; /* sectors for vendor space - - * at least 32768(sectors) */ - uint64_t workspace_lba; - uint16_t max_pd_entries; /* one of 15, 63, 255, 1023, 4095 */ - uint16_t max_vd_entries; /* 2^(4,6,8,10,12)-1 : i.e. as above */ - uint16_t max_partitions; /* i.e. max num of configuration - record entries per disk */ - uint16_t config_record_len; /* 1 +ROUNDUP(max_primary_element_entries - *12/512) */ - uint16_t max_primary_element_entries; /* 16, 64, 256, 1024, or 4096 */ - uint8_t pad3[54]; /* 0xff */ - /* 192 bytes so far */ - uint32_t controller_section_offset; - uint32_t controller_section_length; - uint32_t phys_section_offset; - uint32_t phys_section_length; - uint32_t virt_section_offset; - uint32_t virt_section_length; - uint32_t config_section_offset; - uint32_t config_section_length; - uint32_t data_section_offset; - uint32_t data_section_length; - uint32_t bbm_section_offset; - uint32_t bbm_section_length; - uint32_t diag_space_offset; - uint32_t diag_space_length; - uint32_t vendor_offset; - uint32_t vendor_length; - /* 256 bytes so far */ - uint8_t pad4[256]; /* 0xff */ -} __attribute__((packed)); - -static int probe_ddf(blkid_probe pr, const struct blkid_idmag *mag) -{ - int hdrs[] = { 1, 257 }; - int i; - struct ddf_header *ddf = NULL; - char version[DDF_REV_LENGTH + 1]; - uint64_t off, lba; - - if (pr->size < 0x30000) - return -1; - - for (i = 0; i < ARRAY_SIZE(hdrs); i++) { - off = ((pr->size / 0x200) - hdrs[i]) * 0x200; - - ddf = (struct ddf_header *) blkid_probe_get_buffer(pr, - off, - sizeof(struct ddf_header)); - if (!ddf) - return -1; - - if (ddf->signature == cpu_to_be32(DDF_MAGIC) || - ddf->signature == cpu_to_le32(DDF_MAGIC)) - break; - ddf = NULL; - } - - if (!ddf) - return -1; - - lba = ddf->signature == cpu_to_be32(DDF_MAGIC) ? - be64_to_cpu(ddf->primary_lba) : - le64_to_cpu(ddf->primary_lba); - - if (lba > 0) { - /* check primary header */ - unsigned char *buf; - - buf = blkid_probe_get_buffer(pr, - lba << 9, sizeof(ddf->signature)); - if (!buf || memcmp(buf, &ddf->signature, 4)) - return -1; - } - - blkid_probe_strncpy_uuid(pr, ddf->guid, sizeof(ddf->guid)); - - memcpy(version, ddf->ddf_rev, sizeof(ddf->ddf_rev)); - *(version + sizeof(ddf->ddf_rev)) = '\0'; - - if (blkid_probe_set_version(pr, version) != 0) - return -1; - if (blkid_probe_set_magic(pr, off, - sizeof(ddf->signature), - (unsigned char *) &ddf->signature)) - return -1; - return 0; -} - -const struct blkid_idinfo ddfraid_idinfo = { - .name = "ddf_raid_member", - .usage = BLKID_USAGE_RAID, - .probefunc = probe_ddf, - .magics = BLKID_NONE_MAGIC -}; - - diff --git a/shlibs/blkid/src/superblocks/drbd.c b/shlibs/blkid/src/superblocks/drbd.c deleted file mode 100644 index 3490948d..00000000 --- a/shlibs/blkid/src/superblocks/drbd.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2009 by Bastian Friedrich - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * - * defines, structs taken from drbd source; file names represent drbd source - * files. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "superblocks.h" - -/* - * drbd/linux/drbd.h - */ -#define DRBD_MAGIC 0x83740267 - -/* - * user/drbdmeta.c - * We only support v08 for now - */ -#define DRBD_MD_MAGIC_08 (DRBD_MAGIC+4) - -/* - * drbd/linux/drbd.h - */ -enum drbd_uuid_index { - UI_CURRENT, - UI_BITMAP, - UI_HISTORY_START, - UI_HISTORY_END, - UI_SIZE, /* nl-packet: number of dirty bits */ - UI_FLAGS, /* nl-packet: flags */ - UI_EXTENDED_SIZE /* Everything. */ -}; - -/* - * user/drbdmeta.c - * Minor modifications wrt. types - */ -struct md_on_disk_08 { - uint64_t la_sect; /* last agreed size. */ - uint64_t uuid[UI_SIZE]; /* UUIDs */ - uint64_t device_uuid; - uint64_t reserved_u64_1; - uint32_t flags; - uint32_t magic; - uint32_t md_size_sect; - int32_t al_offset; /* signed sector offset to this block */ - uint32_t al_nr_extents; /* important for restoring the AL */ - int32_t bm_offset; /* signed sector offset to the bitmap, from here */ - uint32_t bm_bytes_per_bit; - uint32_t reserved_u32[4]; - - char reserved[8 * 512 - (8*(UI_SIZE+3)+4*11)]; -}; - - -static int probe_drbd(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct md_on_disk_08 *md; - off_t off; - - off = pr->size - sizeof(*md); - - /* Small devices cannot be drbd (?) */ - if (pr->size < 0x10000) - return -1; - - md = (struct md_on_disk_08 *) - blkid_probe_get_buffer(pr, - off, - sizeof(struct md_on_disk_08)); - if (!md) - return -1; - - if (be32_to_cpu(md->magic) != DRBD_MD_MAGIC_08) - return -1; - - /* - * DRBD does not have "real" uuids; the following resembles DRBD's - * notion of uuids (64 bit, see struct above) - */ - blkid_probe_sprintf_uuid(pr, - (unsigned char *) &md->device_uuid, sizeof(md->device_uuid), - "%" PRIx64, be64_to_cpu(md->device_uuid)); - - blkid_probe_set_version(pr, "v08"); - - if (blkid_probe_set_magic(pr, - off + offsetof(struct md_on_disk_08, magic), - sizeof(md->magic), - (unsigned char *) &md->magic)) - return -1; - - return 0; -} - -const struct blkid_idinfo drbd_idinfo = -{ - .name = "drbd", - .usage = BLKID_USAGE_RAID, - .probefunc = probe_drbd, - .magics = BLKID_NONE_MAGIC -}; - diff --git a/shlibs/blkid/src/superblocks/exfat.c b/shlibs/blkid/src/superblocks/exfat.c deleted file mode 100644 index bada3a83..00000000 --- a/shlibs/blkid/src/superblocks/exfat.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (C) 2010 Andrew Nayenko - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include "superblocks.h" - -struct exfat_super_block { - uint8_t jump[3]; - uint8_t oem_name[8]; - uint8_t __unused1[53]; - uint64_t block_start; - uint64_t block_count; - uint32_t fat_block_start; - uint32_t fat_block_count; - uint32_t cluster_block_start; - uint32_t cluster_count; - uint32_t rootdir_cluster; - uint8_t volume_serial[4]; - struct { - uint8_t minor; - uint8_t major; - } version; - uint16_t volume_state; - uint8_t block_bits; - uint8_t bpc_bits; - uint8_t fat_count; - uint8_t drive_no; - uint8_t allocated_percent; -} __attribute__((__packed__)); - -struct exfat_entry_label { - uint8_t type; - uint8_t length; - uint8_t name[30]; -} __attribute__((__packed__)); - -#define BLOCK_SIZE(sb) (1 << (sb)->block_bits) -#define CLUSTER_SIZE(sb) (BLOCK_SIZE(sb) << (sb)->bpc_bits) -#define EXFAT_FIRST_DATA_CLUSTER 2 -#define EXFAT_LAST_DATA_CLUSTER 0xffffff6 -#define EXFAT_ENTRY_SIZE 32 - -#define EXFAT_ENTRY_EOD 0x00 -#define EXFAT_ENTRY_LABEL 0x83 - -static blkid_loff_t block_to_offset(const struct exfat_super_block *sb, - blkid_loff_t block) -{ - return (blkid_loff_t) block << sb->block_bits; -} - -static blkid_loff_t cluster_to_block(const struct exfat_super_block *sb, - uint32_t cluster) -{ - return le32_to_cpu(sb->cluster_block_start) + - ((blkid_loff_t) (cluster - EXFAT_FIRST_DATA_CLUSTER) - << sb->bpc_bits); -} - -static blkid_loff_t cluster_to_offset(const struct exfat_super_block *sb, - uint32_t cluster) -{ - return block_to_offset(sb, cluster_to_block(sb, cluster)); -} - -static uint32_t next_cluster(blkid_probe pr, - const struct exfat_super_block *sb, uint32_t cluster) -{ - uint32_t *next; - blkid_loff_t fat_offset; - - fat_offset = block_to_offset(sb, le32_to_cpu(sb->fat_block_start)) - + (blkid_loff_t) cluster * sizeof(cluster); - next = (uint32_t *) blkid_probe_get_buffer(pr, fat_offset, - sizeof(uint32_t)); - if (!next) - return 0; - return le32_to_cpu(*next); -} - -static struct exfat_entry_label *find_label(blkid_probe pr, - const struct exfat_super_block *sb) -{ - uint32_t cluster = le32_to_cpu(sb->rootdir_cluster); - blkid_loff_t offset = cluster_to_offset(sb, cluster); - uint8_t *entry; - - for (;;) { - entry = (uint8_t *) blkid_probe_get_buffer(pr, offset, - EXFAT_ENTRY_SIZE); - if (!entry) - return NULL; - if (entry[0] == EXFAT_ENTRY_EOD) - return NULL; - if (entry[0] == EXFAT_ENTRY_LABEL) - return (struct exfat_entry_label *) entry; - offset += EXFAT_ENTRY_SIZE; - if (offset % CLUSTER_SIZE(sb) == 0) { - cluster = next_cluster(pr, sb, cluster); - if (cluster < EXFAT_FIRST_DATA_CLUSTER) - return NULL; - if (cluster > EXFAT_LAST_DATA_CLUSTER) - return NULL; - offset = cluster_to_offset(sb, cluster); - } - } -} - -static int probe_exfat(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct exfat_super_block *sb; - struct exfat_entry_label *label; - - sb = blkid_probe_get_sb(pr, mag, struct exfat_super_block); - if (!sb) - return -1; - - label = find_label(pr, sb); - if (label) - blkid_probe_set_utf8label(pr, label->name, - min(label->length * 2, 30), BLKID_ENC_UTF16LE); - - blkid_probe_sprintf_uuid(pr, sb->volume_serial, 4, - "%02hhX%02hhX-%02hhX%02hhX", - sb->volume_serial[3], sb->volume_serial[2], - sb->volume_serial[1], sb->volume_serial[0]); - - blkid_probe_sprintf_version(pr, "%hu.%hu", - sb->version.major, sb->version.minor); - - return 0; -} - -const struct blkid_idinfo exfat_idinfo = -{ - .name = "exfat", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_exfat, - .magics = - { - { .magic = "EXFAT ", .len = 8, .sboff = 3 }, - { NULL } - } -}; diff --git a/shlibs/blkid/src/superblocks/ext.c b/shlibs/blkid/src/superblocks/ext.c deleted file mode 100644 index 6dfe5283..00000000 --- a/shlibs/blkid/src/superblocks/ext.c +++ /dev/null @@ -1,526 +0,0 @@ -/* - * Copyright (C) 1999, 2001 by Andries Brouwer - * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o - * Copyright (C) 2008 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include -#include -#include -#ifdef __linux__ -#include -#endif -#include - -#include "linux_version.h" -#include "superblocks.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_dummy3[7]; - unsigned char s_magic[2]; - 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; - unsigned char s_uuid[16]; - char s_volume_name[16]; - char 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; - uint16_t s_raid_stride; - uint16_t s_mmp_interval; - uint64_t s_mmp_block; - uint32_t s_raid_stripe_width; - uint32_t s_reserved[163]; -} __attribute__((packed)); - -/* magic string */ -#define EXT_SB_MAGIC "\123\357" -/* supper block offset */ -#define EXT_SB_OFF 0x400 -/* supper block offset in kB */ -#define EXT_SB_KBOFF (EXT_SB_OFF >> 10) -/* magic string offset within super block */ -#define EXT_MAG_OFF 0x38 - - - -/* for s_flags */ -#define EXT2_FLAGS_TEST_FILESYS 0x0004 - -/* for s_feature_compat */ -#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004 - -/* for s_feature_ro_compat */ -#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 EXT4_FEATURE_RO_COMPAT_HUGE_FILE 0x0008 -#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010 -#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020 -#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040 - -/* for s_feature_incompat */ -#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002 -#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 -#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 -#define EXT2_FEATURE_INCOMPAT_META_BG 0x0010 -#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */ -#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 -#define EXT4_FEATURE_INCOMPAT_MMP 0x0100 -#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200 - -#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_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \ - EXT2_FEATURE_INCOMPAT_META_BG) -#define EXT2_FEATURE_INCOMPAT_UNSUPPORTED ~EXT2_FEATURE_INCOMPAT_SUPP -#define EXT2_FEATURE_RO_COMPAT_UNSUPPORTED ~EXT2_FEATURE_RO_COMPAT_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_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 EXT3_FEATURE_RO_COMPAT_UNSUPPORTED ~EXT3_FEATURE_RO_COMPAT_SUPP - -/* - * Check to see if a filesystem is in /proc/filesystems. - * Returns 1 if found, 0 if not - */ -static int fs_proc_check(const char *fs_name) -{ - FILE *f; - char buf[80], *cp, *t; - - f = fopen("/proc/filesystems", "r"); - if (!f) - return 0; - while (!feof(f)) { - if (!fgets(buf, sizeof(buf), f)) - break; - cp = buf; - if (!isspace(*cp)) { - while (*cp && !isspace(*cp)) - cp++; - } - while (*cp && isspace(*cp)) - cp++; - if ((t = strchr(cp, '\n')) != NULL) - *t = 0; - if ((t = strchr(cp, '\t')) != NULL) - *t = 0; - if ((t = strchr(cp, ' ')) != NULL) - *t = 0; - if (!strcmp(fs_name, cp)) { - fclose(f); - return 1; - } - } - fclose(f); - return (0); -} - -/* - * Check to see if a filesystem is available as a module - * Returns 1 if found, 0 if not - */ -static int check_for_modules(const char *fs_name) -{ -#ifdef __linux__ - struct utsname uts; - FILE *f; - char buf[1024], *cp; - int namesz; - - if (uname(&uts)) - return 0; - snprintf(buf, sizeof(buf), "/lib/modules/%s/modules.dep", uts.release); - - f = fopen(buf, "r"); - if (!f) - return 0; - - namesz = strlen(fs_name); - - while (!feof(f)) { - if (!fgets(buf, sizeof(buf), f)) - break; - if ((cp = strchr(buf, ':')) != NULL) - *cp = 0; - else - continue; - if ((cp = strrchr(buf, '/')) == NULL) - continue; - cp++; - - if (!strncmp(cp, fs_name, namesz) && - (!strcmp(cp + namesz, ".ko") || - !strcmp(cp + namesz, ".ko.gz"))) { - fclose(f); - return 1; - } - } - fclose(f); -#endif /* __linux__ */ - return 0; -} - -/* - * Starting in 2.6.29, ext4 can be used to support filesystems - * without a journal. - */ -#define EXT4_SUPPORTS_EXT2 KERNEL_VERSION(2, 6, 29) - -static int system_supports_ext2(void) -{ - static time_t last_check = 0; - static int ret = -1; - time_t now = time(0); - - if (ret != -1 || (now - last_check) < 5) - return ret; - last_check = now; - ret = (fs_proc_check("ext2") || check_for_modules("ext2")); - return ret; -} - -static int system_supports_ext4(void) -{ - static time_t last_check = 0; - static int ret = -1; - time_t now = time(0); - - if (ret != -1 || (now - last_check) < 5) - return ret; - last_check = now; - ret = (fs_proc_check("ext4") || check_for_modules("ext4")); - return ret; -} - -static int system_supports_ext4dev(void) -{ - static time_t last_check = 0; - static int ret = -1; - time_t now = time(0); - - if (ret != -1 || (now - last_check) < 5) - return ret; - last_check = now; - ret = (fs_proc_check("ext4dev") || check_for_modules("ext4dev")); - return ret; -} -/* - * reads superblock and returns: - * fc = feature_compat - * fi = feature_incompat - * frc = feature_ro_compat - */ -static struct ext2_super_block *ext_get_super( - blkid_probe pr, uint32_t *fc, uint32_t *fi, uint32_t *frc) -{ - struct ext2_super_block *es; - - es = (struct ext2_super_block *) - blkid_probe_get_buffer(pr, EXT_SB_OFF, 0x200); - if (!es) - return NULL; - if (fc) - *fc = le32_to_cpu(es->s_feature_compat); - if (fi) - *fi = le32_to_cpu(es->s_feature_incompat); - if (frc) - *frc = le32_to_cpu(es->s_feature_ro_compat); - - return es; -} - -static void ext_get_info(blkid_probe pr, int ver, struct ext2_super_block *es) -{ - struct blkid_chain *chn = blkid_probe_get_chain(pr); - - DBG(DEBUG_PROBE, printf("ext2_sb.compat = %08X:%08X:%08X\n", - le32_to_cpu(es->s_feature_compat), - le32_to_cpu(es->s_feature_incompat), - le32_to_cpu(es->s_feature_ro_compat))); - - if (strlen(es->s_volume_name)) - blkid_probe_set_label(pr, (unsigned char *) es->s_volume_name, - sizeof(es->s_volume_name)); - blkid_probe_set_uuid(pr, es->s_uuid); - - if (le32_to_cpu(es->s_feature_compat) & EXT3_FEATURE_COMPAT_HAS_JOURNAL) - blkid_probe_set_uuid_as(pr, es->s_journal_uuid, "EXT_JOURNAL"); - - if (ver != 2 && (chn->flags & BLKID_SUBLKS_SECTYPE) && - ((le32_to_cpu(es->s_feature_incompat) & EXT2_FEATURE_INCOMPAT_UNSUPPORTED) == 0)) - blkid_probe_set_value(pr, "SEC_TYPE", - (unsigned char *) "ext2", - sizeof("ext2")); - - blkid_probe_sprintf_version(pr, "%u.%u", - le32_to_cpu(es->s_rev_level), - le16_to_cpu(es->s_minor_rev_level)); -} - - -static int probe_jbd(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct ext2_super_block *es; - uint32_t fi; - - es = ext_get_super(pr, NULL, &fi, NULL); - if (!es) - return -BLKID_ERR_PARAM; - if (!(fi & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) - return -BLKID_ERR_PARAM; - - ext_get_info(pr, 2, es); - return 0; -} - -static int probe_ext2(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct ext2_super_block *es; - uint32_t fc, frc, fi; - - es = ext_get_super(pr, &fc, &fi, &frc); - if (!es) - return -BLKID_ERR_PARAM; - - /* Distinguish between ext3 and ext2 */ - if (fc & EXT3_FEATURE_COMPAT_HAS_JOURNAL) - return -BLKID_ERR_PARAM; - - /* Any features which ext2 doesn't understand */ - if ((frc & EXT2_FEATURE_RO_COMPAT_UNSUPPORTED) || - (fi & EXT2_FEATURE_INCOMPAT_UNSUPPORTED)) - return -BLKID_ERR_PARAM; - - /* - * If ext2 is not present, but ext4 or ext4dev are, then - * disclaim we are ext2 - */ - if (!system_supports_ext2() && - (system_supports_ext4() || system_supports_ext4dev()) && - get_linux_version() >= EXT4_SUPPORTS_EXT2) - return -BLKID_ERR_PARAM; - - ext_get_info(pr, 2, es); - return 0; -} - -static int probe_ext3(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct ext2_super_block *es; - uint32_t fc, frc, fi; - - es = ext_get_super(pr, &fc, &fi, &frc); - if (!es) - return -BLKID_ERR_PARAM; - - /* ext3 requires journal */ - if (!(fc & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) - return -BLKID_ERR_PARAM; - - /* Any features which ext3 doesn't understand */ - if ((frc & EXT3_FEATURE_RO_COMPAT_UNSUPPORTED) || - (fi & EXT3_FEATURE_INCOMPAT_UNSUPPORTED)) - return -BLKID_ERR_PARAM; - - ext_get_info(pr, 3, es); - return 0; -} - - -static int probe_ext4dev(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct ext2_super_block *es; - uint32_t fc, frc, fi; - - es = ext_get_super(pr, &fc, &fi, &frc); - if (!es) - return -BLKID_ERR_PARAM; - - /* Distinguish from jbd */ - if (fi & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) - return -BLKID_ERR_PARAM; - - /* - * If the filesystem does not have a journal and ext2 and ext4 - * is not present, then force this to be detected as an - * ext4dev filesystem. - */ - if (!(fc & EXT3_FEATURE_COMPAT_HAS_JOURNAL) && - !system_supports_ext2() && !system_supports_ext4() && - system_supports_ext4dev() && - get_linux_version() >= EXT4_SUPPORTS_EXT2) - goto force_ext4dev; - - /* - * If the filesystem is marked as OK for use by in-development - * filesystem code, but ext4dev is not supported, and ext4 is, - * then don't call ourselves ext4dev, since we should be - * detected as ext4 in that case. - * - * If the filesystem is marked as in use by production - * filesystem, then it can only be used by ext4 and NOT by - * ext4dev, so always disclaim we are ext4dev in that case. - */ - if (le32_to_cpu(es->s_flags) & EXT2_FLAGS_TEST_FILESYS) { - if (!system_supports_ext4dev() && system_supports_ext4()) - return -BLKID_ERR_PARAM; - } else - return -BLKID_ERR_PARAM; - -force_ext4dev: - ext_get_info(pr, 4, es); - return 0; -} - -static int probe_ext4(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct ext2_super_block *es; - uint32_t fc, frc, fi; - - es = ext_get_super(pr, &fc, &fi, &frc); - if (!es) - return -1; - - /* Distinguish from jbd */ - if (fi & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) - return -BLKID_ERR_PARAM; - - /* - * If the filesystem does not have a journal and ext2 is not - * present, then force this to be detected as an ext2 - * filesystem. - */ - if (!(fc & EXT3_FEATURE_COMPAT_HAS_JOURNAL) && - !system_supports_ext2() && system_supports_ext4() && - get_linux_version() >= EXT4_SUPPORTS_EXT2) - goto force_ext4; - - /* Ext4 has at least one feature which ext3 doesn't understand */ - if (!(frc & EXT3_FEATURE_RO_COMPAT_UNSUPPORTED) && - !(fi & EXT3_FEATURE_INCOMPAT_UNSUPPORTED)) - return -BLKID_ERR_PARAM; - -force_ext4: - /* - * If the filesystem is a OK for use by in-development - * filesystem code, and ext4dev is supported or ext4 is not - * supported, then don't call ourselves ext4, so we can redo - * the detection and mark the filesystem as ext4dev. - * - * If the filesystem is marked as in use by production - * filesystem, then it can only be used by ext4 and NOT by - * ext4dev. - */ - if (le32_to_cpu(es->s_flags) & EXT2_FLAGS_TEST_FILESYS) { - if (system_supports_ext4dev() || !system_supports_ext4()) - return -BLKID_ERR_PARAM; - } - - ext_get_info(pr, 4, es); - return 0; -} - -#define BLKID_EXT_MAGICS \ - { \ - { \ - .magic = EXT_SB_MAGIC, \ - .len = sizeof(EXT_SB_MAGIC) - 1, \ - .kboff = EXT_SB_KBOFF, \ - .sboff = EXT_MAG_OFF \ - }, \ - { NULL } \ - } - -const struct blkid_idinfo jbd_idinfo = -{ - .name = "jbd", - .usage = BLKID_USAGE_OTHER, - .probefunc = probe_jbd, - .magics = BLKID_EXT_MAGICS -}; - -const struct blkid_idinfo ext2_idinfo = -{ - .name = "ext2", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_ext2, - .magics = BLKID_EXT_MAGICS -}; - -const struct blkid_idinfo ext3_idinfo = -{ - .name = "ext3", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_ext3, - .magics = BLKID_EXT_MAGICS -}; - -const struct blkid_idinfo ext4_idinfo = -{ - .name = "ext4", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_ext4, - .magics = BLKID_EXT_MAGICS -}; - -const struct blkid_idinfo ext4dev_idinfo = -{ - .name = "ext4dev", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_ext4dev, - .magics = BLKID_EXT_MAGICS -}; - diff --git a/shlibs/blkid/src/superblocks/gfs.c b/shlibs/blkid/src/superblocks/gfs.c deleted file mode 100644 index b2c01630..00000000 --- a/shlibs/blkid/src/superblocks/gfs.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2008 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include - -#include "superblocks.h" - -/* Common gfs/gfs2 constants: */ -#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 */ -} __attribute__((packed)); - -static int probe_gfs(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct gfs2_sb *sbd; - - sbd = blkid_probe_get_sb(pr, mag, struct gfs2_sb); - if (!sbd) - return -1; - - if (be32_to_cpu(sbd->sb_fs_format) == GFS_FORMAT_FS && - be32_to_cpu(sbd->sb_multihost_format) == GFS_FORMAT_MULTI) - { - if (*sbd->sb_locktable) - blkid_probe_set_label(pr, - (unsigned char *) sbd->sb_locktable, - sizeof(sbd->sb_locktable)); - - blkid_probe_set_uuid(pr, sbd->sb_uuid); - return 0; - } - - return -1; -} - -static int probe_gfs2(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct gfs2_sb *sbd; - - sbd = blkid_probe_get_sb(pr, mag, struct gfs2_sb); - if (!sbd) - return -1; - - if (be32_to_cpu(sbd->sb_fs_format) == GFS2_FORMAT_FS && - be32_to_cpu(sbd->sb_multihost_format) == GFS2_FORMAT_MULTI) - { - if (*sbd->sb_locktable) - blkid_probe_set_label(pr, - (unsigned char *) sbd->sb_locktable, - sizeof(sbd->sb_locktable)); - blkid_probe_set_uuid(pr, sbd->sb_uuid); - blkid_probe_set_version(pr, "1"); - return 0; - } - return -1; -} - -const struct blkid_idinfo gfs_idinfo = -{ - .name = "gfs", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_gfs, - .minsz = 32 * 1024 * 1024, /* minimal size of GFS journal */ - .magics = - { - { .magic = "\x01\x16\x19\x70", .len = 4, .kboff = 64 }, - { NULL } - } -}; - -const struct blkid_idinfo gfs2_idinfo = -{ - .name = "gfs2", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_gfs2, - .minsz = 32 * 1024 * 1024, /* minimal size of GFS journal */ - .magics = - { - { .magic = "\x01\x16\x19\x70", .len = 4, .kboff = 64 }, - { NULL } - } -}; - diff --git a/shlibs/blkid/src/superblocks/hfs.c b/shlibs/blkid/src/superblocks/hfs.c deleted file mode 100644 index e043994e..00000000 --- a/shlibs/blkid/src/superblocks/hfs.c +++ /dev/null @@ -1,321 +0,0 @@ -/* - * Copyright (C) 2004-2008 Kay Sievers - * Copyright (C) 2008 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include - -#include "superblocks.h" -#include "md5.h" - -/* HFS / HFS+ */ -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]; -} __attribute__((packed)); - -struct hfs_mdb { - uint8_t signature[2]; - uint32_t cr_date; - uint32_t ls_Mod; - uint16_t atrb; - uint16_t nm_fls; - uint16_t vbm_st; - uint16_t alloc_ptr; - uint16_t nm_al_blks; - uint32_t al_blk_size; - uint32_t clp_size; - uint16_t al_bl_st; - uint32_t nxt_cnid; - uint16_t free_bks; - uint8_t label_len; - uint8_t label[27]; - uint32_t vol_bkup; - uint16_t vol_seq_num; - uint32_t wr_cnt; - uint32_t xt_clump_size; - uint32_t ct_clump_size; - uint16_t num_root_dirs; - uint32_t file_count; - uint32_t dir_count; - struct hfs_finder_info finder_info; - uint8_t embed_sig[2]; - uint16_t embed_startblock; - uint16_t embed_blockcount; -} __attribute__((packed)); - - -#define HFS_NODE_LEAF 0xff -#define HFSPLUS_POR_CNID 1 - -struct hfsplus_bnode_descriptor { - uint32_t next; - uint32_t prev; - uint8_t type; - uint8_t height; - uint16_t num_recs; - uint16_t reserved; -} __attribute__((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; -} __attribute__((packed)); - -struct hfsplus_catalog_key { - uint16_t key_len; - uint32_t parent_id; - uint16_t unicode_len; - uint8_t unicode[255 * 2]; -} __attribute__((packed)); - -struct hfsplus_extent { - uint32_t start_block; - uint32_t block_count; -} __attribute__((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]; -} __attribute__((packed)); - -struct hfsplus_vol_header { - uint8_t signature[2]; - uint16_t version; - uint32_t attributes; - uint32_t last_mount_vers; - uint32_t reserved; - uint32_t create_date; - uint32_t modify_date; - uint32_t backup_date; - uint32_t checked_date; - uint32_t file_count; - uint32_t folder_count; - uint32_t blocksize; - uint32_t total_blocks; - uint32_t free_blocks; - uint32_t next_alloc; - uint32_t rsrc_clump_sz; - uint32_t data_clump_sz; - uint32_t next_cnid; - uint32_t write_count; - uint64_t encodings_bmp; - struct hfs_finder_info finder_info; - struct hfsplus_fork alloc_file; - struct hfsplus_fork ext_file; - struct hfsplus_fork cat_file; - struct hfsplus_fork attr_file; - struct hfsplus_fork start_file; -} __attribute__((packed)); - -#define HFSPLUS_SECTOR_SIZE 512 - -static int hfs_set_uuid(blkid_probe pr, unsigned char const *hfs_info, size_t len) -{ - static unsigned char const hash_init[16] = { - 0xb3, 0xe2, 0x0f, 0x39, 0xf2, 0x92, 0x11, 0xd6, - 0x97, 0xa4, 0x00, 0x30, 0x65, 0x43, 0xec, 0xac - }; - unsigned char uuid[16]; - struct MD5Context md5c; - - if (memcmp(hfs_info, "\0\0\0\0\0\0\0\0", len) == 0) - return -1; - MD5Init(&md5c); - MD5Update(&md5c, hash_init, 16); - MD5Update(&md5c, hfs_info, len); - MD5Final(uuid, &md5c); - uuid[6] = 0x30 | (uuid[6] & 0x0f); - uuid[8] = 0x80 | (uuid[8] & 0x3f); - return blkid_probe_set_uuid(pr, uuid); -} - -static int probe_hfs(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct hfs_mdb *hfs; - - hfs = blkid_probe_get_sb(pr, mag, struct hfs_mdb); - if (!hfs) - return -1; - - if ((memcmp(hfs->embed_sig, "H+", 2) == 0) || - (memcmp(hfs->embed_sig, "HX", 2) == 0)) - return 1; /* Not hfs, but an embedded HFS+ */ - - hfs_set_uuid(pr, hfs->finder_info.id, sizeof(hfs->finder_info.id)); - - blkid_probe_set_label(pr, hfs->label, hfs->label_len); - return 0; -} - -static int probe_hfsplus(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT]; - struct hfsplus_bnode_descriptor *descr; - struct hfsplus_bheader_record *bnode; - struct hfsplus_catalog_key *key; - struct hfsplus_vol_header *hfsplus; - struct hfs_mdb *sbd; - unsigned int alloc_block_size; - unsigned int alloc_first_block; - unsigned int embed_first_block; - unsigned int off = 0; - unsigned int blocksize; - unsigned int cat_block; - unsigned int ext_block_start; - unsigned int ext_block_count; - unsigned int record_count; - unsigned int leaf_node_head; - unsigned int leaf_node_count; - unsigned int leaf_node_size; - unsigned int leaf_block; - int ext; - uint64_t leaf_off; - unsigned char *buf; - - sbd = blkid_probe_get_sb(pr, mag, struct hfs_mdb); - if (!sbd) - return -1; - - /* Check for a HFS+ volume embedded in a HFS volume */ - if (memcmp(sbd->signature, "BD", 2) == 0) { - if ((memcmp(sbd->embed_sig, "H+", 2) != 0) && - (memcmp(sbd->embed_sig, "HX", 2) != 0)) - /* This must be an HFS volume, so fail */ - return 1; - - alloc_block_size = be32_to_cpu(sbd->al_blk_size); - alloc_first_block = be16_to_cpu(sbd->al_bl_st); - embed_first_block = be16_to_cpu(sbd->embed_startblock); - off = (alloc_first_block * 512) + - (embed_first_block * alloc_block_size); - - buf = blkid_probe_get_buffer(pr, - off + (mag->kboff * 1024), - sizeof(struct hfsplus_vol_header)); - hfsplus = (struct hfsplus_vol_header *) buf; - - } else - hfsplus = blkid_probe_get_sb(pr, mag, - struct hfsplus_vol_header); - - if (!hfsplus) - return -1; - - if ((memcmp(hfsplus->signature, "H+", 2) != 0) && - (memcmp(hfsplus->signature, "HX", 2) != 0)) - return 1; - - hfs_set_uuid(pr, hfsplus->finder_info.id, sizeof(hfsplus->finder_info.id)); - - blocksize = be32_to_cpu(hfsplus->blocksize); - if (blocksize < HFSPLUS_SECTOR_SIZE) - return -1; - - memcpy(extents, hfsplus->cat_file.extents, sizeof(extents)); - cat_block = be32_to_cpu(extents[0].start_block); - - buf = blkid_probe_get_buffer(pr, - off + ((blkid_loff_t) cat_block * blocksize), 0x2000); - if (!buf) - return 0; - - bnode = (struct hfsplus_bheader_record *) - &buf[sizeof(struct hfsplus_bnode_descriptor)]; - - leaf_node_head = be32_to_cpu(bnode->leaf_head); - leaf_node_size = be16_to_cpu(bnode->node_size); - leaf_node_count = be32_to_cpu(bnode->leaf_count); - if (leaf_node_count == 0) - return 0; - - 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); - if (ext_block_count == 0) - return 0; - - /* this is our extent */ - if (leaf_block < ext_block_count) - break; - - leaf_block -= ext_block_count; - } - if (ext == HFSPLUS_EXTENT_COUNT) - return 0; - - leaf_off = (ext_block_start + leaf_block) * blocksize; - - buf = blkid_probe_get_buffer(pr, - (blkid_loff_t) off + leaf_off, - leaf_node_size); - if (!buf) - return 0; - - descr = (struct hfsplus_bnode_descriptor *) buf; - record_count = be16_to_cpu(descr->num_recs); - if (record_count == 0) - return 0; - - if (descr->type != HFS_NODE_LEAF) - return 0; - - key = (struct hfsplus_catalog_key *) - &buf[sizeof(struct hfsplus_bnode_descriptor)]; - - if (be32_to_cpu(key->parent_id) != HFSPLUS_POR_CNID) - return 0; - - blkid_probe_set_utf8label(pr, key->unicode, - be16_to_cpu(key->unicode_len) * 2, - BLKID_ENC_UTF16BE); - return 0; -} - -const struct blkid_idinfo hfs_idinfo = -{ - .name = "hfs", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_hfs, - .flags = BLKID_IDINFO_TOLERANT, - .magics = - { - { .magic = "BD", .len = 2, .kboff = 1 }, - { NULL } - } -}; - -const struct blkid_idinfo hfsplus_idinfo = -{ - .name = "hfsplus", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_hfsplus, - .magics = - { - { .magic = "BD", .len = 2, .kboff = 1 }, - { .magic = "H+", .len = 2, .kboff = 1 }, - { .magic = "HX", .len = 2, .kboff = 1 }, - { NULL } - } -}; diff --git a/shlibs/blkid/src/superblocks/highpoint_raid.c b/shlibs/blkid/src/superblocks/highpoint_raid.c deleted file mode 100644 index 25e3114b..00000000 --- a/shlibs/blkid/src/superblocks/highpoint_raid.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2008 Karel Zak - * - * Inspired by libvolume_id by - * Kay Sievers - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include - -#include "superblocks.h" - -struct hpt45x_metadata { - uint32_t magic; -}; - -#define HPT45X_MAGIC_OK 0x5a7816f3 -#define HPT45X_MAGIC_BAD 0x5a7816fd - -static int probe_highpoint45x(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct hpt45x_metadata *hpt; - uint64_t off; - uint32_t magic; - - if (pr->size < 0x10000) - return -1; - if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) - return -1; - - off = ((pr->size / 0x200) - 11) * 0x200; - hpt = (struct hpt45x_metadata *) - blkid_probe_get_buffer(pr, - off, - sizeof(struct hpt45x_metadata)); - if (!hpt) - return -1; - magic = le32_to_cpu(hpt->magic); - if (magic != HPT45X_MAGIC_OK && magic != HPT45X_MAGIC_BAD) - return -1; - if (blkid_probe_set_magic(pr, off, sizeof(hpt->magic), - (unsigned char *) &hpt->magic)) - return -1; - return 0; -} - -static int probe_highpoint37x(blkid_probe pr, const struct blkid_idmag *mag) -{ - if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) - return -1; - return 0; -} - - -const struct blkid_idinfo highpoint45x_idinfo = { - .name = "hpt45x_raid_member", - .usage = BLKID_USAGE_RAID, - .probefunc = probe_highpoint45x, - .magics = BLKID_NONE_MAGIC -}; - -const struct blkid_idinfo highpoint37x_idinfo = { - .name = "hpt37x_raid_member", - .usage = BLKID_USAGE_RAID, - .probefunc = probe_highpoint37x, - .magics = { - /* - * Superblok offset: 4608 bytes (9 sectors) - * Magic string offset within superblock: 32 bytes - * - * kboff = (4608 + 32) / 1024 - * sboff = (4608 + 32) % kboff - */ - { .magic = "\xf0\x16\x78\x5a", .len = 4, .kboff = 4, .sboff = 544 }, - { .magic = "\xfd\x16\x78\x5a", .len = 4, .kboff = 4, .sboff = 544 }, - { NULL } - } -}; - - diff --git a/shlibs/blkid/src/superblocks/hpfs.c b/shlibs/blkid/src/superblocks/hpfs.c deleted file mode 100644 index f9b851a4..00000000 --- a/shlibs/blkid/src/superblocks/hpfs.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2008 Karel Zak - * - * Inspired by libvolume_id by - * Kay Sievers - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include - -#include "superblocks.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]; -} __attribute__((packed)); - -struct hpfs_super_block -{ - uint8_t magic[4]; - uint8_t magic1[4]; - uint8_t version; -} __attribute__((packed)); - -struct hpfs_spare_super -{ - uint8_t magic[4]; - uint8_t magic1[4]; -} __attribute__((packed)); - - -#define HPFS_SB_OFFSET 0x2000 -#define HPFS_SBSPARE_OFFSET 0x2200 - -static int probe_hpfs(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct hpfs_super_block *hs; - struct hpfs_spare_super *hss; - struct hpfs_boot_block *hbb; - uint8_t version; - - /* super block */ - hs = blkid_probe_get_sb(pr, mag, struct hpfs_super_block); - if (!hs) - return -1; - version = hs->version; - - /* spare super block */ - hss = (struct hpfs_spare_super *) - blkid_probe_get_buffer(pr, - HPFS_SBSPARE_OFFSET, - sizeof(struct hpfs_spare_super)); - if (!hss) - return -1; - if (memcmp(hss->magic, "\x49\x18\x91\xf9", 4) != 0) - return -1; - - /* boot block (with UUID and LABEL) */ - hbb = (struct hpfs_boot_block *) - blkid_probe_get_buffer(pr, - 0, - sizeof(struct hpfs_boot_block)); - if (!hbb) - return -1; - if (memcmp(hbb->magic, "\x55\xaa", 2) == 0 && - memcmp(hbb->sig_hpfs, "HPFS", 4) == 0 && - hbb->sig_28h == 0x28) { - blkid_probe_set_label(pr, hbb->vol_label, sizeof(hbb->vol_label)); - blkid_probe_sprintf_uuid(pr, - hbb->vol_serno, sizeof(hbb->vol_serno), - "%02X%02X-%02X%02X", - hbb->vol_serno[3], hbb->vol_serno[2], - hbb->vol_serno[1], hbb->vol_serno[0]); - } - blkid_probe_sprintf_version(pr, "%u", version); - - return 0; -} - -const struct blkid_idinfo hpfs_idinfo = -{ - .name = "hpfs", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_hpfs, - .magics = - { - { - .magic = "\x49\xe8\x95\xf9", - .len = 4, - .kboff = (HPFS_SB_OFFSET >> 10) - }, - { NULL } - } -}; - - diff --git a/shlibs/blkid/src/superblocks/iso9660.c b/shlibs/blkid/src/superblocks/iso9660.c deleted file mode 100644 index 9f3ce2e6..00000000 --- a/shlibs/blkid/src/superblocks/iso9660.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 1999 by Andries Brouwer - * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o - * Copyright (C) 2001 by Andreas Dilger - * Copyright (C) 2004 Kay Sievers - * Copyright (C) 2008 Karel Zak - * - * Inspired also by libvolume_id by - * Kay Sievers - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include - -#include "superblocks.h" - -/* PVD - Primary volume descriptor */ -struct iso_volume_descriptor { - unsigned char vd_type; - unsigned char vd_id[5]; - unsigned char vd_version; - unsigned char flags; - unsigned char system_id[32]; - unsigned char volume_id[32]; - unsigned char unused[8]; - unsigned char space_size[8]; - unsigned char escape_sequences[8]; -} __attribute__((packed)); - -#define ISO_SUPERBLOCK_OFFSET 0x8000 -#define ISO_SECTOR_SIZE 0x800 -#define ISO_VD_OFFSET (ISO_SUPERBLOCK_OFFSET + ISO_SECTOR_SIZE) -#define ISO_VD_SUPPLEMENTARY 0x2 -#define ISO_VD_END 0xff -#define ISO_VD_MAX 16 - -struct high_sierra_volume_descriptor { - unsigned char foo[8]; - unsigned char type; - unsigned char id[5]; - unsigned char version; - unsigned char unused1; - unsigned char system_id[32]; - unsigned char volume_id[32]; -} __attribute__((packed)); - -/* returns 1 if the begin of @ascii is equal to @utf16 string. - */ -static int ascii_eq_utf16be(unsigned char *ascii, - unsigned char *utf16, size_t len) -{ - int a, u; - - for (a = 0, u = 0; u < len; a++, u += 2) { - if (utf16[u] != 0x0 || ascii[a] != utf16[u + 1]) - return 0; - } - return 1; -} - -/* old High Sierra format */ -static int probe_iso9660_hsfs(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct high_sierra_volume_descriptor *iso; - - iso = blkid_probe_get_sb(pr, mag, struct high_sierra_volume_descriptor); - if (!iso) - return -1; - - blkid_probe_set_version(pr, "High Sierra"); - blkid_probe_set_label(pr, iso->volume_id, sizeof(iso->volume_id)); - return 0; -} - -/* iso9660 [+ Microsoft Joliet Extension] */ -static int probe_iso9660(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct iso_volume_descriptor *iso; - unsigned char label[32]; - int i; - int off; - - if (strcmp(mag->magic, "CDROM") == 0) - return probe_iso9660_hsfs(pr, mag); - - iso = blkid_probe_get_sb(pr, mag, struct iso_volume_descriptor); - if (!iso) - return -1; - - memcpy(label, iso->volume_id, sizeof(label)); - - /* Joliet Extension */ - off = ISO_VD_OFFSET; - for (i = 0; i < ISO_VD_MAX; i++) { - iso = (struct iso_volume_descriptor *) - blkid_probe_get_buffer(pr, - off, - sizeof(struct iso_volume_descriptor)); - - if (iso == NULL || iso->vd_type == ISO_VD_END) - break; - if (iso->vd_type != ISO_VD_SUPPLEMENTARY) - continue; - - if (memcmp(iso->escape_sequences, "%/@", 3) == 0 || - memcmp(iso->escape_sequences, "%/C", 3) == 0 || - memcmp(iso->escape_sequences, "%/E", 3) == 0) { - - blkid_probe_set_version(pr, "Joliet Extension"); - - /* Is the Joliet (UTF16BE) label equal to the label in - * the PVD? If yes, use PVD label. The Jolied version - * of the label could be trimed (because UTF16..). - */ - if (ascii_eq_utf16be(label, iso->volume_id, 32)) - break; - - blkid_probe_set_utf8label(pr, - iso->volume_id, - sizeof(iso->volume_id), - BLKID_ENC_UTF16BE); - goto has_label; - } - off += ISO_SECTOR_SIZE; - } - - /* Joliet not found, let use standard iso label */ - blkid_probe_set_label(pr, label, sizeof(label)); - -has_label: - return 0; -} - - -const struct blkid_idinfo iso9660_idinfo = -{ - .name = "iso9660", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_iso9660, - .flags = BLKID_IDINFO_TOLERANT, - .magics = - { - { .magic = "CD001", .len = 5, .kboff = 32, .sboff = 1 }, - { .magic = "CDROM", .len = 5, .kboff = 32, .sboff = 9 }, - { NULL } - } -}; - diff --git a/shlibs/blkid/src/superblocks/isw_raid.c b/shlibs/blkid/src/superblocks/isw_raid.c deleted file mode 100644 index ac6251d7..00000000 --- a/shlibs/blkid/src/superblocks/isw_raid.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2008 Karel Zak - * - * Inspired by libvolume_id by - * Kay Sievers - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include - -#include "superblocks.h" - -struct isw_metadata { - uint8_t sig[32]; - uint32_t check_sum; - uint32_t mpb_size; - uint32_t family_num; - uint32_t generation_num; -}; - -#define ISW_SIGNATURE "Intel Raid ISM Cfg Sig. " - - -static int probe_iswraid(blkid_probe pr, const struct blkid_idmag *mag) -{ - uint64_t off; - struct isw_metadata *isw; - - if (pr->size < 0x10000) - return -1; - if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) - return -1; - - off = ((pr->size / 0x200) - 2) * 0x200; - isw = (struct isw_metadata *) - blkid_probe_get_buffer(pr, - off, - sizeof(struct isw_metadata)); - if (!isw) - return -1; - if (memcmp(isw->sig, ISW_SIGNATURE, sizeof(ISW_SIGNATURE)-1) != 0) - return -1; - if (blkid_probe_sprintf_version(pr, "%6s", - &isw->sig[sizeof(ISW_SIGNATURE)-1]) != 0) - return -1; - if (blkid_probe_set_magic(pr, off, sizeof(isw->sig), - (unsigned char *) isw->sig)) - return -1; - return 0; -} - -const struct blkid_idinfo iswraid_idinfo = { - .name = "isw_raid_member", - .usage = BLKID_USAGE_RAID, - .probefunc = probe_iswraid, - .magics = BLKID_NONE_MAGIC -}; - - diff --git a/shlibs/blkid/src/superblocks/jfs.c b/shlibs/blkid/src/superblocks/jfs.c deleted file mode 100644 index 9a49c674..00000000 --- a/shlibs/blkid/src/superblocks/jfs.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 1999 by Andries Brouwer - * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o - * Copyright (C) 2001 by Andreas Dilger - * Copyright (C) 2004 Kay Sievers - * Copyright (C) 2008 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include -#include -#include - -#include "superblocks.h" - -struct jfs_super_block { - unsigned char js_magic[4]; - uint32_t js_version; - uint64_t js_size; - uint32_t js_bsize; /* 4: aggregate block size in bytes */ - uint16_t js_l2bsize; /* 2: log2 of s_bsize */ - uint16_t js_l2bfactor; /* 2: log2(s_bsize/hardware block size) */ - uint32_t js_pbsize; /* 4: hardware/LVM block size in bytes */ - uint16_t js_l2pbsize; /* 2: log2 of s_pbsize */ - uint16_t js_pad; /* 2: padding necessary for alignment */ - uint32_t js_dummy2[26]; - unsigned char js_uuid[16]; - unsigned char js_label[16]; - unsigned char js_loguuid[16]; -}; - -static int probe_jfs(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct jfs_super_block *js; - - js = blkid_probe_get_sb(pr, mag, struct jfs_super_block); - if (!js) - return -1; - if (le32_to_cpu(js->js_bsize) != (1 << le16_to_cpu(js->js_l2bsize))) - return 1; - if (le32_to_cpu(js->js_pbsize) != (1 << le16_to_cpu(js->js_l2pbsize))) - return 1; - if ((le16_to_cpu(js->js_l2bsize) - le16_to_cpu(js->js_l2pbsize)) != - le16_to_cpu(js->js_l2bfactor)) - return 1; - - if (strlen((char *) js->js_label)) - blkid_probe_set_label(pr, js->js_label, sizeof(js->js_label)); - blkid_probe_set_uuid(pr, js->js_uuid); - return 0; -} - - -const struct blkid_idinfo jfs_idinfo = -{ - .name = "jfs", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_jfs, - .minsz = 16 * 1024 * 1024, - .magics = - { - { .magic = "JFS1", .len = 4, .kboff = 32 }, - { NULL } - } -}; - diff --git a/shlibs/blkid/src/superblocks/jmicron_raid.c b/shlibs/blkid/src/superblocks/jmicron_raid.c deleted file mode 100644 index d35b17f8..00000000 --- a/shlibs/blkid/src/superblocks/jmicron_raid.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2008 Karel Zak - * - * Inspired by libvolume_id by - * Kay Sievers - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -#include -#include -#include -#include -#include - -#include "superblocks.h" - -struct jm_metadata { - int8_t signature[2]; - uint8_t minor_version; - uint8_t major_version; - uint16_t checksum; -}; - -#define JM_SIGNATURE "JM" - -static int probe_jmraid(blkid_probe pr, const struct blkid_idmag *mag) -{ - uint64_t off; - struct jm_metadata *jm; - - if (pr->size < 0x10000) - return -1; - if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) - return -1; - - off = ((pr->size / 0x200) - 1) * 0x200; - jm = (struct jm_metadata *) - blkid_probe_get_buffer(pr, - off, - sizeof(struct jm_metadata)); - if (!jm) - return -1; - if (memcmp(jm->signature, JM_SIGNATURE, sizeof(JM_SIGNATURE) - 1) != 0) - return -1; - if (blkid_probe_sprintf_version(pr, "%u.%u", - jm->major_version, jm->minor_version) != 0) - return -1; - if (blkid_probe_set_magic(pr, off, sizeof(jm->signature), - (unsigned char *) jm->signature)) - return -1; - return 0; -} - -const struct blkid_idinfo jmraid_idinfo = { - .name = "jmicron_raid_member", - .usage = BLKID_USAGE_RAID, - .probefunc = probe_jmraid, - .magics = BLKID_NONE_MAGIC -}; - - diff --git a/shlibs/blkid/src/superblocks/linux_raid.c b/shlibs/blkid/src/superblocks/linux_raid.c deleted file mode 100644 index e74f57de..00000000 --- a/shlibs/blkid/src/superblocks/linux_raid.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright (C) 2008 Karel Zak - * - * Inspired by libvolume_id by - * Kay Sievers - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include - -#include "superblocks.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; -}; - -/* - * Version-1, little-endian. - */ -struct mdp1_super_block { - /* constant array information - 128 bytes */ - uint32_t magic; /* MD_SB_MAGIC: 0xa92b4efc - little endian */ - uint32_t major_version; /* 1 */ - uint32_t feature_map; /* 0 for now */ - uint32_t pad0; /* always set to 0 when writing */ - - uint8_t set_uuid[16]; /* user-space generated. */ - unsigned char set_name[32]; /* set and interpreted by user-space */ - - uint64_t ctime; /* lo 40 bits are seconds, top 24 are microseconds or 0*/ - uint32_t level; /* -4 (multipath), -1 (linear), 0,1,4,5 */ - uint32_t layout; /* only for raid5 currently */ - uint64_t size; /* used size of component devices, in 512byte sectors */ - - uint32_t chunksize; /* in 512byte sectors */ - uint32_t raid_disks; - uint32_t bitmap_offset; /* sectors after start of superblock that bitmap starts - * NOTE: signed, so bitmap can be before superblock - * only meaningful of feature_map[0] is set. - */ - - /* These are only valid with feature bit '4' */ - uint32_t new_level; /* new level we are reshaping to */ - uint64_t reshape_position; /* next address in array-space for reshape */ - uint32_t delta_disks; /* change in number of raid_disks */ - uint32_t new_layout; /* new layout */ - uint32_t new_chunk; /* new chunk size (bytes) */ - uint8_t pad1[128-124]; /* set to 0 when written */ - - /* constant this-device information - 64 bytes */ - uint64_t data_offset; /* sector start of data, often 0 */ - uint64_t data_size; /* sectors in this device that can be used for data */ - uint64_t super_offset; /* sector start of this superblock */ - uint64_t recovery_offset;/* sectors before this offset (from data_offset) have been recovered */ - uint32_t dev_number; /* permanent identifier of this device - not role in raid */ - uint32_t cnt_corrected_read; /* number of read errors that were corrected by re-writing */ - uint8_t device_uuid[16]; /* user-space setable, ignored by kernel */ - uint8_t devflags; /* per-device flags. Only one defined...*/ - uint8_t pad2[64-57]; /* set to 0 when writing */ - - /* array state information - 64 bytes */ - uint64_t utime; /* 40 bits second, 24 btes microseconds */ - uint64_t events; /* incremented when superblock updated */ - uint64_t resync_offset; /* data before this offset (from data_offset) known to be in sync */ - uint32_t sb_csum; /* checksum upto dev_roles[max_dev] */ - uint32_t max_dev; /* size of dev_roles[] array to consider */ - uint8_t pad3[64-32]; /* set to 0 when writing */ - - /* device state information. Indexed by dev_number. - * 2 bytes per device - * Note there are no per-device state flags. State information is rolled - * into the 'roles' value. If a device is spare or faulty, then it doesn't - * have a meaningful role. - */ - uint16_t dev_roles[0]; /* role in array, or 0xffff for a spare, or 0xfffe for faulty */ -}; - - -#define MD_RESERVED_BYTES 0x10000 -#define MD_SB_MAGIC 0xa92b4efc - -static int probe_raid0(blkid_probe pr, blkid_loff_t off) -{ - struct mdp0_super_block *mdp0; - union { - uint32_t ints[4]; - uint8_t bytes[16]; - } uuid; - uint32_t ma, mi, pa; - uint64_t size; - - if (pr->size < MD_RESERVED_BYTES) - return -1; - mdp0 = (struct mdp0_super_block *) - blkid_probe_get_buffer(pr, - off, - sizeof(struct mdp0_super_block)); - if (!mdp0) - return -1; - - memset(uuid.ints, 0, sizeof(uuid.ints)); - - if (le32_to_cpu(mdp0->md_magic) == MD_SB_MAGIC) { - uuid.ints[0] = swab32(mdp0->set_uuid0); - if (le32_to_cpu(mdp0->minor_version) >= 90) { - uuid.ints[1] = swab32(mdp0->set_uuid1); - uuid.ints[2] = swab32(mdp0->set_uuid2); - uuid.ints[3] = swab32(mdp0->set_uuid3); - } - ma = le32_to_cpu(mdp0->major_version); - mi = le32_to_cpu(mdp0->minor_version); - pa = le32_to_cpu(mdp0->patch_version); - size = le32_to_cpu(mdp0->size); - - } 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; - } - ma = be32_to_cpu(mdp0->major_version); - mi = be32_to_cpu(mdp0->minor_version); - pa = be32_to_cpu(mdp0->patch_version); - size = be32_to_cpu(mdp0->size); - } else - return 1; - - size <<= 10; /* convert KiB to bytes */ - - if (pr->size < size + MD_RESERVED_BYTES) - /* device is too small */ - return 1; - - if (off < size) - /* no space before superblock */ - return 1; - - /* - * Check for collisions between RAID and partition table - * - * For example the superblock is at the end of the last partition, it's - * the same possition as at the end of the disk... - */ - if ((S_ISREG(pr->mode) || blkid_probe_is_wholedisk(pr)) && - blkid_probe_is_covered_by_pt(pr, - off - size, /* min. start */ - size + MD_RESERVED_BYTES)) { /* min. length */ - - /* ignore this superblock, it's within any partition and - * we are working with whole-disk now */ - return 1; - } - - if (blkid_probe_sprintf_version(pr, "%u.%u.%u", ma, mi, pa) != 0) - return -1; - if (blkid_probe_set_uuid(pr, (unsigned char *) uuid.bytes) != 0) - return -1; - if (blkid_probe_set_magic(pr, off, sizeof(mdp0->md_magic), - (unsigned char *) &mdp0->md_magic)) - return -1; - return 0; -} - -static int probe_raid1(blkid_probe pr, off_t off) -{ - struct mdp1_super_block *mdp1; - - mdp1 = (struct mdp1_super_block *) - blkid_probe_get_buffer(pr, - off, - sizeof(struct mdp1_super_block)); - if (!mdp1) - return -1; - if (le32_to_cpu(mdp1->magic) != MD_SB_MAGIC) - return -1; - if (le32_to_cpu(mdp1->major_version) != 1) - return -1; - if (le64_to_cpu(mdp1->super_offset) != off >> 9) - return -1; - if (blkid_probe_set_uuid(pr, (unsigned char *) mdp1->set_uuid) != 0) - return -1; - if (blkid_probe_set_uuid_as(pr, - (unsigned char *) mdp1->device_uuid, "UUID_SUB") != 0) - return -1; - if (blkid_probe_set_label(pr, mdp1->set_name, - sizeof(mdp1->set_name)) != 0) - return -1; - if (blkid_probe_set_magic(pr, off, sizeof(mdp1->magic), - (unsigned char *) &mdp1->magic)) - return -1; - return 0; -} - -int probe_raid(blkid_probe pr, const struct blkid_idmag *mag) -{ - const char *ver = NULL; - - if (pr->size > MD_RESERVED_BYTES) { - /* version 0 at the end of the device */ - uint64_t sboff = (pr->size & ~(MD_RESERVED_BYTES - 1)) - - MD_RESERVED_BYTES; - if (probe_raid0(pr, sboff) == 0) - return 0; - - /* version 1.0 at the end of the device */ - sboff = (pr->size & ~(0x1000 - 1)) - 0x2000; - if (probe_raid1(pr, sboff) == 0) - ver = "1.0"; - } - - if (!ver) { - /* version 1.1 at the start of the device */ - if (probe_raid1(pr, 0) == 0) - ver = "1.1"; - - /* version 1.2 at 4k offset from the start */ - else if (probe_raid1(pr, 0x1000) == 0) - ver = "1.2"; - } - - if (ver) { - blkid_probe_set_version(pr, ver); - return 0; - } - return -1; -} - - -const struct blkid_idinfo linuxraid_idinfo = { - .name = "linux_raid_member", - .usage = BLKID_USAGE_RAID, - .probefunc = probe_raid, - .magics = BLKID_NONE_MAGIC -}; - - diff --git a/shlibs/blkid/src/superblocks/lsi_raid.c b/shlibs/blkid/src/superblocks/lsi_raid.c deleted file mode 100644 index 5217a009..00000000 --- a/shlibs/blkid/src/superblocks/lsi_raid.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2008 Karel Zak - * - * Inspired by libvolume_id by - * Kay Sievers - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -#include -#include -#include -#include -#include - -#include "superblocks.h" - -struct lsi_metadata { - uint8_t sig[6]; -}; - - -#define LSI_SIGNATURE "$XIDE$" - -static int probe_lsiraid(blkid_probe pr, const struct blkid_idmag *mag) -{ - uint64_t off; - struct lsi_metadata *lsi; - - if (pr->size < 0x10000) - return -1; - if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) - return -1; - - off = ((pr->size / 0x200) - 1) * 0x200; - lsi = (struct lsi_metadata *) - blkid_probe_get_buffer(pr, - off, - sizeof(struct lsi_metadata)); - if (!lsi) - return -1; - - if (memcmp(lsi->sig, LSI_SIGNATURE, sizeof(LSI_SIGNATURE)-1) != 0) - return -1; - if (blkid_probe_set_magic(pr, off, sizeof(lsi->sig), - (unsigned char *) lsi->sig)) - return -1; - return 0; -} - -const struct blkid_idinfo lsiraid_idinfo = { - .name = "lsi_mega_raid_member", - .usage = BLKID_USAGE_RAID, - .probefunc = probe_lsiraid, - .magics = BLKID_NONE_MAGIC -}; - - diff --git a/shlibs/blkid/src/superblocks/luks.c b/shlibs/blkid/src/superblocks/luks.c deleted file mode 100644 index f716e31c..00000000 --- a/shlibs/blkid/src/superblocks/luks.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2008 Karel Zak - * - * Inspired by libvolume_id by - * Kay Sievers - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include -#include -#include - -#include "superblocks.h" - -#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_MAGIC_L 6 -#define UUID_STRING_L 40 - -struct luks_phdr { - uint8_t magic[LUKS_MAGIC_L]; - uint16_t version; - uint8_t cipherName[LUKS_CIPHERNAME_L]; - uint8_t cipherMode[LUKS_CIPHERMODE_L]; - uint8_t hashSpec[LUKS_HASHSPEC_L]; - uint32_t payloadOffset; - uint32_t keyBytes; - uint8_t mkDigest[LUKS_DIGESTSIZE]; - uint8_t mkDigestSalt[LUKS_SALTSIZE]; - uint32_t mkDigestIterations; - uint8_t uuid[UUID_STRING_L]; -} __attribute__((packed)); - -static int probe_luks(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct luks_phdr *header; - - header = blkid_probe_get_sb(pr, mag, struct luks_phdr); - if (header == NULL) - return -1; - - blkid_probe_strncpy_uuid(pr, (unsigned char *) header->uuid, - sizeof(header->uuid)); - blkid_probe_sprintf_version(pr, "%u", be16_to_cpu(header->version)); - return 0; -} - -const struct blkid_idinfo luks_idinfo = -{ - .name = "crypto_LUKS", - .usage = BLKID_USAGE_CRYPTO, - .probefunc = probe_luks, - .magics = - { - { .magic = "LUKS\xba\xbe", .len = 6 }, - { NULL } - } -}; diff --git a/shlibs/blkid/src/superblocks/lvm.c b/shlibs/blkid/src/superblocks/lvm.c deleted file mode 100644 index 3a9807c8..00000000 --- a/shlibs/blkid/src/superblocks/lvm.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (C) 1999 by Andries Brouwer - * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o - * Copyright (C) 2001 by Andreas Dilger - * Copyright (C) 2004 Kay Sievers - * Copyright (C) 2008 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include - -#include "superblocks.h" - -#define LVM1_ID_LEN 128 -#define LVM2_ID_LEN 32 - -struct lvm2_pv_label_header { - /* label_header */ - uint8_t id[8]; /* LABELONE */ - uint64_t sector_xl; /* Sector number of this label */ - uint32_t crc_xl; /* From next field to end of sector */ - uint32_t offset_xl; /* Offset from start of struct to contents */ - uint8_t type[8]; /* LVM2 001 */ - /* pv_header */ - uint8_t pv_uuid[LVM2_ID_LEN]; -} __attribute__ ((packed)); - -struct lvm1_pv_label_header { - uint8_t id[2]; /* HM */ - uint16_t version; /* version 1 or 2 */ - uint32_t _notused[10]; /* lvm1 internals */ - uint8_t pv_uuid[LVM1_ID_LEN]; -} __attribute__ ((packed)); - -#define LVM2_LABEL_SIZE 512 -static unsigned int lvm2_calc_crc(const void *buf, unsigned int size) -{ - static const unsigned int crctab[] = { - 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, - 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, - 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, - 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c - }; - unsigned int i, crc = 0xf597a6cf; - const uint8_t *data = (const uint8_t *) buf; - - for (i = 0; i < size; i++) { - crc ^= *data++; - crc = (crc >> 4) ^ crctab[crc & 0xf]; - crc = (crc >> 4) ^ crctab[crc & 0xf]; - } - return crc; -} - -/* Length of real UUID is always LVM2_ID_LEN */ -static void format_lvm_uuid(char *dst_uuid, char *src_uuid) -{ - unsigned int i, b; - - for (i = 0, b = 1; i < LVM2_ID_LEN; i++, b <<= 1) { - if (b & 0x4444440) - *dst_uuid++ = '-'; - *dst_uuid++ = *src_uuid++; - } - *dst_uuid = '\0'; -} - -static int probe_lvm2(blkid_probe pr, const struct blkid_idmag *mag) -{ - int sector = mag->kboff << 1; - struct lvm2_pv_label_header *label; - char uuid[LVM2_ID_LEN + 7]; - unsigned char *buf; - - buf = blkid_probe_get_buffer(pr, - mag->kboff << 10, - 512 + sizeof(struct lvm2_pv_label_header)); - if (!buf) - return -1; - - /* buf is at 0k or 1k offset; find label inside */ - if (memcmp(buf, "LABELONE", 8) == 0) { - label = (struct lvm2_pv_label_header *) buf; - } else if (memcmp(buf + 512, "LABELONE", 8) == 0) { - label = (struct lvm2_pv_label_header *)(buf + 512); - sector++; - } else { - return 1; - } - - if (le64_to_cpu(label->sector_xl) != (unsigned) sector) - return 1; - - if (lvm2_calc_crc(&label->offset_xl, LVM2_LABEL_SIZE - - ((char *) &label->offset_xl - (char *) label)) != - le32_to_cpu(label->crc_xl)) { - DBG(DEBUG_PROBE, - printf("LVM2: label checksum incorrect at sector %d\n", - sector)); - return 1; - } - - format_lvm_uuid(uuid, (char *) label->pv_uuid); - blkid_probe_sprintf_uuid(pr, label->pv_uuid, sizeof(label->pv_uuid), - "%s", uuid); - - /* the mag->magic is the same string as label->type, - * but zero terminated */ - blkid_probe_set_version(pr, mag->magic); - - /* LVM (pvcreate) wipes begin of the device -- let's remember this - * to resolve conflicts bettween LVM and partition tables, ... - */ - blkid_probe_set_wiper(pr, 0, 8 * 1024); - - return 0; -} - -static int probe_lvm1(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct lvm1_pv_label_header *label; - char uuid[LVM2_ID_LEN + 7]; - unsigned int version; - - label = blkid_probe_get_sb(pr, mag, struct lvm1_pv_label_header); - if (!label) - return -1; - - version = le16_to_cpu(label->version); - if (version != 1 && version != 2) - return 1; - - format_lvm_uuid(uuid, (char *) label->pv_uuid); - blkid_probe_sprintf_uuid(pr, label->pv_uuid, sizeof(label->pv_uuid), - "%s", uuid); - - return 0; -} - -/* NOTE: the original libblkid uses "lvm2pv" as a name */ -const struct blkid_idinfo lvm2_idinfo = -{ - .name = "LVM2_member", - .usage = BLKID_USAGE_RAID, - .probefunc = probe_lvm2, - .magics = - { - { .magic = "LVM2 001", .len = 8, .sboff = 0x218 }, - { .magic = "LVM2 001", .len = 8, .sboff = 0x018 }, - { .magic = "LVM2 001", .len = 8, .kboff = 1, .sboff = 0x018 }, - { .magic = "LVM2 001", .len = 8, .kboff = 1, .sboff = 0x218 }, - { NULL } - } -}; - -const struct blkid_idinfo lvm1_idinfo = -{ - .name = "LVM1_member", - .usage = BLKID_USAGE_RAID, - .probefunc = probe_lvm1, - .magics = - { - { .magic = "HM", .len = 2 }, - { NULL } - } -}; - -const struct blkid_idinfo snapcow_idinfo = -{ - .name = "DM_snapshot_cow", - .usage = BLKID_USAGE_OTHER, - .magics = - { - { .magic = "SnAp", .len = 4 }, - { NULL } - } -}; diff --git a/shlibs/blkid/src/superblocks/minix.c b/shlibs/blkid/src/superblocks/minix.c deleted file mode 100644 index 3290c275..00000000 --- a/shlibs/blkid/src/superblocks/minix.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 1999 by Andries Brouwer - * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o - * Copyright (C) 2001 by Andreas Dilger - * Copyright (C) 2004 Kay Sievers - * Copyright (C) 2008 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -#include -#include "superblocks.h" - -struct minix_super_block { - uint16_t s_ninodes; - uint16_t s_nzones; - uint16_t s_imap_blocks; - uint16_t s_zmap_blocks; - uint16_t s_firstdatazone; - uint16_t s_log_zone_size; - uint32_t s_max_size; - uint16_t s_magic; - uint16_t s_state; - uint32_t s_zones; -}; - -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; -}; - -#define MINIX_BLOCK_SIZE_BITS 10 -#define MINIX_BLOCK_SIZE (1 << MINIX_BLOCK_SIZE_BITS) - -static int probe_minix(blkid_probe pr, const struct blkid_idmag *mag) -{ - unsigned char *ext; - int version; - - /* for more details see magic strings below */ - switch(mag->magic[1]) { - case '\023': - version = 1; - break; - case '\044': - version = 2; - break; - case '\115': - version = 3; - break; - default: - return -1; - break; - } - - if (version <= 2) { - struct minix_super_block *sb; - uint32_t zones; - - sb = blkid_probe_get_sb(pr, mag, struct minix_super_block); - if (!sb || sb->s_imap_blocks == 0 || sb->s_zmap_blocks == 0) - return -1; - - zones = version == 2 ? sb->s_zones : sb->s_nzones; - - /* sanity checks to be sure that the FS is really minix */ - if (sb->s_imap_blocks * MINIX_BLOCK_SIZE * 8 < sb->s_ninodes + 1) - return -1; - if (sb->s_zmap_blocks * MINIX_BLOCK_SIZE * 8 < zones - sb->s_firstdatazone + 1) - return -1; - - } else if (version == 3) { - struct minix3_super_block *sb; - - sb = blkid_probe_get_sb(pr, mag, struct minix3_super_block); - if (!sb || sb->s_imap_blocks == 0 || sb->s_zmap_blocks == 0) - return -1; - - } - - /* unfortunately, some parts of ext3 is sometimes possible to - * interpreted as minix superblock. So check for extN magic - * string. (For extN magic string and offsets see ext.c.) - */ - ext = blkid_probe_get_buffer(pr, 0x400 + 0x38, 2); - if (ext && memcmp(ext, "\123\357", 2) == 0) - return -1; - - blkid_probe_sprintf_version(pr, "%d", version); - return 0; -} - -const struct blkid_idinfo minix_idinfo = -{ - .name = "minix", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_minix, - .magics = - { - /* version 1 */ - { .magic = "\177\023", .len = 2, .kboff = 1, .sboff = 0x10 }, - { .magic = "\217\023", .len = 2, .kboff = 1, .sboff = 0x10 }, - - /* version 2 */ - { .magic = "\150\044", .len = 2, .kboff = 1, .sboff = 0x10 }, - { .magic = "\170\044", .len = 2, .kboff = 1, .sboff = 0x10 }, - - /* version 3 */ - { .magic = "\132\115", .len = 2, .kboff = 1, .sboff = 0x18 }, - { NULL } - } -}; - diff --git a/shlibs/blkid/src/superblocks/netware.c b/shlibs/blkid/src/superblocks/netware.c deleted file mode 100644 index 7ef21625..00000000 --- a/shlibs/blkid/src/superblocks/netware.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2008 Karel Zak - * - * Inspired by libvolume_id by - * Kay Sievers - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include - -#include "superblocks.h" - -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)]; -} __attribute__((__packed__)); - -static int probe_netware(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct netware_super_block *nw; - - nw = blkid_probe_get_sb(pr, mag, struct netware_super_block); - if (!nw) - return -1; - - blkid_probe_set_uuid(pr, nw->SBH_PoolID); - - blkid_probe_sprintf_version(pr, "%u.%02u", - le16_to_cpu(nw->SBH_VersionMediaMajor), - le16_to_cpu(nw->SBH_VersionMediaMinor)); - - return 0; -} - -const struct blkid_idinfo netware_idinfo = -{ - .name = "nss", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_netware, - .magics = - { - { .magic = "SPB5", .len = 4, .kboff = 4 }, - { NULL } - } -}; - - diff --git a/shlibs/blkid/src/superblocks/nilfs.c b/shlibs/blkid/src/superblocks/nilfs.c deleted file mode 100644 index 1f8f3a69..00000000 --- a/shlibs/blkid/src/superblocks/nilfs.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2010 by Jiro SEKIBA - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License - */ -#include -#include - -#include "superblocks.h" -#include "crc32.h" - -struct nilfs_super_block { - uint32_t s_rev_level; - uint16_t s_minor_rev_level; - uint16_t s_magic; - - uint16_t s_bytes; - - uint16_t s_flags; - uint32_t s_crc_seed; - uint32_t s_sum; - - uint32_t s_log_block_size; - - uint64_t s_nsegments; - uint64_t s_dev_size; - uint64_t s_first_data_block; - uint32_t s_blocks_per_segment; - uint32_t s_r_segments_percentage; - - uint64_t s_last_cno; - uint64_t s_last_pseg; - uint64_t s_last_seq; - uint64_t s_free_blocks_count; - - uint64_t s_ctime; - - uint64_t s_mtime; - uint64_t s_wtime; - uint16_t s_mnt_count; - uint16_t s_max_mnt_count; - uint16_t s_state; - uint16_t s_errors; - uint64_t s_lastcheck; - - uint32_t s_checkinterval; - uint32_t s_creator_os; - uint16_t s_def_resuid; - uint16_t s_def_resgid; - uint32_t s_first_ino; - - uint16_t s_inode_size; - uint16_t s_dat_entry_size; - uint16_t s_checkpoint_size; - uint16_t s_segment_usage_size; - - uint8_t s_uuid[16]; - char s_volume_name[80]; - - uint32_t s_c_interval; - uint32_t s_c_block_max; - uint32_t s_reserved[192]; -}; - -/* nilfs2 magic string */ -#define NILFS_SB_MAGIC "\x34\x34" -/* nilfs2 super block offset */ -#define NILFS_SB_OFF 0x400 -/* nilfs2 super block offset in kB */ -#define NILFS_SB_KBOFF (NILFS_SB_OFF >> 10) -/* nilfs2 magic string offset within super block */ -#define NILFS_MAG_OFF 6 - -static int probe_nilfs2(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct nilfs_super_block *sb; - static unsigned char sum[4]; - const int sumoff = offsetof(struct nilfs_super_block, s_sum); - size_t bytes; - uint32_t crc; - - sb = blkid_probe_get_sb(pr, mag, struct nilfs_super_block); - if (!sb) - return -1; - - bytes = le16_to_cpu(sb->s_bytes); - crc = crc32(le32_to_cpu(sb->s_crc_seed), (unsigned char *)sb, sumoff); - crc = crc32(crc, sum, 4); - crc = crc32(crc, (unsigned char *)sb + sumoff + 4, bytes - sumoff - 4); - - if (crc != le32_to_cpu(sb->s_sum)) - return -1; - - if (strlen(sb->s_volume_name)) - blkid_probe_set_label(pr, (unsigned char *) sb->s_volume_name, - sizeof(sb->s_volume_name)); - - blkid_probe_set_uuid(pr, sb->s_uuid); - blkid_probe_sprintf_version(pr, "%u", le32_to_cpu(sb->s_rev_level)); - - return 0; -} - -const struct blkid_idinfo nilfs2_idinfo = -{ - .name = "nilfs2", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_nilfs2, - .magics = - { - { - .magic = NILFS_SB_MAGIC, - .len = 2, - .kboff = NILFS_SB_KBOFF, - .sboff = NILFS_MAG_OFF - }, - { NULL } - } -}; diff --git a/shlibs/blkid/src/superblocks/ntfs.c b/shlibs/blkid/src/superblocks/ntfs.c deleted file mode 100644 index 98f3fb2f..00000000 --- a/shlibs/blkid/src/superblocks/ntfs.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2004 Kay Sievers - * Copyright (C) 2008 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include - -#include "superblocks.h" - -struct ntfs_super_block { - uint8_t jump[3]; - uint8_t oem_id[8]; - uint8_t bios_parameter_block[25]; - 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]; - uint64_t volume_serial; - uint16_t checksum; -} __attribute__((packed)); - -struct master_file_table_record { - uint32_t magic; - 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; -} __attribute__((__packed__)); - -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; -} __attribute__((__packed__)); - -#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 - -static int probe_ntfs(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct ntfs_super_block *ns; - struct master_file_table_record *mft; - struct file_attribute *attr; - int bytes_per_sector, sectors_per_cluster; - int mft_record_size, attr_off, attr_len; - unsigned int attr_type, val_len; - int val_off; - uint64_t nr_clusters; - blkid_loff_t off; - unsigned char *buf_mft, *val; - - ns = blkid_probe_get_sb(pr, mag, struct ntfs_super_block); - if (!ns) - return -1; - - bytes_per_sector = ns->bios_parameter_block[0] + - (ns->bios_parameter_block[1] << 8); - sectors_per_cluster = ns->bios_parameter_block[2]; - - if ((bytes_per_sector < 512) || (sectors_per_cluster == 0)) - return 1; - - if (ns->cluster_per_mft_record < 0) - mft_record_size = 1 << (0 - ns->cluster_per_mft_record); - else - mft_record_size = ns->cluster_per_mft_record * - sectors_per_cluster * bytes_per_sector; - nr_clusters = le64_to_cpu(ns->number_of_sectors) / sectors_per_cluster; - - if ((le64_to_cpu(ns->mft_cluster_location) > nr_clusters) || - (le64_to_cpu(ns->mft_mirror_cluster_location) > nr_clusters)) - return 1; - - off = le64_to_cpu(ns->mft_mirror_cluster_location) * - bytes_per_sector * sectors_per_cluster; - - buf_mft = blkid_probe_get_buffer(pr, off, mft_record_size); - if (!buf_mft) - return 1; - - if (memcmp(buf_mft, "FILE", 4)) - return 1; - - off = le64_to_cpu(ns->mft_cluster_location) * bytes_per_sector * - sectors_per_cluster; - - buf_mft = blkid_probe_get_buffer(pr, off, mft_record_size); - if (!buf_mft) - return 1; - - if (memcmp(buf_mft, "FILE", 4)) - return 1; - - off += MFT_RECORD_VOLUME * mft_record_size; - - buf_mft = blkid_probe_get_buffer(pr, off, mft_record_size); - if (!buf_mft) - return 1; - - if (memcmp(buf_mft, "FILE", 4)) - return 1; - - mft = (struct master_file_table_record *) buf_mft; - - attr_off = le16_to_cpu(mft->attrs_offset); - - while (1) { - attr = (struct file_attribute *) (buf_mft + attr_off); - attr_len = le32_to_cpu(attr->len); - attr_type = le32_to_cpu(attr->type); - val_off = le16_to_cpu(attr->value_offset); - val_len = le32_to_cpu(attr->value_len); - - attr_off += attr_len; - - if ((attr_off > mft_record_size) || - (attr_len == 0)) - break; - - if (attr_type == MFT_RECORD_ATTR_END) - break; - - if (attr_type == MFT_RECORD_ATTR_VOLUME_NAME) { - val = ((uint8_t *) attr) + val_off; - blkid_probe_set_utf8label(pr, val, val_len, BLKID_ENC_UTF16LE); - } - } - - blkid_probe_sprintf_uuid(pr, - (unsigned char *) &ns->volume_serial, - sizeof(ns->volume_serial), - "%016" PRIX64, le64_to_cpu(ns->volume_serial)); - return 0; -} - - -const struct blkid_idinfo ntfs_idinfo = -{ - .name = "ntfs", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_ntfs, - .magics = - { - { .magic = "NTFS ", .len = 8, .sboff = 3 }, - { NULL } - } -}; - diff --git a/shlibs/blkid/src/superblocks/nvidia_raid.c b/shlibs/blkid/src/superblocks/nvidia_raid.c deleted file mode 100644 index c3db949a..00000000 --- a/shlibs/blkid/src/superblocks/nvidia_raid.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2008 Karel Zak - * Copyright (C) 2005 Kay Sievers - * - * Inspired by libvolume_id by - * Kay Sievers - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include - -#include "superblocks.h" - -struct nv_metadata { - uint8_t vendor[8]; - uint32_t size; - uint32_t chksum; - uint16_t version; -} __attribute__((packed)); - -#define NVIDIA_SIGNATURE "NVIDIA" - -static int probe_nvraid(blkid_probe pr, const struct blkid_idmag *mag) -{ - uint64_t off; - struct nv_metadata *nv; - - if (pr->size < 0x10000) - return -1; - if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) - return -1; - - off = ((pr->size / 0x200) - 2) * 0x200; - nv = (struct nv_metadata *) - blkid_probe_get_buffer(pr, - off, - sizeof(struct nv_metadata)); - if (!nv) - return -1; - - if (memcmp(nv->vendor, NVIDIA_SIGNATURE, sizeof(NVIDIA_SIGNATURE)-1) != 0) - return -1; - if (blkid_probe_sprintf_version(pr, "%u", le16_to_cpu(nv->version)) != 0) - return -1; - if (blkid_probe_set_magic(pr, off, sizeof(nv->vendor), - (unsigned char *) nv->vendor)) - return -1; - return 0; -} - -const struct blkid_idinfo nvraid_idinfo = { - .name = "nvidia_raid_member", - .usage = BLKID_USAGE_RAID, - .probefunc = probe_nvraid, - .magics = BLKID_NONE_MAGIC -}; - - diff --git a/shlibs/blkid/src/superblocks/ocfs.c b/shlibs/blkid/src/superblocks/ocfs.c deleted file mode 100644 index 9dbf41b1..00000000 --- a/shlibs/blkid/src/superblocks/ocfs.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (C) 1999, 2001 by Andries Brouwer - * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o - * Copyright (C) 2008 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include - -#include "superblocks.h" - -struct ocfs_volume_header { - unsigned char minor_version[4]; - unsigned char major_version[4]; - unsigned char signature[128]; - char mount[128]; - unsigned char mount_len[2]; -} __attribute__((packed)); - -struct ocfs_volume_label { - unsigned char disk_lock[48]; - char label[64]; - unsigned char label_len[2]; - unsigned char vol_id[16]; - unsigned char vol_id_len[2]; -} __attribute__((packed)); - -#define ocfsmajor(o) ( (uint32_t) o.major_version[0] \ - + (((uint32_t) o.major_version[1]) << 8) \ - + (((uint32_t) o.major_version[2]) << 16) \ - + (((uint32_t) o.major_version[3]) << 24)) - -#define ocfsminor(o) ( (uint32_t) o.minor_version[0] \ - + (((uint32_t) o.minor_version[1]) << 8) \ - + (((uint32_t) o.minor_version[2]) << 16) \ - + (((uint32_t) o.minor_version[3]) << 24)) - -#define ocfslabellen(o) ((uint32_t)o.label_len[0] + (((uint32_t) o.label_len[1]) << 8)) -#define ocfsmountlen(o) ((uint32_t)o.mount_len[0] + (((uint32_t) o.mount_len[1]) << 8)) - -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]; -} __attribute__((packed)); - -struct oracle_asm_disk_label { - char dummy[32]; - char dl_tag[8]; - char dl_id[24]; -} __attribute__((packed)); - -static int probe_ocfs(blkid_probe pr, const struct blkid_idmag *mag) -{ - unsigned char *buf; - struct ocfs_volume_header ovh; - struct ocfs_volume_label ovl; - uint32_t maj, min; - - /* header */ - buf = blkid_probe_get_buffer(pr, mag->kboff << 10, - sizeof(struct ocfs_volume_header)); - if (!buf) - return -1; - memcpy(&ovh, buf, sizeof(ovh)); - - /* label */ - buf = blkid_probe_get_buffer(pr, (mag->kboff << 10) + 512, - sizeof(struct ocfs_volume_label)); - if (!buf) - return -1; - memcpy(&ovl, buf, sizeof(ovl)); - - maj = ocfsmajor(ovh); - min = ocfsminor(ovh); - - if (maj == 1) - blkid_probe_set_value(pr, "SEC_TYPE", - (unsigned char *) "ocfs1", sizeof("ocfs1")); - else if (maj >= 9) - blkid_probe_set_value(pr, "SEC_TYPE", - (unsigned char *) "ntocfs", sizeof("ntocfs")); - - blkid_probe_set_label(pr, (unsigned char *) ovl.label, - ocfslabellen(ovl)); - blkid_probe_set_value(pr, "MOUNT", (unsigned char *) ovh.mount, - ocfsmountlen(ovh)); - blkid_probe_set_uuid(pr, ovl.vol_id); - blkid_probe_sprintf_version(pr, "%u.%u", maj, min); - return 0; -} - -static int probe_ocfs2(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct ocfs2_super_block *osb; - - osb = blkid_probe_get_sb(pr, mag, struct ocfs2_super_block); - if (!osb) - return -1; - - blkid_probe_set_label(pr, (unsigned char *) osb->s_label, sizeof(osb->s_label)); - blkid_probe_set_uuid(pr, osb->s_uuid); - - blkid_probe_sprintf_version(pr, "%u.%u", - le16_to_cpu(osb->s_major_rev_level), - le16_to_cpu(osb->s_minor_rev_level)); - - return 0; -} - -static int probe_oracleasm(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct oracle_asm_disk_label *dl; - - dl = blkid_probe_get_sb(pr, mag, struct oracle_asm_disk_label); - if (!dl) - return -1; - - blkid_probe_set_label(pr, (unsigned char *) dl->dl_id, sizeof(dl->dl_id)); - return 0; -} - - -const struct blkid_idinfo ocfs_idinfo = -{ - .name = "ocfs", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_ocfs, - .minsz = 108 * 1024 * 1024, - .magics = - { - { .magic = "OracleCFS", .len = 9, .kboff = 8 }, - { NULL } - } -}; - -const struct blkid_idinfo ocfs2_idinfo = -{ - .name = "ocfs2", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_ocfs2, - .minsz = 108 * 1024 * 1024, - .magics = - { - { .magic = "OCFSV2", .len = 6, .kboff = 1 }, - { .magic = "OCFSV2", .len = 6, .kboff = 2 }, - { .magic = "OCFSV2", .len = 6, .kboff = 4 }, - { .magic = "OCFSV2", .len = 6, .kboff = 8 }, - { NULL } - } -}; - -/* Oracle ASM (Automatic Storage Management) */ -const struct blkid_idinfo oracleasm_idinfo = -{ - .name = "oracleasm", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_oracleasm, - .magics = - { - { .magic = "ORCLDISK", .len = 8, .sboff = 32 }, - { NULL } - } -}; - diff --git a/shlibs/blkid/src/superblocks/promise_raid.c b/shlibs/blkid/src/superblocks/promise_raid.c deleted file mode 100644 index 0e91d3c2..00000000 --- a/shlibs/blkid/src/superblocks/promise_raid.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2008 Karel Zak - * - * Inspired by libvolume_id by - * Kay Sievers - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include -#include -#include - -#include "superblocks.h" - -struct promise_metadata { - uint8_t sig[24]; -}; - -#define PDC_CONFIG_OFF 0x1200 -#define PDC_SIGNATURE "Promise Technology, Inc." - -static int probe_pdcraid(blkid_probe pr, const struct blkid_idmag *mag) -{ - unsigned int i; - static unsigned int sectors[] = { - 63, 255, 256, 16, 399, 0 - }; - - if (pr->size < 0x40000) - return -1; - if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) - return -1; - - for (i = 0; sectors[i] != 0; i++) { - uint64_t off; - struct promise_metadata *pdc; - - off = ((pr->size / 0x200) - sectors[i]) * 0x200; - pdc = (struct promise_metadata *) - blkid_probe_get_buffer(pr, - off, - sizeof(struct promise_metadata)); - if (!pdc) - return -1; - - if (memcmp(pdc->sig, PDC_SIGNATURE, - sizeof(PDC_SIGNATURE) - 1) == 0) { - - if (blkid_probe_set_magic(pr, off, sizeof(pdc->sig), - (unsigned char *) pdc->sig)) - return -1; - return 0; - } - } - return -1; -} - -const struct blkid_idinfo pdcraid_idinfo = { - .name = "promise_fasttrack_raid_member", - .usage = BLKID_USAGE_RAID, - .probefunc = probe_pdcraid, - .magics = BLKID_NONE_MAGIC -}; - - diff --git a/shlibs/blkid/src/superblocks/reiserfs.c b/shlibs/blkid/src/superblocks/reiserfs.c deleted file mode 100644 index 921f5237..00000000 --- a/shlibs/blkid/src/superblocks/reiserfs.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 1999, 2001 by Andries Brouwer - * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o - * Copyright (C) 2008 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include - -#include "superblocks.h" - -struct reiserfs_super_block { - uint32_t rs_blocks_count; - uint32_t rs_free_blocks; - uint32_t rs_root_block; - uint32_t rs_journal_block; - uint32_t rs_journal_dev; - uint32_t rs_orig_journal_size; - uint32_t rs_dummy2[5]; - uint16_t rs_blocksize; - uint16_t rs_dummy3[3]; - unsigned char rs_magic[12]; - uint32_t rs_dummy4[5]; - unsigned char rs_uuid[16]; - char rs_label[16]; -} __attribute__((packed)); - -struct reiser4_super_block { - unsigned char rs4_magic[16]; - uint16_t rs4_dummy[2]; - unsigned char rs4_uuid[16]; - unsigned char rs4_label[16]; - uint64_t rs4_dummy2; -} __attribute__((packed)); - -static int probe_reiser(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct reiserfs_super_block *rs; - unsigned int blocksize; - - rs = blkid_probe_get_sb(pr, mag, struct reiserfs_super_block); - if (!rs) - return -1; - - blocksize = le16_to_cpu(rs->rs_blocksize); - - /* The blocksize must be at least 1k */ - if ((blocksize >> 10) == 0) - return -BLKID_ERR_PARAM; - - /* If the superblock is inside the journal, we have the wrong one */ - if (mag->kboff / (blocksize >> 10) > le32_to_cpu(rs->rs_journal_block)) - return -BLKID_ERR_BIG; - - /* LABEL/UUID are only valid for later versions of Reiserfs v3.6. */ - if (mag->magic[6] == '2' || mag->magic[6] == '3') { - if (*rs->rs_label) - blkid_probe_set_label(pr, - (unsigned char *) rs->rs_label, - sizeof(rs->rs_label)); - blkid_probe_set_uuid(pr, rs->rs_uuid); - } - - if (mag->magic[6] == '3') - blkid_probe_set_version(pr, "JR"); - else if (mag->magic[6] == '2') - blkid_probe_set_version(pr, "3.6"); - else - blkid_probe_set_version(pr, "3.5"); - - return 0; -} - -static int probe_reiser4(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct reiser4_super_block *rs4; - - rs4 = blkid_probe_get_sb(pr, mag, struct reiser4_super_block); - if (!rs4) - return -1; - - if (*rs4->rs4_label) - blkid_probe_set_label(pr, rs4->rs4_label, sizeof(rs4->rs4_label)); - blkid_probe_set_uuid(pr, rs4->rs4_uuid); - blkid_probe_set_version(pr, "4"); - - return 0; -} - - -const struct blkid_idinfo reiser_idinfo = -{ - .name = "reiserfs", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_reiser, - .minsz = 4096 * 512, /* not sure, this is minimal size of journal */ - .magics = - { - { .magic = "ReIsErFs", .len = 8, .kboff = 8, .sboff = 0x34 }, - { .magic = "ReIsEr2Fs", .len = 9, .kboff = 64, .sboff = 0x34 }, - { .magic = "ReIsEr3Fs", .len = 9, .kboff = 64, .sboff = 0x34 }, - { .magic = "ReIsErFs", .len = 8, .kboff = 64, .sboff = 0x34 }, - { .magic = "ReIsErFs", .len = 8, .kboff = 8, .sboff = 20 }, - { NULL } - } -}; - -const struct blkid_idinfo reiser4_idinfo = -{ - .name = "reiser4", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_reiser4, - .minsz = 4096 * 512, /* not sure, this is minimal size of journal */ - .magics = - { - { .magic = "ReIsEr4", .len = 7, .kboff = 64 }, - { NULL } - } -}; - - - - diff --git a/shlibs/blkid/src/superblocks/romfs.c b/shlibs/blkid/src/superblocks/romfs.c deleted file mode 100644 index 91ef996f..00000000 --- a/shlibs/blkid/src/superblocks/romfs.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 1999, 2001 by Andries Brouwer - * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o - * Copyright (C) 2008 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "superblocks.h" - -struct romfs_super_block { - unsigned char ros_magic[8]; - uint32_t ros_dummy1[2]; - unsigned char ros_volume[16]; -} __attribute__((packed)); - -static int probe_romfs(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct romfs_super_block *ros; - - ros = blkid_probe_get_sb(pr, mag, struct romfs_super_block); - if (!ros) - return -1; - - if (strlen((char *) ros->ros_volume)) - blkid_probe_set_label(pr, ros->ros_volume, - sizeof(ros->ros_volume)); - return 0; -} - -const struct blkid_idinfo romfs_idinfo = -{ - .name = "romfs", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_romfs, - .magics = - { - { .magic = "-rom1fs-", .len = 8 }, - { NULL } - } -}; - diff --git a/shlibs/blkid/src/superblocks/silicon_raid.c b/shlibs/blkid/src/superblocks/silicon_raid.c deleted file mode 100644 index b72b7276..00000000 --- a/shlibs/blkid/src/superblocks/silicon_raid.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2008 Karel Zak - * Copyright (C) 2005 Kay Sievers - * - * Inspired by libvolume_id by - * Kay Sievers - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "superblocks.h" - -struct silicon_metadata { - 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; -} __attribute__((packed)); - -#define SILICON_MAGIC 0x2F000000 - - -static int probe_silraid(blkid_probe pr, const struct blkid_idmag *mag) -{ - uint64_t off; - struct silicon_metadata *sil; - - if (pr->size < 0x10000) - return -1; - if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) - return -1; - - off = ((pr->size / 0x200) - 1) * 0x200; - - sil = (struct silicon_metadata *) - blkid_probe_get_buffer(pr, off, - sizeof(struct silicon_metadata)); - if (!sil) - return -1; - - if (le32_to_cpu(sil->magic) != SILICON_MAGIC) - return -1; - - if (blkid_probe_sprintf_version(pr, "%u.%u", - le16_to_cpu(sil->major_ver), - le16_to_cpu(sil->minor_ver)) != 0) - return -1; - if (blkid_probe_set_magic(pr, - off + offsetof(struct silicon_metadata, magic), - sizeof(sil->magic), - (unsigned char *) &sil->magic)) - return -1; - return 0; -} - -const struct blkid_idinfo silraid_idinfo = { - .name = "silicon_medley_raid_member", - .usage = BLKID_USAGE_RAID, - .probefunc = probe_silraid, - .magics = BLKID_NONE_MAGIC -}; - - diff --git a/shlibs/blkid/src/superblocks/squashfs.c b/shlibs/blkid/src/superblocks/squashfs.c deleted file mode 100644 index 45f10291..00000000 --- a/shlibs/blkid/src/superblocks/squashfs.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2008 Karel Zak - * - * Inspired by libvolume_id by - * Kay Sievers - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include - -#include "bitops.h" /* swab16() */ -#include "superblocks.h" - -struct sqsh_super_block { - 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; -} __attribute__((packed)); - -static int probe_squashfs(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct sqsh_super_block *sq; - - sq = blkid_probe_get_sb(pr, mag, struct sqsh_super_block); - if (!sq) - return -1; - - if (strcmp(mag->magic, "sqsh") == 0 || - strcmp(mag->magic, "qshs") == 0) - blkid_probe_sprintf_version(pr, "%u.%u", - sq->s_major, - sq->s_minor); - else - blkid_probe_sprintf_version(pr, "%u.%u", - swab16(sq->s_major), - swab16(sq->s_minor)); - return 0; -} - -const struct blkid_idinfo squashfs_idinfo = -{ - .name = "squashfs", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_squashfs, - .magics = - { - { .magic = "sqsh", .len = 4 }, - { .magic = "hsqs", .len = 4 }, /* swap */ - - /* LZMA version */ - { .magic = "qshs", .len = 4 }, - { .magic = "shsq", .len = 4 }, /* swap */ - { NULL } - } -}; - - diff --git a/shlibs/blkid/src/superblocks/superblocks.c b/shlibs/blkid/src/superblocks/superblocks.c deleted file mode 100644 index 56a45433..00000000 --- a/shlibs/blkid/src/superblocks/superblocks.c +++ /dev/null @@ -1,754 +0,0 @@ -/* - * superblocks.c - reads information from filesystem and raid superblocks - * - * Copyright (C) 2008-2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "superblocks.h" - -/** - * SECTION:superblocks - * @title: Superblocks probing - * @short_description: filesystems and raids superblocks probing. - * - * The library API has been originaly designed for superblocks probing only. - * This is reason why some *deprecated* superblock specific functions don't use - * '_superblocks_' namespace in the function name. Please, don't use these - * functions in new code. - * - * The 'superblocks' probers support NAME=value (tags) interface only. The - * superblocks probing is enabled by default (and controled by - * blkid_probe_enable_superblocks()). - * - * Currently supported tags: - * - * @TYPE: filesystem type - * - * @SEC_TYPE: secondary filesystem type - * - * @LABEL: filesystem label - * - * @LABEL_RAW: raw label from FS superblock - * - * @UUID: filesystem UUID (lower case) - * - * @UUID_SUB: subvolume uuid (e.g. btrfs) - * - * @UUID_RAW: raw UUID from FS superblock - * - * @EXT_JOURNAL: external journal UUID - * - * @USAGE: usage string: "raid", "filesystem", ... - * - * @VERSION: filesystem version - * - * @MOUNT: cluster mount name (?) -- ocfs only - * - * @SBMAGIC: super block magic string - * - * @SBMAGIC_OFFSET: offset of SBMAGIC - * - * @FSSIZE: size of filessystem [not-implemented yet] - */ - -static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn); -static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn); - -static int blkid_probe_set_usage(blkid_probe pr, int usage); - - -/* - * Superblocks chains probing functions - */ -static const struct blkid_idinfo *idinfos[] = -{ - /* RAIDs */ - &linuxraid_idinfo, - &ddfraid_idinfo, - &iswraid_idinfo, - &lsiraid_idinfo, - &viaraid_idinfo, - &silraid_idinfo, - &nvraid_idinfo, - &pdcraid_idinfo, - &highpoint45x_idinfo, - &highpoint37x_idinfo, - &adraid_idinfo, - &jmraid_idinfo, - - &drbd_idinfo, - &lvm2_idinfo, - &lvm1_idinfo, - &snapcow_idinfo, - &luks_idinfo, - &vmfs_volume_idinfo, - - /* Filesystems */ - &vfat_idinfo, - &swsuspend_idinfo, - &swap_idinfo, - &xfs_idinfo, - &ext4dev_idinfo, - &ext4_idinfo, - &ext3_idinfo, - &ext2_idinfo, - &jbd_idinfo, - &reiser_idinfo, - &reiser4_idinfo, - &jfs_idinfo, - &udf_idinfo, - &iso9660_idinfo, - &zfs_idinfo, - &hfsplus_idinfo, - &hfs_idinfo, - &ufs_idinfo, - &hpfs_idinfo, - &sysv_idinfo, - &xenix_idinfo, - &ntfs_idinfo, - &cramfs_idinfo, - &romfs_idinfo, - &minix_idinfo, - &gfs_idinfo, - &gfs2_idinfo, - &ocfs_idinfo, - &ocfs2_idinfo, - &oracleasm_idinfo, - &vxfs_idinfo, - &squashfs_idinfo, - &netware_idinfo, - &btrfs_idinfo, - &ubifs_idinfo, - &bfs_idinfo, - &vmfs_fs_idinfo, - &befs_idinfo, - &nilfs2_idinfo, - &exfat_idinfo -}; - -/* - * Driver definition - */ -const struct blkid_chaindrv superblocks_drv = { - .id = BLKID_CHAIN_SUBLKS, - .name = "superblocks", - .dflt_enabled = TRUE, - .dflt_flags = BLKID_SUBLKS_DEFAULT, - .idinfos = idinfos, - .nidinfos = ARRAY_SIZE(idinfos), - .has_fltr = TRUE, - .probe = superblocks_probe, - .safeprobe = superblocks_safeprobe, -}; - -/** - * blkid_probe_enable_superblocks: - * @pr: probe - * @enable: TRUE/FALSE - * - * Enables/disables the superblocks probing for non-binary interface. - * - * Returns: 0 on success, or -1 in case of error. - */ -int blkid_probe_enable_superblocks(blkid_probe pr, int enable) -{ - if (!pr) - return -1; - pr->chains[BLKID_CHAIN_SUBLKS].enabled = enable; - return 0; -} - -/** - * blkid_probe_set_superblocks_flags: - * @pr: prober - * @flags: BLKID_SUBLKS_* flags - * - * Sets probing flags to the superblocks prober. This function is optional, the - * default are BLKID_SUBLKS_DEFAULTS flags. - * - * Returns: 0 on success, or -1 in case of error. - */ -int blkid_probe_set_superblocks_flags(blkid_probe pr, int flags) -{ - if (!pr) - return -1; - - pr->chains[BLKID_CHAIN_SUBLKS].flags = flags; - return 0; -} - -/** - * blkid_probe_reset_superblocks_filter: - * @pr: prober - * - * Resets superblocks probing filter - * - * Returns: 0 on success, or -1 in case of error. - */ -int blkid_probe_reset_superblocks_filter(blkid_probe pr) -{ - return __blkid_probe_reset_filter(pr, BLKID_CHAIN_SUBLKS); -} - -/** - * blkid_probe_invert_superblocks_filter: - * @pr: prober - * - * Inverts superblocks probing filter - * - * Returns: 0 on success, or -1 in case of error. - */ -int blkid_probe_invert_superblocks_filter(blkid_probe pr) -{ - return __blkid_probe_invert_filter(pr, BLKID_CHAIN_SUBLKS); -} - -/** - * blkid_probe_filter_superblocks_type: - * @pr: prober - * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag - * @names: NULL terminated array of probing function names (e.g. "vfat"). - * - * BLKID_FLTR_NOTIN - probe for all items which are NOT IN @names - * BLKID_FLTR_ONLYIN - probe for items which are IN @names - * - * Returns: 0 on success, or -1 in case of error. - */ -int blkid_probe_filter_superblocks_type(blkid_probe pr, int flag, char *names[]) -{ - return __blkid_probe_filter_types(pr, BLKID_CHAIN_SUBLKS, flag, names); -} - -/** - * blkid_probe_filter_superblocks_usage: - * @pr: prober - * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag - * @usage: BLKID_USAGE_* flags - * - * BLKID_FLTR_NOTIN - probe for all items which are NOT IN @usage - * BLKID_FLTR_ONLYIN - probe for items which are IN @usage - * - * Returns: 0 on success, or -1 in case of error. - */ -int blkid_probe_filter_superblocks_usage(blkid_probe pr, int flag, int usage) -{ - unsigned long *fltr; - struct blkid_chain *chn; - int i; - - if (!pr) - return -1; - - fltr = blkid_probe_get_filter(pr, BLKID_CHAIN_SUBLKS, TRUE); - if (!fltr) - return -1; - - chn = &pr->chains[BLKID_CHAIN_SUBLKS]; - - for (i = 0; i < chn->driver->nidinfos; i++) { - const struct blkid_idinfo *id = chn->driver->idinfos[i]; - - if (id->usage & usage) { - if (flag & BLKID_FLTR_NOTIN) - blkid_bmp_set_item(chn->fltr, i); - } else if (flag & BLKID_FLTR_ONLYIN) - blkid_bmp_set_item(chn->fltr, i); - } - DBG(DEBUG_LOWPROBE, printf("a new probing usage-filter initialized\n")); - return 0; -} - -/** - * blkid_known_fstype: - * @fstype: filesystem name - * - * Returns: 1 for known filesytems, or 0 for unknown filesystem. - */ -int blkid_known_fstype(const char *fstype) -{ - int i; - - if (!fstype) - return 0; - - for (i = 0; i < ARRAY_SIZE(idinfos); i++) { - const struct blkid_idinfo *id = idinfos[i]; - if (strcmp(id->name, fstype) == 0) - return 1; - } - return 0; -} - -/* - * The blkid_do_probe() backend. - */ -static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn) -{ - int i = 0; - - if (!pr || chn->idx < -1) - return -1; - blkid_probe_chain_reset_vals(pr, chn); - - DBG(DEBUG_LOWPROBE, - printf("--> starting probing loop [SUBLKS idx=%d]\n", - chn->idx)); - - if (pr->size <= 0 || (pr->size <= 1024 && !S_ISCHR(pr->mode))) - /* Ignore very very small block devices or regular files (e.g. - * extended partitions). Note that size of the UBI char devices - * is 1 byte */ - goto nothing; - - i = chn->idx + 1; - - for ( ; i < ARRAY_SIZE(idinfos); i++) { - const struct blkid_idinfo *id; - const struct blkid_idmag *mag = NULL; - blkid_loff_t off = 0; - - chn->idx = i; - - if (chn->fltr && blkid_bmp_get_item(chn->fltr, i)) - continue; - - id = idinfos[i]; - - if (id->minsz && id->minsz > pr->size) - continue; /* the device is too small */ - - mag = id->magics ? &id->magics[0] : NULL; - - /* don't probe for RAIDs, swap or journal on CD/DVDs */ - if ((id->usage & (BLKID_USAGE_RAID | BLKID_USAGE_OTHER)) && - blkid_probe_is_cdrom(pr)) - continue; - - /* don't probe for RAIDs on floppies */ - if ((id->usage & BLKID_USAGE_RAID) && blkid_probe_is_tiny(pr)) - continue; - - DBG(DEBUG_LOWPROBE, printf("[%d] %s:\n", i, id->name)); - - if (blkid_probe_get_idmag(pr, id, &off, &mag)) - continue; - - /* final check by probing function */ - if (id->probefunc) { - DBG(DEBUG_LOWPROBE, printf("\tcall probefunc()\n")); - if (id->probefunc(pr, mag) != 0) { - blkid_probe_chain_reset_vals(pr, chn); - continue; - } - } - - /* all cheks passed */ - if (chn->flags & BLKID_SUBLKS_TYPE) - blkid_probe_set_value(pr, "TYPE", - (unsigned char *) id->name, - strlen(id->name) + 1); - - blkid_probe_set_usage(pr, id->usage); - - if (mag) - blkid_probe_set_magic(pr, off, mag->len, - (unsigned char *) mag->magic); - - DBG(DEBUG_LOWPROBE, - printf("<-- leaving probing loop (type=%s) [SUBLKS idx=%d]\n", - id->name, chn->idx)); - return 0; - } - -nothing: - DBG(DEBUG_LOWPROBE, - printf("<-- leaving probing loop (failed) [SUBLKS idx=%d]\n", - chn->idx)); - return 1; -} - -/* - * This is the same function as blkid_do_probe(), but returns only one result - * (cannot be used in while()) and checks for ambivalen results (more - * filesystems on the device) -- in such case returns -2. - * - * The function does not check for filesystems when a RAID or crypto signature - * is detected. The function also does not check for collision between RAIDs - * and crypto devices. The first detected RAID or crypto device is returned. - * - * The function does not probe for ambivalent results on very small devices - * (e.g. floppies), on small devices the first detected filesystem is returned. - */ -static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn) -{ - struct blkid_prval vals[BLKID_NVALS_SUBLKS]; - int nvals = BLKID_NVALS_SUBLKS; - int idx = -1; - int count = 0; - int intol = 0; - int rc; - - while ((rc = superblocks_probe(pr, chn)) == 0) { - - if (blkid_probe_is_tiny(pr) && !count) - /* floppy or so -- returns the first result. */ - return 0; - - count++; - - if (idinfos[chn->idx]->usage & (BLKID_USAGE_RAID | BLKID_USAGE_CRYPTO)) - break; - - if (!(idinfos[chn->idx]->flags & BLKID_IDINFO_TOLERANT)) - intol++; - - if (count == 1) { - /* save the first result */ - nvals = blkid_probe_chain_copy_vals(pr, chn, vals, nvals); - idx = chn->idx; - } - } - - if (rc < 0) - return rc; /* error */ - - if (count > 1 && intol) { - DBG(DEBUG_LOWPROBE, - printf("ERROR: superblocks chain: " - "ambivalent result detected (%d filesystems)!\n", - count)); - return -2; /* error, ambivalent result (more FS) */ - } - if (!count) - return 1; /* nothing detected */ - - if (idx != -1) { - /* restore the first result */ - blkid_probe_chain_reset_vals(pr, chn); - blkid_probe_append_vals(pr, vals, nvals); - chn->idx = idx; - } - - /* - * The RAID device could be partitioned. The problem are RAID1 devices - * where the partition table is visible from underlaying devices. We - * have to ignore such partition tables. - */ - if (chn->idx >= 0 && idinfos[chn->idx]->usage & BLKID_USAGE_RAID) - pr->prob_flags |= BLKID_PROBE_FL_IGNORE_PT; - - return 0; -} - -int blkid_probe_set_magic(blkid_probe pr, blkid_loff_t offset, - size_t len, unsigned char *magic) -{ - int rc = 0; - struct blkid_chain *chn = blkid_probe_get_chain(pr); - - if (magic && len && (chn->flags & BLKID_SUBLKS_MAGIC)) { - rc = blkid_probe_set_value(pr, "SBMAGIC", magic, len); - if (!rc) - rc = blkid_probe_sprintf_value(pr, "SBMAGIC_OFFSET", - "%llu", offset); - } - return rc; -} - -int blkid_probe_set_version(blkid_probe pr, const char *version) -{ - struct blkid_chain *chn = blkid_probe_get_chain(pr); - - if (chn->flags & BLKID_SUBLKS_VERSION) - return blkid_probe_set_value(pr, "VERSION", - (unsigned char *) version, strlen(version) + 1); - return 0; -} - -int blkid_probe_sprintf_version(blkid_probe pr, const char *fmt, ...) -{ - struct blkid_chain *chn = blkid_probe_get_chain(pr); - int rc = 0; - - if (chn->flags & BLKID_SUBLKS_VERSION) { - va_list ap; - - va_start(ap, fmt); - rc = blkid_probe_vsprintf_value(pr, "VERSION", fmt, ap); - va_end(ap); - } - return rc; -} - -static int blkid_probe_set_usage(blkid_probe pr, int usage) -{ - struct blkid_chain *chn = blkid_probe_get_chain(pr); - char *u = NULL; - - if (!(chn->flags & BLKID_SUBLKS_USAGE)) - return 0; - - if (usage & BLKID_USAGE_FILESYSTEM) - u = "filesystem"; - else if (usage & BLKID_USAGE_RAID) - u = "raid"; - else if (usage & BLKID_USAGE_CRYPTO) - u = "crypto"; - else if (usage & BLKID_USAGE_OTHER) - u = "other"; - else - u = "unknown"; - - return blkid_probe_set_value(pr, "USAGE", (unsigned char *) u, strlen(u) + 1); -} - -int blkid_probe_set_label(blkid_probe pr, unsigned char *label, size_t len) -{ - struct blkid_chain *chn = blkid_probe_get_chain(pr); - struct blkid_prval *v; - if (len > BLKID_PROBVAL_BUFSIZ) - len = BLKID_PROBVAL_BUFSIZ; - - if ((chn->flags & BLKID_SUBLKS_LABELRAW) && - blkid_probe_set_value(pr, "LABEL_RAW", label, len) < 0) - return -1; - if (!(chn->flags & BLKID_SUBLKS_LABEL)) - return 0; - v = blkid_probe_assign_value(pr, "LABEL"); - if (!v) - return -1; - - if (len == BLKID_PROBVAL_BUFSIZ) - len--; /* make a space for \0 */ - - memcpy(v->data, label, len); - v->data[len] = '\0'; - - v->len = blkid_rtrim_whitespace(v->data) + 1; - if (v->len == 1) - blkid_probe_reset_last_value(pr); - return 0; -} - -int blkid_probe_set_utf8label(blkid_probe pr, unsigned char *label, - size_t len, int enc) -{ - struct blkid_chain *chn = blkid_probe_get_chain(pr); - struct blkid_prval *v; - - if ((chn->flags & BLKID_SUBLKS_LABELRAW) && - blkid_probe_set_value(pr, "LABEL_RAW", label, len) < 0) - return -1; - if (!(chn->flags & BLKID_SUBLKS_LABEL)) - return 0; - v = blkid_probe_assign_value(pr, "LABEL"); - if (!v) - return -1; - - blkid_encode_to_utf8(enc, v->data, sizeof(v->data), label, len); - v->len = blkid_rtrim_whitespace(v->data) + 1; - if (v->len == 1) - blkid_probe_reset_last_value(pr); - return 0; -} - -/* like uuid_is_null() from libuuid, but works with arbitrary size of UUID */ -static int uuid_is_empty(const unsigned char *buf, size_t len) -{ - int i; - - for (i = 0; i < len; i++) - if (buf[i]) - return 0; - return 1; -} - -int blkid_probe_sprintf_uuid(blkid_probe pr, unsigned char *uuid, - size_t len, const char *fmt, ...) -{ - struct blkid_chain *chn = blkid_probe_get_chain(pr); - int rc = -1; - va_list ap; - - if (len > BLKID_PROBVAL_BUFSIZ) - len = BLKID_PROBVAL_BUFSIZ; - - if (uuid_is_empty(uuid, len)) - return 0; - - if ((chn->flags & BLKID_SUBLKS_UUIDRAW) && - blkid_probe_set_value(pr, "UUID_RAW", uuid, len) < 0) - return -1; - if (!(chn->flags & BLKID_SUBLKS_UUID)) - return 0; - - va_start(ap, fmt); - rc = blkid_probe_vsprintf_value(pr, "UUID", fmt, ap); - va_end(ap); - - /* convert to lower case (..be paranoid) */ - if (!rc) { - int i; - struct blkid_prval *v = __blkid_probe_get_value(pr, - blkid_probe_numof_values(pr)); - if (v) { - for (i = 0; i < v->len; i++) - if (v->data[i] >= 'A' && v->data[i] <= 'F') - v->data[i] = (v->data[i] - 'A') + 'a'; - } - } - return rc; -} - -/* function to set UUIDs that are in suberblocks stored as strings */ -int blkid_probe_strncpy_uuid(blkid_probe pr, unsigned char *str, size_t len) -{ - struct blkid_chain *chn = blkid_probe_get_chain(pr); - struct blkid_prval *v; - - if (str == NULL || *str == '\0') - return -1; - if (!len) - len = strlen((char *) str); - if (len > BLKID_PROBVAL_BUFSIZ) - len = BLKID_PROBVAL_BUFSIZ; - - if ((chn->flags & BLKID_SUBLKS_UUIDRAW) && - blkid_probe_set_value(pr, "UUID_RAW", str, len) < 0) - return -1; - if (!(chn->flags & BLKID_SUBLKS_UUID)) - return 0; - - v = blkid_probe_assign_value(pr, "UUID"); - if (v) { - if (len == BLKID_PROBVAL_BUFSIZ) - len--; /* make a space for \0 */ - - memcpy((char *) v->data, str, len); - v->data[len] = '\0'; - v->len = len + 1; - return 0; - } - return -1; -} - -/* default _set_uuid function to set DCE UUIDs */ -int blkid_probe_set_uuid_as(blkid_probe pr, unsigned char *uuid, const char *name) -{ - struct blkid_chain *chn = blkid_probe_get_chain(pr); - struct blkid_prval *v; - - if (uuid_is_empty(uuid, 16)) - return 0; - - if (!name) { - if ((chn->flags & BLKID_SUBLKS_UUIDRAW) && - blkid_probe_set_value(pr, "UUID_RAW", uuid, 16) < 0) - return -1; - if (!(chn->flags & BLKID_SUBLKS_UUID)) - return 0; - - v = blkid_probe_assign_value(pr, "UUID"); - } else - v = blkid_probe_assign_value(pr, name); - - blkid_unparse_uuid(uuid, (char *) v->data, sizeof(v->data)); - v->len = 37; - - return 0; -} - -int blkid_probe_set_uuid(blkid_probe pr, unsigned char *uuid) -{ - return blkid_probe_set_uuid_as(pr, uuid, NULL); -} - -/* - * DEPRECATED FUNCTIONS - */ - -/** - * blkid_probe_set_request: - * @pr: probe - * @flags: BLKID_PROBREQ_* (deprecated) or BLKID_SUBLKS_* flags - * - * Returns: 0 on success, or -1 in case of error. - * - * Deprecated: Use blkid_probe_set_superblocks_flags(). - */ -int blkid_probe_set_request(blkid_probe pr, int flags) -{ - return blkid_probe_set_superblocks_flags(pr, flags); -} - -/** - * blkid_probe_reset_filter: - * @pr: prober - * - * Returns: 0 on success, or -1 in case of error. - * - * Deprecated: Use blkid_probe_reset_superblocks_filter(). - */ -int blkid_probe_reset_filter(blkid_probe pr) -{ - return __blkid_probe_reset_filter(pr, BLKID_CHAIN_SUBLKS); -} - -/** - * blkid_probe_invert_filter: - * @pr: prober - * - * Returns: 0 on success, or -1 in case of error. - * - * Deprecated: Use blkid_probe_invert_superblocks_filter(). - */ -int blkid_probe_invert_filter(blkid_probe pr) -{ - return __blkid_probe_invert_filter(pr, BLKID_CHAIN_SUBLKS); -} - -/** - * blkid_probe_filter_types - * @pr: prober - * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag - * @names: NULL terminated array of probing function names (e.g. "vfat"). - * - * Returns: 0 on success, or -1 in case of error. - * - * Deprecated: Use blkid_probe_filter_superblocks_types(). - */ -int blkid_probe_filter_types(blkid_probe pr, int flag, char *names[]) -{ - return __blkid_probe_filter_types(pr, BLKID_CHAIN_SUBLKS, flag, names); -} - -/** - * blkid_probe_filter_usage - * @pr: prober - * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag - * @usage: BLKID_USAGE_* flags - * - * Returns: 0 on success, or -1 in case of error. - * - * Deprecated: Use blkid_probe_filter_superblocks_usage(). - */ -int blkid_probe_filter_usage(blkid_probe pr, int flag, int usage) -{ - return blkid_probe_filter_superblocks_usage(pr, flag, usage); -} - diff --git a/shlibs/blkid/src/superblocks/superblocks.h b/shlibs/blkid/src/superblocks/superblocks.h deleted file mode 100644 index a79d7cb6..00000000 --- a/shlibs/blkid/src/superblocks/superblocks.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2008-2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#ifndef _BLKID_SUPERBLOCKS_H -#define _BLKID_SUPERBLOCKS_H - -#include "blkidP.h" - -extern const struct blkid_idinfo cramfs_idinfo; -extern const struct blkid_idinfo swap_idinfo; -extern const struct blkid_idinfo swsuspend_idinfo; -extern const struct blkid_idinfo adraid_idinfo; -extern const struct blkid_idinfo ddfraid_idinfo; -extern const struct blkid_idinfo iswraid_idinfo; -extern const struct blkid_idinfo jmraid_idinfo; -extern const struct blkid_idinfo lsiraid_idinfo; -extern const struct blkid_idinfo nvraid_idinfo; -extern const struct blkid_idinfo pdcraid_idinfo; -extern const struct blkid_idinfo silraid_idinfo; -extern const struct blkid_idinfo viaraid_idinfo; -extern const struct blkid_idinfo linuxraid_idinfo; -extern const struct blkid_idinfo ext4dev_idinfo; -extern const struct blkid_idinfo ext4_idinfo; -extern const struct blkid_idinfo ext3_idinfo; -extern const struct blkid_idinfo ext2_idinfo; -extern const struct blkid_idinfo jbd_idinfo; -extern const struct blkid_idinfo jfs_idinfo; -extern const struct blkid_idinfo xfs_idinfo; -extern const struct blkid_idinfo gfs_idinfo; -extern const struct blkid_idinfo gfs2_idinfo; -extern const struct blkid_idinfo romfs_idinfo; -extern const struct blkid_idinfo ocfs_idinfo; -extern const struct blkid_idinfo ocfs2_idinfo; -extern const struct blkid_idinfo oracleasm_idinfo; -extern const struct blkid_idinfo reiser_idinfo; -extern const struct blkid_idinfo reiser4_idinfo; -extern const struct blkid_idinfo hfs_idinfo; -extern const struct blkid_idinfo hfsplus_idinfo; -extern const struct blkid_idinfo ntfs_idinfo; -extern const struct blkid_idinfo iso9660_idinfo; -extern const struct blkid_idinfo udf_idinfo; -extern const struct blkid_idinfo vxfs_idinfo; -extern const struct blkid_idinfo minix_idinfo; -extern const struct blkid_idinfo vfat_idinfo; -extern const struct blkid_idinfo ufs_idinfo; -extern const struct blkid_idinfo hpfs_idinfo; -extern const struct blkid_idinfo lvm2_idinfo; -extern const struct blkid_idinfo lvm1_idinfo; -extern const struct blkid_idinfo snapcow_idinfo; -extern const struct blkid_idinfo luks_idinfo; -extern const struct blkid_idinfo highpoint37x_idinfo; -extern const struct blkid_idinfo highpoint45x_idinfo; -extern const struct blkid_idinfo squashfs_idinfo; -extern const struct blkid_idinfo netware_idinfo; -extern const struct blkid_idinfo sysv_idinfo; -extern const struct blkid_idinfo xenix_idinfo; -extern const struct blkid_idinfo btrfs_idinfo; -extern const struct blkid_idinfo ubifs_idinfo; -extern const struct blkid_idinfo zfs_idinfo; -extern const struct blkid_idinfo bfs_idinfo; -extern const struct blkid_idinfo vmfs_volume_idinfo; -extern const struct blkid_idinfo vmfs_fs_idinfo; -extern const struct blkid_idinfo drbd_idinfo; -extern const struct blkid_idinfo befs_idinfo; -extern const struct blkid_idinfo nilfs2_idinfo; -extern const struct blkid_idinfo exfat_idinfo; - -/* - * superblock functions - */ -extern int blkid_probe_set_magic(blkid_probe pr, blkid_loff_t offset, - size_t len, unsigned char *magic); -extern int blkid_probe_set_version(blkid_probe pr, const char *version); -extern int blkid_probe_sprintf_version(blkid_probe pr, const char *fmt, ...) - __attribute__ ((format (printf, 2, 3))); - -extern int blkid_probe_set_label(blkid_probe pr, unsigned char *label, size_t len); -extern int blkid_probe_set_utf8label(blkid_probe pr, unsigned char *label, - size_t len, int enc); -extern int blkid_probe_sprintf_uuid(blkid_probe pr, unsigned char *uuid, - size_t len, const char *fmt, ...) - __attribute__ ((format (printf, 4, 5))); -extern int blkid_probe_strncpy_uuid(blkid_probe pr, unsigned char *str, size_t len); - -extern int blkid_probe_set_uuid(blkid_probe pr, unsigned char *uuid); -extern int blkid_probe_set_uuid_as(blkid_probe pr, unsigned char *uuid, const char *name); - - -#endif /* _BLKID_SUPERBLOCKS_H */ diff --git a/shlibs/blkid/src/superblocks/swap.c b/shlibs/blkid/src/superblocks/swap.c deleted file mode 100644 index 325a8faf..00000000 --- a/shlibs/blkid/src/superblocks/swap.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 1999 by Andries Brouwer - * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o - * Copyright (C) 2001 by Andreas Dilger - * Copyright (C) 2004 Kay Sievers - * Copyright (C) 2008 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include -#include -#include - -#include "superblocks.h" - -/* linux-2.6/include/linux/swap.h */ -struct swap_header_v1_2 { - /* char bootbits[1024]; */ /* Space for disklabel etc. */ - uint32_t version; - uint32_t lastpage; - uint32_t nr_badpages; - unsigned char uuid[16]; - unsigned char volume[16]; - uint32_t padding[117]; - uint32_t badpages[1]; -} __attribute__((packed)); - -#define PAGESIZE_MIN 0xff6 /* 4086 (arm, i386, ...) */ -#define PAGESIZE_MAX 0xfff6 /* 65526 (ia64) */ - -#define TOI_MAGIC_STRING "\xed\xc3\x02\xe9\x98\x56\xe5\x0c" -#define TOI_MAGIC_STRLEN (sizeof(TOI_MAGIC_STRING) - 1) - -static int swap_set_info(blkid_probe pr, const char *version) -{ - struct swap_header_v1_2 *hdr; - - /* Swap header always located at offset of 1024 bytes */ - hdr = (struct swap_header_v1_2 *) blkid_probe_get_buffer(pr, 1024, - sizeof(struct swap_header_v1_2)); - if (!hdr) - return -1; - - /* SWAPSPACE2 - check for wrong version or zeroed pagecount */ - if (strcmp(version, "2") == 0 && - (hdr->version != 1 || hdr->lastpage == 0)) - return -1; - - /* arbitrary sanity check.. is there any garbage down there? */ - if (hdr->padding[32] == 0 && hdr->padding[33] == 0) { - if (hdr->volume[0] && blkid_probe_set_label(pr, hdr->volume, - sizeof(hdr->volume)) < 0) - return -1; - if (hdr->uuid[0] && blkid_probe_set_uuid(pr, hdr->uuid) < 0) - return -1; - } - - blkid_probe_set_version(pr, version); - return 0; -} - -static int probe_swap(blkid_probe pr, const struct blkid_idmag *mag) -{ - unsigned char *buf; - - if (!mag) - return -1; - - /* TuxOnIce keeps valid swap header at the end of the 1st page */ - buf = blkid_probe_get_buffer(pr, 0, TOI_MAGIC_STRLEN); - if (!buf) - return -1; - - if (memcmp(buf, TOI_MAGIC_STRING, TOI_MAGIC_STRLEN) == 0) - return 1; /* Ignore swap signature, it's TuxOnIce */ - - if (!memcmp(mag->magic, "SWAP-SPACE", mag->len)) { - /* swap v0 doesn't support LABEL or UUID */ - blkid_probe_set_version(pr, "1"); - return 0; - - } else if (!memcmp(mag->magic, "SWAPSPACE2", mag->len)) - return swap_set_info(pr, "2"); - - return -1; -} - -static int probe_swsuspend(blkid_probe pr, const struct blkid_idmag *mag) -{ - if (!mag) - return -1; - if (!memcmp(mag->magic, "S1SUSPEND", mag->len)) - return swap_set_info(pr, "s1suspend"); - if (!memcmp(mag->magic, "S2SUSPEND", mag->len)) - return swap_set_info(pr, "s2suspend"); - if (!memcmp(mag->magic, "ULSUSPEND", mag->len)) - return swap_set_info(pr, "ulsuspend"); - if (!memcmp(mag->magic, TOI_MAGIC_STRING, mag->len)) - return swap_set_info(pr, "tuxonice"); - if (!memcmp(mag->magic, "LINHIB0001", mag->len)) - return swap_set_info(pr, "linhib0001"); - - return -1; /* no signature detected */ -} - -const struct blkid_idinfo swap_idinfo = -{ - .name = "swap", - .usage = BLKID_USAGE_OTHER, - .probefunc = probe_swap, - .minsz = 10 * 4096, /* 10 pages */ - .magics = - { - { "SWAP-SPACE", 10, 0, 0xff6 }, - { "SWAPSPACE2", 10, 0, 0xff6 }, - { "SWAP-SPACE", 10, 0, 0x1ff6 }, - { "SWAPSPACE2", 10, 0, 0x1ff6 }, - { "SWAP-SPACE", 10, 0, 0x3ff6 }, - { "SWAPSPACE2", 10, 0, 0x3ff6 }, - { "SWAP-SPACE", 10, 0, 0x7ff6 }, - { "SWAPSPACE2", 10, 0, 0x7ff6 }, - { "SWAP-SPACE", 10, 0, 0xfff6 }, - { "SWAPSPACE2", 10, 0, 0xfff6 }, - { NULL } - } -}; - - -const struct blkid_idinfo swsuspend_idinfo = -{ - .name = "swsuspend", - .usage = BLKID_USAGE_OTHER, - .probefunc = probe_swsuspend, - .minsz = 10 * 4096, /* 10 pages */ - .magics = - { - { TOI_MAGIC_STRING, TOI_MAGIC_STRLEN, 0, 0 }, - { "S1SUSPEND", 9, 0, 0xff6 }, - { "S2SUSPEND", 9, 0, 0xff6 }, - { "ULSUSPEND", 9, 0, 0xff6 }, - { "LINHIB0001",10,0, 0xff6 }, - - { "S1SUSPEND", 9, 0, 0x1ff6 }, - { "S2SUSPEND", 9, 0, 0x1ff6 }, - { "ULSUSPEND", 9, 0, 0x1ff6 }, - { "LINHIB0001",10,0, 0x1ff6 }, - - { "S1SUSPEND", 9, 0, 0x3ff6 }, - { "S2SUSPEND", 9, 0, 0x3ff6 }, - { "ULSUSPEND", 9, 0, 0x3ff6 }, - { "LINHIB0001",10,0, 0x3ff6 }, - - { "S1SUSPEND", 9, 0, 0x7ff6 }, - { "S2SUSPEND", 9, 0, 0x7ff6 }, - { "ULSUSPEND", 9, 0, 0x7ff6 }, - { "LINHIB0001",10,0, 0x7ff6 }, - - { "S1SUSPEND", 9, 0, 0xfff6 }, - { "S2SUSPEND", 9, 0, 0xfff6 }, - { "ULSUSPEND", 9, 0, 0xfff6 }, - { "LINHIB0001",10,0, 0xfff6 }, - - { NULL } - } -}; - diff --git a/shlibs/blkid/src/superblocks/sysv.c b/shlibs/blkid/src/superblocks/sysv.c deleted file mode 100644 index 00c8c978..00000000 --- a/shlibs/blkid/src/superblocks/sysv.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2008 Karel Zak - * - * This is written from sratch according to Linux kernel fs/sysv/super.c file. - * It seems that sysv probing code in libvolume_id and also in the original - * blkid is useless. - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include - -#include "superblocks.h" - -#define XENIX_NICINOD 100 -#define XENIX_NICFREE 100 - -struct xenix_super_block { - 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; -} __attribute__((packed)); - - -#define SYSV_NICINOD 100 -#define SYSV_NICFREE 50 - -struct sysv_super_block -{ - 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; -}; - -static int probe_xenix(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct xenix_super_block *sb; - - sb = blkid_probe_get_sb(pr, mag, struct xenix_super_block); - if (!sb) - return -1; - blkid_probe_set_label(pr, sb->s_fname, sizeof(sb->s_fname)); - return 0; -} - -#define SYSV_BLOCK_SIZE 1024 - -/* Note that we don't probe for Coherent FS, this FS does not have - * magic string. (It requires to probe fname/fpack field..) - */ -static int probe_sysv(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct sysv_super_block *sb; - int blocks[] = {0, 9, 15, 18}; - int i; - - for (i = 0; i < ARRAY_SIZE(blocks); i++) { - int off = blocks[i] * SYSV_BLOCK_SIZE + SYSV_BLOCK_SIZE/2; - - sb = (struct sysv_super_block *) - blkid_probe_get_buffer(pr, - off, - sizeof(struct sysv_super_block)); - if (!sb) - return -1; - - if (sb->s_magic == cpu_to_le32(0xfd187e20) || - sb->s_magic == cpu_to_be32(0xfd187e20)) { - - if (blkid_probe_set_label(pr, sb->s_fname, - sizeof(sb->s_fname))) - return -1; - - if (blkid_probe_set_magic(pr, - off + offsetof(struct sysv_super_block, - s_magic), - sizeof(sb->s_magic), - (unsigned char *) &sb->s_magic)) - return -1; - - return 0; - } - } - return 1; -} - -const struct blkid_idinfo xenix_idinfo = -{ - .name = "xenix", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_xenix, - .magics = - { - { .magic = "\x2b\x55\x44", .len = 3, .kboff = 1, .sboff = 0x400 }, - { .magic = "\x44\x55\x2b", .len = 3, .kboff = 1, .sboff = 0x400 }, - { NULL } - } -}; - -const struct blkid_idinfo sysv_idinfo = -{ - .name = "sysv", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_sysv, - - /* SYSV is BE and LE and superblock could be on four positions. It's - * simpler to probe for the magic string by .probefunc(). - */ - .magics = BLKID_NONE_MAGIC -}; - diff --git a/shlibs/blkid/src/superblocks/ubifs.c b/shlibs/blkid/src/superblocks/ubifs.c deleted file mode 100644 index 87d94ba2..00000000 --- a/shlibs/blkid/src/superblocks/ubifs.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2009 Corentin Chary - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include - -#include "superblocks.h" - -/** - * struct ubifs_ch - common header node. - * @magic: UBIFS node magic number (%UBIFS_NODE_MAGIC) - * @crc: CRC-32 checksum of the node header - * @sqnum: sequence number - * @len: full node length - * @node_type: node type - * @group_type: node group type - * @padding: reserved for future, zeroes - * - * Every UBIFS node starts with this common part. If the node has a key, the - * key always goes next. - */ -struct ubifs_ch { - uint32_t magic; - uint32_t crc; - uint64_t sqnum; - uint32_t len; - uint8_t node_type; - uint8_t group_type; - uint8_t padding[2]; -} __attribute__ ((packed)); - -/** - * struct ubifs_sb_node - superblock node. - * @ch: common header - * @padding: reserved for future, zeroes - * @key_hash: type of hash function used in keys - * @key_fmt: format of the key - * @flags: file-system flags (%UBIFS_FLG_BIGLPT, etc) - * @min_io_size: minimal input/output unit size - * @leb_size: logical eraseblock size in bytes - * @leb_cnt: count of LEBs used by file-system - * @max_leb_cnt: maximum count of LEBs used by file-system - * @max_bud_bytes: maximum amount of data stored in buds - * @log_lebs: log size in logical eraseblocks - * @lpt_lebs: number of LEBs used for lprops table - * @orph_lebs: number of LEBs used for recording orphans - * @jhead_cnt: count of journal heads - * @fanout: tree fanout (max. number of links per indexing node) - * @lsave_cnt: number of LEB numbers in LPT's save table - * @fmt_version: UBIFS on-flash format version - * @default_compr: default compression algorithm (%UBIFS_COMPR_LZO, etc) - * @padding1: reserved for future, zeroes - * @rp_uid: reserve pool UID - * @rp_gid: reserve pool GID - * @rp_size: size of the reserved pool in bytes - * @padding2: reserved for future, zeroes - * @time_gran: time granularity in nanoseconds - * @uuid: UUID generated when the file system image was created - * @ro_compat_version: UBIFS R/O compatibility version - */ -struct ubifs_sb_node { - struct ubifs_ch ch; - uint8_t padding[2]; - uint8_t key_hash; - uint8_t key_fmt; - uint32_t flags; - uint32_t min_io_size; - uint32_t leb_size; - uint32_t leb_cnt; - uint32_t max_leb_cnt; - uint64_t max_bud_bytes; - uint32_t log_lebs; - uint32_t lpt_lebs; - uint32_t orph_lebs; - uint32_t jhead_cnt; - uint32_t fanout; - uint32_t lsave_cnt; - uint32_t fmt_version; - uint16_t default_compr; - uint8_t padding1[2]; - uint32_t rp_uid; - uint32_t rp_gid; - uint64_t rp_size; - uint32_t time_gran; - uint8_t uuid[16]; - uint32_t ro_compat_version; - uint8_t padding2[3968]; -} __attribute__ ((packed)); - - -static int probe_ubifs(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct ubifs_sb_node *sb; - - sb = blkid_probe_get_sb(pr, mag, struct ubifs_sb_node); - if (!sb) - return -1; - - blkid_probe_set_uuid(pr, sb->uuid); - blkid_probe_sprintf_version(pr, "w%dr%d", - sb->fmt_version, sb->ro_compat_version); - return 0; -} - -const struct blkid_idinfo ubifs_idinfo = -{ - .name = "ubifs", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_ubifs, - .magics = - { - { .magic = "\x31\x18\x10\x06", .len = 4 }, - { NULL } - } -}; diff --git a/shlibs/blkid/src/superblocks/udf.c b/shlibs/blkid/src/superblocks/udf.c deleted file mode 100644 index 766d6980..00000000 --- a/shlibs/blkid/src/superblocks/udf.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 1999 by Andries Brouwer - * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o - * Copyright (C) 2001 by Andreas Dilger - * Copyright (C) 2004 Kay Sievers - * Copyright (C) 2008 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include -#include -#include - -#include "superblocks.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; - } __attribute__((packed)) tag; - - union { - struct anchor_descriptor { - uint32_t length; - uint32_t location; - } __attribute__((packed)) anchor; - - struct primary_descriptor { - uint32_t seq_num; - uint32_t desc_num; - struct dstring { - uint8_t clen; - uint8_t c[31]; - } __attribute__((packed)) ident; - } __attribute__((packed)) primary; - - } __attribute__((packed)) type; - -} __attribute__((packed)); - -struct volume_structure_descriptor { - uint8_t type; - uint8_t id[5]; - uint8_t version; -} __attribute__((packed)); - -#define UDF_VSD_OFFSET 0x8000LL - -static int probe_udf(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct volume_descriptor *vd; - struct volume_structure_descriptor *vsd; - unsigned int bs; - unsigned int b; - unsigned int type; - unsigned int count; - unsigned int loc; - - /* search Volume Sequence Descriptor (VSD) to get the logical - * block size of the volume */ - for (bs = 0x800; bs < 0x8000; bs += 0x800) { - vsd = (struct volume_structure_descriptor *) - blkid_probe_get_buffer(pr, - UDF_VSD_OFFSET + bs, - sizeof(*vsd)); - if (!vsd) - return 1; - 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 *) - blkid_probe_get_buffer(pr, - UDF_VSD_OFFSET + ((blkid_loff_t) b * bs), - sizeof(*vsd)); - if (!vsd) - return -1; - 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 (AVDP) */ - vd = (struct volume_descriptor *) - blkid_probe_get_buffer(pr, 256 * bs, sizeof(*vd)); - if (!vd) - return -1; - - type = le16_to_cpu(vd->tag.id); - if (type != 2) /* TAG_ID_AVDP */ - return 0; - - /* get desriptor list address and block count */ - count = le32_to_cpu(vd->type.anchor.length) / bs; - loc = le32_to_cpu(vd->type.anchor.location); - - /* pick the primary descriptor from the list */ - for (b = 0; b < count; b++) { - vd = (struct volume_descriptor *) - blkid_probe_get_buffer(pr, - (blkid_loff_t) (loc + b) * bs, - sizeof(*vd)); - if (!vd) - return -1; - - type = le16_to_cpu(vd->tag.id); - if (type == 0) - break; - if (le32_to_cpu(vd->tag.location) != loc + b) - break; - if (type == 1) { /* TAG_ID_PVD */ - uint8_t clen = vd->type.primary.ident.clen; - - if (clen == 8) - blkid_probe_set_label(pr, - vd->type.primary.ident.c, 31); - else if (clen == 16) - blkid_probe_set_utf8label(pr, - vd->type.primary.ident.c, - 31, BLKID_ENC_UTF16BE); - - if (clen == 8 || clen == 16) - break; - } - } - - return 0; -} - - -const struct blkid_idinfo udf_idinfo = -{ - .name = "udf", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_udf, - .flags = BLKID_IDINFO_TOLERANT, - .magics = - { - { .magic = "BEA01", .len = 5, .kboff = 32, .sboff = 1 }, - { .magic = "BOOT2", .len = 5, .kboff = 32, .sboff = 1 }, - { .magic = "CD001", .len = 5, .kboff = 32, .sboff = 1 }, - { .magic = "CDW02", .len = 5, .kboff = 32, .sboff = 1 }, - { .magic = "NSR02", .len = 5, .kboff = 32, .sboff = 1 }, - { .magic = "NSR03", .len = 5, .kboff = 32, .sboff = 1 }, - { .magic = "TEA01", .len = 5, .kboff = 32, .sboff = 1 }, - { NULL } - } -}; diff --git a/shlibs/blkid/src/superblocks/ufs.c b/shlibs/blkid/src/superblocks/ufs.c deleted file mode 100644 index 05bed145..00000000 --- a/shlibs/blkid/src/superblocks/ufs.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright (C) 2008 Karel Zak - * - * Inspired by libvolume_id by - * Kay Sievers - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "superblocks.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; - } 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]; - } 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]; - } fs_cstotal; - struct ufs_timeval { - int32_t tv_sec; - int32_t tv_usec; - } fs_time; - int64_t fs_size; - int64_t fs_dsize; - uint64_t fs_csaddr; - int64_t fs_pendingblocks; - int32_t fs_pendinginodes; - } __attribute__((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]; - } 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]; - } 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; - } 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]; -} __attribute__((packed)); - -#define UFS_MAGIC 0x00011954 -#define UFS2_MAGIC 0x19540119 -#define UFS_MAGIC_FEA 0x00195612 -#define UFS_MAGIC_LFN 0x00095014 -#define UFS_MAGIC_SEC 0x00612195 -#define UFS_MAGIC_4GB 0x05231994 - -static int probe_ufs(blkid_probe pr, const struct blkid_idmag *mag) -{ - int offsets[] = { 0, 8, 64, 256 }; - int mags[] = { - UFS2_MAGIC, UFS_MAGIC, UFS_MAGIC_FEA, UFS_MAGIC_LFN, - UFS_MAGIC_SEC, UFS_MAGIC_4GB - }; - int i; - uint32_t magic; - struct ufs_super_block *ufs; - - for (i = 0; i < ARRAY_SIZE(offsets); i++) { - uint32_t magLE, magBE; - int y; - - ufs = (struct ufs_super_block *) - blkid_probe_get_buffer(pr, - offsets[i] * 1024, - sizeof(struct ufs_super_block)); - if (!ufs) - return -1; - - magBE = be32_to_cpu(ufs->fs_magic); - magLE = le32_to_cpu(ufs->fs_magic); - - for (y = 0; y < ARRAY_SIZE(mags); y++) { - if (magLE == mags[y] || magBE == mags[y]) { - magic = mags[y]; - goto found; - } - } - } - - return 1; - -found: - if (magic == UFS2_MAGIC) { - blkid_probe_set_version(pr, "2"); - blkid_probe_set_label(pr, ufs->fs_u11.fs_u2.fs_volname, - sizeof(ufs->fs_u11.fs_u2.fs_volname)); - } else - blkid_probe_set_version(pr, "1"); - - if (blkid_probe_set_magic(pr, - (offsets[i] * 1024) + - offsetof(struct ufs_super_block, fs_magic), - sizeof(ufs->fs_magic), - (unsigned char *) &ufs->fs_magic)) - return -1; - - return 0; -} - -/* - * According to libvolume_id the UFS superblock could be on four positions. - * The original libblkid has checked one position (.kboff=8) only. - * - * We know four UFS magic strings and UFS could be both little-endian and - * big-endian. ... so we have: - * - * 4 position * 4 string * 2 version = 32 magic strings - * - * It seems simpler to check for these string in probing function that hardcode - * all in the .magic array. - */ -const struct blkid_idinfo ufs_idinfo = -{ - .name = "ufs", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_ufs, - .magics = BLKID_NONE_MAGIC -}; - diff --git a/shlibs/blkid/src/superblocks/vfat.c b/shlibs/blkid/src/superblocks/vfat.c deleted file mode 100644 index 1584efae..00000000 --- a/shlibs/blkid/src/superblocks/vfat.c +++ /dev/null @@ -1,427 +0,0 @@ -/* - * Copyright (C) 1999 by Andries Brouwer - * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o - * Copyright (C) 2001 by Andreas Dilger - * Copyright (C) 2004 Kay Sievers - * Copyright (C) 2008 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include -#include -#include -#include -#include -#include -#include - -#include "superblocks.h" - -/* Yucky misaligned values */ -struct vfat_super_block { -/* 00*/ unsigned char vs_ignored[3]; -/* 03*/ unsigned char vs_sysid[8]; -/* 0b*/ unsigned char vs_sector_size[2]; -/* 0d*/ uint8_t vs_cluster_size; -/* 0e*/ uint16_t vs_reserved; -/* 10*/ uint8_t vs_fats; -/* 11*/ unsigned char vs_dir_entries[2]; -/* 13*/ unsigned char vs_sectors[2]; -/* 15*/ unsigned char vs_media; -/* 16*/ uint16_t vs_fat_length; -/* 18*/ uint16_t vs_secs_track; -/* 1a*/ uint16_t vs_heads; -/* 1c*/ uint32_t vs_hidden; -/* 20*/ uint32_t vs_total_sect; -/* 24*/ uint32_t vs_fat32_length; -/* 28*/ uint16_t vs_flags; -/* 2a*/ uint8_t vs_version[2]; -/* 2c*/ uint32_t vs_root_cluster; -/* 30*/ uint16_t vs_fsinfo_sector; -/* 32*/ uint16_t vs_backup_boot; -/* 34*/ uint16_t vs_reserved2[6]; -/* 40*/ unsigned char vs_unknown[3]; -/* 43*/ unsigned char vs_serno[4]; -/* 47*/ unsigned char vs_label[11]; -/* 52*/ unsigned char vs_magic[8]; -/* 5a*/ unsigned char vs_dummy2[0x1fe - 0x5a]; -/*1fe*/ unsigned char vs_pmagic[2]; -} __attribute__((packed)); - -/* Yucky misaligned values */ -struct msdos_super_block { -/* 00*/ unsigned char ms_ignored[3]; -/* 03*/ unsigned char ms_sysid[8]; -/* 0b*/ unsigned char ms_sector_size[2]; -/* 0d*/ uint8_t ms_cluster_size; -/* 0e*/ uint16_t ms_reserved; -/* 10*/ uint8_t ms_fats; -/* 11*/ unsigned char ms_dir_entries[2]; -/* 13*/ unsigned char ms_sectors[2]; /* =0 iff V3 or later */ -/* 15*/ unsigned char ms_media; -/* 16*/ uint16_t ms_fat_length; /* Sectors per FAT */ -/* 18*/ uint16_t ms_secs_track; -/* 1a*/ uint16_t ms_heads; -/* 1c*/ uint32_t ms_hidden; -/* V3 BPB */ -/* 20*/ uint32_t ms_total_sect; /* iff ms_sectors == 0 */ -/* V4 BPB */ -/* 24*/ unsigned char ms_unknown[3]; /* Phys drive no., resvd, V4 sig (0x29) */ -/* 27*/ unsigned char ms_serno[4]; -/* 2b*/ unsigned char ms_label[11]; -/* 36*/ unsigned char ms_magic[8]; -/* 3e*/ unsigned char ms_dummy2[0x1fe - 0x3e]; -/*1fe*/ unsigned char ms_pmagic[2]; -} __attribute__((packed)); - -struct vfat_dir_entry { - uint8_t name[11]; - uint8_t attr; - uint16_t time_creat; - uint16_t date_creat; - uint16_t time_acc; - uint16_t date_acc; - uint16_t cluster_high; - uint16_t time_write; - uint16_t date_write; - uint16_t cluster_low; - uint32_t size; -} __attribute__((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]; -} __attribute__((packed)); - -/* maximum number of clusters */ -#define FAT12_MAX 0xFF4 -#define FAT16_MAX 0xFFF4 -#define FAT32_MAX 0x0FFFFFF6 - -#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 - -static const char *no_name = "NO NAME "; - -#define unaligned_le16(x) \ - (((unsigned char *) x)[0] + (((unsigned char *) x)[1] << 8)) - -/* - * Look for LABEL (name) in the FAT root directory. - */ -static unsigned char *search_fat_label(blkid_probe pr, - uint32_t offset, uint32_t entries) -{ - struct vfat_dir_entry *ent, *dir = NULL; - int i; - - DBG(DEBUG_LOWPROBE, - printf("\tlook for label in root-dir " - "(entries: %d, offset: %d)\n", entries, offset)); - - if (!blkid_probe_is_tiny(pr)) { - /* large disk, read whole root directory */ - dir = (struct vfat_dir_entry *) - blkid_probe_get_buffer(pr, - offset, - (blkid_loff_t) entries * - sizeof(struct vfat_dir_entry)); - if (!dir) - return NULL; - } - - for (i = 0; i < entries; i++) { - /* - * The root directory could be relatively large (4-16kB). - * Fortunately, the LABEL is usually the first entry in the - * directory. On tiny disks we call read() per entry. - */ - if (!dir) - ent = (struct vfat_dir_entry *) - blkid_probe_get_buffer(pr, - (blkid_loff_t) offset + (i * - sizeof(struct vfat_dir_entry)), - sizeof(struct vfat_dir_entry)); - else - ent = &dir[i]; - - if (!ent || ent->name[0] == 0x00) - break; - - if ((ent->name[0] == FAT_ENTRY_FREE) || - (ent->cluster_high != 0 || ent->cluster_low != 0) || - ((ent->attr & FAT_ATTR_MASK) == FAT_ATTR_LONG_NAME)) - continue; - - if ((ent->attr & (FAT_ATTR_VOLUME_ID | FAT_ATTR_DIR)) == - FAT_ATTR_VOLUME_ID) { - DBG(DEBUG_LOWPROBE, - printf("\tfound fs LABEL at entry %d\n", i)); - return ent->name; - } - } - return NULL; -} - -static int fat_valid_superblock(const struct blkid_idmag *mag, - struct msdos_super_block *ms, - struct vfat_super_block *vs, - uint32_t *cluster_count, uint32_t *fat_size) -{ - uint16_t sector_size, dir_entries, reserved; - uint32_t sect_count, __fat_size, dir_size, __cluster_count, fat_length; - uint32_t max_count; - - /* extra check for FATs without magic strings */ - if (mag->len <= 2) { - /* Old floppies have a valid MBR signature */ - if (ms->ms_pmagic[0] != 0x55 || ms->ms_pmagic[1] != 0xAA) - return 0; - - /* - * OS/2 and apparently DFSee will place a FAT12/16-like - * pseudo-superblock in the first 512 bytes of non-FAT - * filesystems --- at least JFS and HPFS, and possibly others. - * So we explicitly check for those filesystems at the - * FAT12/16 filesystem magic field identifier, and if they are - * present, we rule this out as a FAT filesystem, despite the - * FAT-like pseudo-header. - */ - if ((memcmp(ms->ms_magic, "JFS ", 8) == 0) || - (memcmp(ms->ms_magic, "HPFS ", 8) == 0)) - return 0; - } - - /* fat counts(Linux kernel expects at least 1 FAT table) */ - if (!ms->ms_fats) - return 0; - if (!ms->ms_reserved) - return 0; - if (!(0xf8 <= ms->ms_media || ms->ms_media == 0xf0)) - return 0; - if (!is_power_of_2(ms->ms_cluster_size)) - return 0; - - sector_size = unaligned_le16(&ms->ms_sector_size); - if (!is_power_of_2(sector_size) || - sector_size < 512 || sector_size > 4096) - return 0; - - dir_entries = unaligned_le16(&ms->ms_dir_entries); - reserved = le16_to_cpu(ms->ms_reserved); - sect_count = unaligned_le16(&ms->ms_sectors); - - if (sect_count == 0) - sect_count = le32_to_cpu(ms->ms_total_sect); - - fat_length = le16_to_cpu(ms->ms_fat_length); - if (fat_length == 0) - fat_length = le32_to_cpu(vs->vs_fat32_length); - - __fat_size = fat_length * ms->ms_fats; - dir_size = ((dir_entries * sizeof(struct vfat_dir_entry)) + - (sector_size-1)) / sector_size; - - __cluster_count = (sect_count - (reserved + __fat_size + dir_size)) / - ms->ms_cluster_size; - if (!ms->ms_fat_length && vs->vs_fat32_length) - max_count = FAT32_MAX; - else - max_count = __cluster_count > FAT12_MAX ? FAT16_MAX : FAT12_MAX; - - if (__cluster_count > max_count) - return 0; - - if (fat_size) - *fat_size = __fat_size; - if (cluster_count) - *cluster_count = __cluster_count; - - return 1; /* valid */ -} - -/* - * This function is used by MBR partition table parser to avoid - * misinterpretation of FAT filesystem. - */ -int blkid_probe_is_vfat(blkid_probe pr) -{ - struct vfat_super_block *vs; - struct msdos_super_block *ms; - const struct blkid_idmag *mag = NULL; - - if (blkid_probe_get_idmag(pr, &vfat_idinfo, NULL, &mag) || !mag) - return 0; - - ms = blkid_probe_get_sb(pr, mag, struct msdos_super_block); - if (!ms) - return 0; - vs = blkid_probe_get_sb(pr, mag, struct vfat_super_block); - if (!vs) - return 0; - - return fat_valid_superblock(mag, ms, vs, NULL, NULL); -} - -/* FAT label extraction from the root directory taken from Kay - * Sievers's volume_id library */ -static int probe_vfat(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct vfat_super_block *vs; - struct msdos_super_block *ms; - const unsigned char *vol_label = 0; - unsigned char *vol_serno = NULL, vol_label_buf[11]; - uint16_t sector_size = 0, reserved; - uint32_t cluster_count, fat_size; - const char *version = NULL; - - ms = blkid_probe_get_sb(pr, mag, struct msdos_super_block); - if (!ms) - return 0; - vs = blkid_probe_get_sb(pr, mag, struct vfat_super_block); - if (!vs) - return 0; - if (!fat_valid_superblock(mag, ms, vs, &cluster_count, &fat_size)) - return 1; - - sector_size = unaligned_le16(&ms->ms_sector_size); - reserved = le16_to_cpu(ms->ms_reserved); - - if (ms->ms_fat_length) { - /* the label may be an attribute in the root directory */ - uint32_t root_start = (reserved + fat_size) * sector_size; - uint32_t root_dir_entries = unaligned_le16(&vs->vs_dir_entries); - - vol_label = search_fat_label(pr, root_start, root_dir_entries); - if (vol_label) { - memcpy(vol_label_buf, vol_label, 11); - vol_label = vol_label_buf; - } - - if (!vol_label || !memcmp(vol_label, no_name, 11)) - vol_label = ms->ms_label; - vol_serno = ms->ms_serno; - - blkid_probe_set_value(pr, "SEC_TYPE", (unsigned char *) "msdos", - sizeof("msdos")); - - if (cluster_count < FAT12_MAX) - version = "FAT12"; - else if (cluster_count < FAT16_MAX) - version = "FAT16"; - - } else if (vs->vs_fat32_length) { - unsigned char *buf; - uint16_t fsinfo_sect; - int maxloop = 100; - - /* Search the FAT32 root dir for the label attribute */ - uint32_t buf_size = vs->vs_cluster_size * sector_size; - uint32_t start_data_sect = reserved + fat_size; - uint32_t entries = le32_to_cpu(vs->vs_fat32_length) * - sector_size / sizeof(uint32_t); - uint32_t next = le32_to_cpu(vs->vs_root_cluster); - - while (next && next < entries && --maxloop) { - uint32_t next_sect_off; - uint64_t next_off, fat_entry_off; - int count; - - next_sect_off = (next - 2) * vs->vs_cluster_size; - next_off = (start_data_sect + next_sect_off) * - sector_size; - - count = buf_size / sizeof(struct vfat_dir_entry); - - vol_label = search_fat_label(pr, next_off, count); - if (vol_label) { - memcpy(vol_label_buf, vol_label, 11); - vol_label = vol_label_buf; - break; - } - - /* get FAT entry */ - fat_entry_off = (reserved * sector_size) + - (next * sizeof(uint32_t)); - buf = blkid_probe_get_buffer(pr, fat_entry_off, buf_size); - if (buf == NULL) - break; - - /* set next cluster */ - next = le32_to_cpu(*((uint32_t *) buf) & 0x0fffffff); - } - - version = "FAT32"; - - if (!vol_label || !memcmp(vol_label, no_name, 11)) - vol_label = vs->vs_label; - vol_serno = vs->vs_serno; - - /* - * 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->vs_fsinfo_sector); - if (fsinfo_sect) { - struct fat32_fsinfo *fsinfo; - - buf = blkid_probe_get_buffer(pr, - (blkid_loff_t) fsinfo_sect * sector_size, - sizeof(struct fat32_fsinfo)); - if (buf == NULL) - return -1; - - fsinfo = (struct fat32_fsinfo *) buf; - if (memcmp(fsinfo->signature1, "\x52\x52\x61\x41", 4) != 0 && - memcmp(fsinfo->signature1, "\x52\x52\x64\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; - } - } - - if (vol_label && memcmp(vol_label, no_name, 11)) - blkid_probe_set_label(pr, (unsigned char *) vol_label, 11); - - /* We can't just print them as %04X, because they are unaligned */ - if (vol_serno) - blkid_probe_sprintf_uuid(pr, vol_serno, 4, "%02X%02X-%02X%02X", - vol_serno[3], vol_serno[2], vol_serno[1], vol_serno[0]); - if (version) - blkid_probe_set_version(pr, version); - - return 0; -} - - -const struct blkid_idinfo vfat_idinfo = -{ - .name = "vfat", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_vfat, - .magics = - { - { .magic = "MSWIN", .len = 5, .sboff = 0x52 }, - { .magic = "FAT32 ", .len = 8, .sboff = 0x52 }, - { .magic = "MSDOS", .len = 5, .sboff = 0x36 }, - { .magic = "FAT16 ", .len = 8, .sboff = 0x36 }, - { .magic = "FAT12 ", .len = 8, .sboff = 0x36 }, - { .magic = "FAT ", .len = 8, .sboff = 0x36 }, - { .magic = "\353", .len = 1, }, - { .magic = "\351", .len = 1, }, - { .magic = "\125\252", .len = 2, .sboff = 0x1fe }, - { NULL } - } -}; - diff --git a/shlibs/blkid/src/superblocks/via_raid.c b/shlibs/blkid/src/superblocks/via_raid.c deleted file mode 100644 index 20131380..00000000 --- a/shlibs/blkid/src/superblocks/via_raid.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2008 Karel Zak - * - * Inspired by libvolume_id by - * Kay Sievers - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "superblocks.h" - -struct via_metadata { - 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; - } __attribute__((packed)) array; - uint32_t serial_checksum[8]; - uint8_t checksum; -} __attribute__((packed)); - -#define VIA_SIGNATURE 0xAA55 - -/* 8 bit checksum on first 50 bytes of metadata. */ -static uint8_t via_checksum(struct via_metadata *v) -{ - uint8_t i = 50, cs = 0; - - while (i--) - cs += ((uint8_t*) v)[i]; - - return cs == v->checksum; -} - -static int probe_viaraid(blkid_probe pr, const struct blkid_idmag *mag) -{ - uint64_t off; - struct via_metadata *v; - - if (pr->size < 0x10000) - return -1; - if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) - return -1; - - off = ((pr->size / 0x200)-1) * 0x200; - - v = (struct via_metadata *) - blkid_probe_get_buffer(pr, - off, - sizeof(struct via_metadata)); - if (!v) - return -1; - if (le16_to_cpu(v->signature) != VIA_SIGNATURE) - return -1; - if (v->version_number > 2) - return -1; - if (!via_checksum(v)) - return -1; - if (blkid_probe_sprintf_version(pr, "%u", v->version_number) != 0) - return -1; - if (blkid_probe_set_magic(pr, off, - sizeof(v->signature), - (unsigned char *) &v->signature)) - return -1; - return 0; -} - -const struct blkid_idinfo viaraid_idinfo = { - .name = "via_raid_member", - .usage = BLKID_USAGE_RAID, - .probefunc = probe_viaraid, - .magics = BLKID_NONE_MAGIC -}; - - diff --git a/shlibs/blkid/src/superblocks/vmfs.c b/shlibs/blkid/src/superblocks/vmfs.c deleted file mode 100644 index ead09a8d..00000000 --- a/shlibs/blkid/src/superblocks/vmfs.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2009 Mike Hommey - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include "superblocks.h" - -struct vmfs_fs_info { - uint32_t magic; - uint32_t volume_version; - uint8_t version; - uint8_t uuid[16]; - uint32_t mode; - char label[128]; -} __attribute__ ((__packed__)); - -struct vmfs_volume_info { - uint32_t magic; - uint32_t ver; - uint8_t irrelevant[122]; - uint8_t uuid[16]; -} __attribute__ ((__packed__)); - -static int probe_vmfs_fs(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct vmfs_fs_info *header; - - header = blkid_probe_get_sb(pr, mag, struct vmfs_fs_info); - if (header == NULL) - return -1; - - blkid_probe_sprintf_uuid(pr, (unsigned char *) header->uuid, 16, - "%02x%02x%02x%02x-%02x%02x%02x%02x-" - "%02x%02x-%02x%02x%02x%02x%02x%02x", - header->uuid[3], header->uuid[2], header->uuid[1], - header->uuid[0], header->uuid[7], header->uuid[6], - header->uuid[5], header->uuid[4], header->uuid[9], - header->uuid[8], header->uuid[10], header->uuid[11], - header->uuid[12], header->uuid[13], header->uuid[14], - header->uuid[15]); - - blkid_probe_set_label(pr, (unsigned char *) header->label, - sizeof(header->label)); - blkid_probe_sprintf_version(pr, "%u", header->version); - return 0; -} - -static int probe_vmfs_volume(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct vmfs_volume_info *header; - unsigned char *lvm_uuid; - - header = blkid_probe_get_sb(pr, mag, struct vmfs_volume_info); - if (header == NULL) - return -1; - - blkid_probe_sprintf_value(pr, "UUID_SUB", - "%02x%02x%02x%02x-%02x%02x%02x%02x-" - "%02x%02x-%02x%02x%02x%02x%02x%02x", - header->uuid[3], header->uuid[2], header->uuid[1], - header->uuid[0], header->uuid[7], header->uuid[6], - header->uuid[5], header->uuid[4], header->uuid[9], - header->uuid[8], header->uuid[10], header->uuid[11], - header->uuid[12], header->uuid[13], header->uuid[14], - header->uuid[15]); - blkid_probe_sprintf_version(pr, "%u", le32_to_cpu(header->ver)); - - lvm_uuid = blkid_probe_get_buffer(pr, - 1024 * 1024 /* Start of the volume info */ - + 512 /* Offset to lvm info */ - + 20 /* Offset in lvm info */, 35); - if (lvm_uuid) - blkid_probe_strncpy_uuid(pr, lvm_uuid, 35); - - return 0; -} - -const struct blkid_idinfo vmfs_fs_idinfo = -{ - .name = "VMFS", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_vmfs_fs, - .magics = - { - { .magic = "\x5e\xf1\xab\x2f", .len = 4, .kboff = 2048 }, - { NULL } - } -}; - -const struct blkid_idinfo vmfs_volume_idinfo = -{ - .name = "VMFS_volume_member", - .usage = BLKID_USAGE_RAID, - .probefunc = probe_vmfs_volume, - .magics = - { - { .magic = "\x0d\xd0\x01\xc0", .len = 4, .kboff = 1024 }, - { NULL } - } -}; diff --git a/shlibs/blkid/src/superblocks/vxfs.c b/shlibs/blkid/src/superblocks/vxfs.c deleted file mode 100644 index fdab85a7..00000000 --- a/shlibs/blkid/src/superblocks/vxfs.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2008 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -#include - -#include "superblocks.h" - -struct vxfs_super_block { - uint32_t vs_magic; - int32_t vs_version; -}; - -static int probe_vxfs(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct vxfs_super_block *vxs; - - vxs = blkid_probe_get_sb(pr, mag, struct vxfs_super_block); - if (!vxs) - return -1; - - blkid_probe_sprintf_version(pr, "%u", (unsigned int) vxs->vs_version); - return 0; -} - - -const struct blkid_idinfo vxfs_idinfo = -{ - .name = "vxfs", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_vxfs, - .magics = - { - { .magic = "\365\374\001\245", .len = 4, .kboff = 1 }, - { NULL } - } -}; - diff --git a/shlibs/blkid/src/superblocks/xfs.c b/shlibs/blkid/src/superblocks/xfs.c deleted file mode 100644 index 1399fe13..00000000 --- a/shlibs/blkid/src/superblocks/xfs.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 1999 by Andries Brouwer - * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o - * Copyright (C) 2001 by Andreas Dilger - * Copyright (C) 2004 Kay Sievers - * Copyright (C) 2008 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "superblocks.h" - -struct xfs_super_block { - unsigned char xs_magic[4]; - uint32_t xs_blocksize; - uint64_t xs_dblocks; - uint64_t xs_rblocks; - uint32_t xs_dummy1[2]; - unsigned char xs_uuid[16]; - uint32_t xs_dummy2[15]; - char xs_fname[12]; - uint32_t xs_dummy3[2]; - uint64_t xs_icount; - uint64_t xs_ifree; - uint64_t xs_fdblocks; -} __attribute__((packed)); - -static int probe_xfs(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct xfs_super_block *xs; - - xs = blkid_probe_get_sb(pr, mag, struct xfs_super_block); - if (!xs) - return -1; - - if (strlen(xs->xs_fname)) - blkid_probe_set_label(pr, (unsigned char *) xs->xs_fname, - sizeof(xs->xs_fname)); - blkid_probe_set_uuid(pr, xs->xs_uuid); - return 0; -} - -const struct blkid_idinfo xfs_idinfo = -{ - .name = "xfs", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_xfs, - .magics = - { - { .magic = "XFSB", .len = 4 }, - { NULL } - } -}; - diff --git a/shlibs/blkid/src/superblocks/zfs.c b/shlibs/blkid/src/superblocks/zfs.c deleted file mode 100644 index af5264d4..00000000 --- a/shlibs/blkid/src/superblocks/zfs.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright (C) 2009-2010 by Andreas Dilger - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "superblocks.h" - -#define VDEV_LABEL_UBERBLOCK (128 * 1024ULL) -#define VDEV_LABEL_NVPAIR ( 16 * 1024ULL) -#define VDEV_LABEL_SIZE (256 * 1024ULL) - -/* #include */ -#define UBERBLOCK_MAGIC 0x00bab10c /* oo-ba-bloc! */ -struct zfs_uberblock { - uint64_t ub_magic; /* UBERBLOCK_MAGIC */ - uint64_t ub_version; /* SPA_VERSION */ - uint64_t ub_txg; /* txg of last sync */ - uint64_t ub_guid_sum; /* sum of all vdev guids */ - uint64_t ub_timestamp; /* UTC time of last sync */ - char ub_rootbp; /* MOS objset_phys_t */ -} __attribute__((packed)); - -#define ZFS_TRIES 64 -#define ZFS_WANT 4 - -#define DATA_TYPE_UINT64 8 -#define DATA_TYPE_STRING 9 - -struct nvpair { - uint32_t nvp_size; - uint32_t nvp_unkown; - uint32_t nvp_namelen; - char nvp_name[0]; /* aligned to 4 bytes */ - /* aligned ptr array for string arrays */ - /* aligned array of data for value */ -}; - -struct nvstring { - uint32_t nvs_type; - uint32_t nvs_elem; - uint32_t nvs_strlen; - unsigned char nvs_string[0]; -}; - -struct nvuint64 { - uint32_t nvu_type; - uint32_t nvu_elem; - uint64_t nvu_value; -}; - -struct nvlist { - uint32_t nvl_unknown[3]; - struct nvpair nvl_nvpair; -}; - -#define nvdebug(fmt, ...) do { } while(0) -/*#define nvdebug(fmt, a...) printf(fmt, ##a)*/ - -static void zfs_extract_guid_name(blkid_probe pr, loff_t offset) -{ - struct nvlist *nvl; - struct nvpair *nvp; - int left = 4096; - int found = 0; - - offset = (offset & ~(VDEV_LABEL_SIZE - 1)) + VDEV_LABEL_NVPAIR; - - /* Note that we currently assume that the desired fields are within - * the first 4k (left) of the nvlist. This is true for all pools - * I've seen, and simplifies this code somewhat, because we don't - * have to handle an nvpair crossing a buffer boundary. */ - nvl = (struct nvlist *)blkid_probe_get_buffer(pr, offset, left); - if (nvl == NULL) - return; - - nvdebug("zfs_extract: nvlist offset %llu\n", offset); - - nvp = &nvl->nvl_nvpair; - while (left > sizeof(*nvp) && nvp->nvp_size != 0 && found < 3) { - int avail; /* tracks that name/value data fits in nvp_size */ - int namesize; - - nvp->nvp_size = be32_to_cpu(nvp->nvp_size); - nvp->nvp_namelen = be32_to_cpu(nvp->nvp_namelen); - avail = nvp->nvp_size - nvp->nvp_namelen - sizeof(*nvp); - - nvdebug("left %u, nvp_size %u\n", left, nvp->nvp_size); - if (left < nvp->nvp_size || avail < 0) - break; - - namesize = (nvp->nvp_namelen + 3) & ~3; - - nvdebug("nvlist: size %u, namelen %u, name %*s\n", - nvp->nvp_size, nvp->nvp_namelen, nvp->nvp_namelen, - nvp->nvp_name); - if (strncmp(nvp->nvp_name, "name", nvp->nvp_namelen) == 0) { - struct nvstring *nvs = (void *)(nvp->nvp_name+namesize); - - nvs->nvs_type = be32_to_cpu(nvs->nvs_type); - nvs->nvs_strlen = be32_to_cpu(nvs->nvs_strlen); - avail -= nvs->nvs_strlen + sizeof(*nvs); - nvdebug("nvstring: type %u string %*s\n", nvs->nvs_type, - nvs->nvs_strlen, nvs->nvs_string); - if (nvs->nvs_type == DATA_TYPE_STRING && avail >= 0) - blkid_probe_set_label(pr, nvs->nvs_string, - nvs->nvs_strlen); - found++; - } else if (strncmp(nvp->nvp_name, "guid", - nvp->nvp_namelen) == 0) { - struct nvuint64 *nvu = (void *)(nvp->nvp_name+namesize); - uint64_t nvu_value; - - memcpy(&nvu_value, &nvu->nvu_value, sizeof(nvu_value)); - nvu->nvu_type = be32_to_cpu(nvu->nvu_type); - nvu_value = be64_to_cpu(nvu_value); - avail -= sizeof(*nvu); - nvdebug("nvuint64: type %u value %"PRIu64"\n", - nvu->nvu_type, nvu_value); - if (nvu->nvu_type == DATA_TYPE_UINT64 && avail >= 0) - blkid_probe_sprintf_value(pr, "UUID_SUB", - "%"PRIu64, nvu_value); - found++; - } else if (strncmp(nvp->nvp_name, "pool_guid", - nvp->nvp_namelen) == 0) { - struct nvuint64 *nvu = (void *)(nvp->nvp_name+namesize); - uint64_t nvu_value; - - memcpy(&nvu_value, &nvu->nvu_value, sizeof(nvu_value)); - nvu->nvu_type = be32_to_cpu(nvu->nvu_type); - nvu_value = be64_to_cpu(nvu_value); - avail -= sizeof(*nvu); - nvdebug("nvuint64: type %u value %"PRIu64"\n", - nvu->nvu_type, nvu_value); - if (nvu->nvu_type == DATA_TYPE_UINT64 && avail >= 0) - blkid_probe_sprintf_uuid(pr, (unsigned char *) - &nvu_value, - sizeof(nvu_value), - "%"PRIu64, nvu_value); - found++; - } - left -= nvp->nvp_size; - nvp = (struct nvpair *)((char *)nvp + nvp->nvp_size); - } -} - -#define zdebug(fmt, ...) do {} while(0) -/*#define zdebug(fmt, a...) printf(fmt, ##a)*/ - -/* ZFS has 128x1kB host-endian root blocks, stored in 2 areas at the start - * of the disk, and 2 areas at the end of the disk. Check only some of them... - * #4 (@ 132kB) is the first one written on a new filesystem. */ -static int probe_zfs(blkid_probe pr, const struct blkid_idmag *mag) -{ - uint64_t swab_magic = swab64(UBERBLOCK_MAGIC); - struct zfs_uberblock *ub; - int swab_endian; - loff_t offset; - int tried; - int found; - - zdebug("probe_zfs\n"); - /* Look for at least 4 uberblocks to ensure a positive match */ - for (tried = found = 0, offset = VDEV_LABEL_UBERBLOCK; - tried < ZFS_TRIES && found < ZFS_WANT; - tried++, offset += 4096) { - /* also try the second uberblock copy */ - if (tried == (ZFS_TRIES / 2)) - offset = VDEV_LABEL_SIZE + VDEV_LABEL_UBERBLOCK; - - ub = (struct zfs_uberblock *) - blkid_probe_get_buffer(pr, offset, - sizeof(struct zfs_uberblock)); - if (ub == NULL) - return -1; - - if (ub->ub_magic == UBERBLOCK_MAGIC) - found++; - - if ((swab_endian = (ub->ub_magic == swab_magic))) - found++; - - zdebug("probe_zfs: found %s-endian uberblock at %llu\n", - swab_endian ? "big" : "little", offset >> 10); - } - - if (found < 4) - return -1; - - /* If we found the 4th uberblock, then we will have exited from the - * scanning loop immediately, and ub will be a valid uberblock. */ - blkid_probe_sprintf_version(pr, "%" PRIu64, swab_endian ? - swab64(ub->ub_version) : ub->ub_version); - - zfs_extract_guid_name(pr, offset); - - if (blkid_probe_set_magic(pr, offset, - sizeof(ub->ub_magic), - (unsigned char *) &ub->ub_magic)) - return -1; - - return 0; -} - -const struct blkid_idinfo zfs_idinfo = -{ - .name = "zfs_member", - .usage = BLKID_USAGE_RAID, - .probefunc = probe_zfs, - .minsz = 64 * 1024 * 1024, - .magics = BLKID_NONE_MAGIC -}; - diff --git a/shlibs/blkid/src/tag.c b/shlibs/blkid/src/tag.c deleted file mode 100644 index 0dbe1ff5..00000000 --- a/shlibs/blkid/src/tag.c +++ /dev/null @@ -1,474 +0,0 @@ -/* - * tag.c - allocation/initialization/free routines for tag structs - * - * Copyright (C) 2001 Andreas Dilger - * Copyright (C) 2003 Theodore Ts'o - * - * %Begin-Header% - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * %End-Header% - */ - -#include -#include -#include -#include - -#include "blkidP.h" - -static blkid_tag blkid_new_tag(void) -{ - blkid_tag tag; - - if (!(tag = (blkid_tag) calloc(1, sizeof(struct blkid_struct_tag)))) - return NULL; - - INIT_LIST_HEAD(&tag->bit_tags); - INIT_LIST_HEAD(&tag->bit_names); - - return tag; -} - -#ifdef CONFIG_BLKID_DEBUG -void blkid_debug_dump_tag(blkid_tag tag) -{ - if (!tag) { - printf(" tag: NULL\n"); - return; - } - - printf(" tag: %s=\"%s\"\n", tag->bit_name, tag->bit_val); -} -#endif - -void blkid_free_tag(blkid_tag tag) -{ - if (!tag) - return; - - DBG(DEBUG_TAG, printf(" freeing tag %s=%s\n", tag->bit_name, - tag->bit_val ? tag->bit_val : "(NULL)")); - DBG(DEBUG_TAG, blkid_debug_dump_tag(tag)); - - list_del(&tag->bit_tags); /* list of tags for this device */ - list_del(&tag->bit_names); /* list of tags with this type */ - - free(tag->bit_name); - free(tag->bit_val); - - free(tag); -} - -/* - * Find the desired tag on a device. If value is NULL, then the - * first such tag is returned, otherwise return only exact tag if found. - */ -blkid_tag blkid_find_tag_dev(blkid_dev dev, const char *type) -{ - struct list_head *p; - - if (!dev || !type) - return NULL; - - list_for_each(p, &dev->bid_tags) { - blkid_tag tmp = list_entry(p, struct blkid_struct_tag, - bit_tags); - - if (!strcmp(tmp->bit_name, type)) - return tmp; - } - return NULL; -} - -extern int blkid_dev_has_tag(blkid_dev dev, const char *type, - const char *value) -{ - blkid_tag tag; - - if (!dev || !type) - return -1; - - tag = blkid_find_tag_dev(dev, type); - if (!value) - return (tag != NULL); - if (!tag || strcmp(tag->bit_val, value)) - return 0; - return 1; -} - -/* - * Find the desired tag type in the cache. - * We return the head tag for this tag type. - */ -static blkid_tag blkid_find_head_cache(blkid_cache cache, const char *type) -{ - blkid_tag head = NULL, tmp; - struct list_head *p; - - if (!cache || !type) - return NULL; - - list_for_each(p, &cache->bic_tags) { - tmp = list_entry(p, struct blkid_struct_tag, bit_tags); - if (!strcmp(tmp->bit_name, type)) { - DBG(DEBUG_TAG, - printf(" found cache tag head %s\n", type)); - head = tmp; - break; - } - } - return head; -} - -/* - * Set a tag on an existing device. - * - * If value is NULL, then delete the tagsfrom the device. - */ -int blkid_set_tag(blkid_dev dev, const char *name, - const char *value, const int vlength) -{ - blkid_tag t = 0, head = 0; - char *val = 0; - char **dev_var = 0; - - if (!dev || !name) - return -BLKID_ERR_PARAM; - - if (!(val = blkid_strndup(value, vlength)) && value) - return -BLKID_ERR_MEM; - - /* - * Certain common tags are linked directly to the device struct - * We need to know what they are before we do anything else because - * the function name parameter might get freed later on. - */ - if (!strcmp(name, "TYPE")) - dev_var = &dev->bid_type; - else if (!strcmp(name, "LABEL")) - dev_var = &dev->bid_label; - else if (!strcmp(name, "UUID")) - dev_var = &dev->bid_uuid; - - t = blkid_find_tag_dev(dev, name); - if (!value) { - if (t) - blkid_free_tag(t); - } else if (t) { - if (!strcmp(t->bit_val, val)) { - /* Same thing, exit */ - free(val); - return 0; - } - free(t->bit_val); - t->bit_val = val; - } else { - /* Existing tag not present, add to device */ - if (!(t = blkid_new_tag())) - goto errout; - t->bit_name = blkid_strdup(name); - t->bit_val = val; - t->bit_dev = dev; - - list_add_tail(&t->bit_tags, &dev->bid_tags); - - if (dev->bid_cache) { - head = blkid_find_head_cache(dev->bid_cache, - t->bit_name); - if (!head) { - head = blkid_new_tag(); - if (!head) - goto errout; - - DBG(DEBUG_TAG, - printf(" creating new cache tag head %s\n", name)); - head->bit_name = blkid_strdup(name); - if (!head->bit_name) - goto errout; - list_add_tail(&head->bit_tags, - &dev->bid_cache->bic_tags); - } - list_add_tail(&t->bit_names, &head->bit_names); - } - } - - /* Link common tags directly to the device struct */ - if (dev_var) - *dev_var = val; - - if (dev->bid_cache) - dev->bid_cache->bic_flags |= BLKID_BIC_FL_CHANGED; - return 0; - -errout: - if (t) - blkid_free_tag(t); - else - free(val); - if (head) - blkid_free_tag(head); - return -BLKID_ERR_MEM; -} - - -/* - * Parse a "NAME=value" string. This is slightly different than - * parse_token, because that will end an unquoted value at a space, while - * this will assume that an unquoted value is the rest of the token (e.g. - * if we are passed an already quoted string from the command-line we don't - * have to both quote and escape quote so that the quotes make it to - * us). - * - * Returns 0 on success, and -1 on failure. - */ -int blkid_parse_tag_string(const char *token, char **ret_type, char **ret_val) -{ - char *name, *value, *cp; - - DBG(DEBUG_TAG, printf("trying to parse '%s' as a tag\n", token)); - - if (!token || !(cp = strchr(token, '='))) - return -1; - - name = blkid_strdup(token); - if (!name) - return -1; - value = name + (cp - token); - *value++ = '\0'; - if (*value == '"' || *value == '\'') { - char c = *value++; - if (!(cp = strrchr(value, c))) - goto errout; /* missing closing quote */ - *cp = '\0'; - } - value = blkid_strdup(value); - if (!value) - goto errout; - - *ret_type = name; - *ret_val = value; - - return 0; - -errout: - free(name); - return -1; -} - -/* - * Tag iteration routines for the public libblkid interface. - * - * These routines do not expose the list.h implementation, which are a - * contamination of the namespace, and which force us to reveal far, far - * too much of our internal implemenation. I'm not convinced I want - * to keep list.h in the long term, anyway. It's fine for kernel - * programming, but performance is not the #1 priority for this - * library, and I really don't like the tradeoff of type-safety for - * performance for this application. [tytso:20030125.2007EST] - */ - -/* - * This series of functions iterate over all tags in a device - */ -#define TAG_ITERATE_MAGIC 0x01a5284c - -struct blkid_struct_tag_iterate { - int magic; - blkid_dev dev; - struct list_head *p; -}; - -extern blkid_tag_iterate blkid_tag_iterate_begin(blkid_dev dev) -{ - blkid_tag_iterate iter; - - iter = malloc(sizeof(struct blkid_struct_tag_iterate)); - if (iter) { - iter->magic = TAG_ITERATE_MAGIC; - iter->dev = dev; - iter->p = dev->bid_tags.next; - } - return (iter); -} - -/* - * Return 0 on success, -1 on error - */ -extern int blkid_tag_next(blkid_tag_iterate iter, - const char **type, const char **value) -{ - blkid_tag tag; - - *type = 0; - *value = 0; - if (!iter || iter->magic != TAG_ITERATE_MAGIC || - iter->p == &iter->dev->bid_tags) - return -1; - tag = list_entry(iter->p, struct blkid_struct_tag, bit_tags); - *type = tag->bit_name; - *value = tag->bit_val; - iter->p = iter->p->next; - return 0; -} - -extern void blkid_tag_iterate_end(blkid_tag_iterate iter) -{ - if (!iter || iter->magic != TAG_ITERATE_MAGIC) - return; - iter->magic = 0; - free(iter); -} - -/* - * This function returns a device which matches a particular - * type/value pair. If there is more than one device that matches the - * search specification, it returns the one with the highest priority - * value. This allows us to give preference to EVMS or LVM devices. - */ -extern blkid_dev blkid_find_dev_with_tag(blkid_cache cache, - const char *type, - const char *value) -{ - blkid_tag head; - blkid_dev dev; - int pri; - struct list_head *p; - int probe_new = 0; - - if (!cache || !type || !value) - return NULL; - - blkid_read_cache(cache); - - DBG(DEBUG_TAG, printf("looking for %s=%s in cache\n", type, value)); - -try_again: - pri = -1; - dev = 0; - head = blkid_find_head_cache(cache, type); - - if (head) { - list_for_each(p, &head->bit_names) { - blkid_tag tmp = list_entry(p, struct blkid_struct_tag, - bit_names); - - if (!strcmp(tmp->bit_val, value) && - (tmp->bit_dev->bid_pri > pri) && - !access(tmp->bit_dev->bid_name, F_OK)) { - dev = tmp->bit_dev; - pri = dev->bid_pri; - } - } - } - if (dev && !(dev->bid_flags & BLKID_BID_FL_VERIFIED)) { - dev = blkid_verify(cache, dev); - if (!dev || (dev && (dev->bid_flags & BLKID_BID_FL_VERIFIED))) - goto try_again; - } - - if (!dev && !probe_new) { - if (blkid_probe_all_new(cache) < 0) - return NULL; - probe_new++; - goto try_again; - } - - if (!dev && !(cache->bic_flags & BLKID_BIC_FL_PROBED)) { - if (blkid_probe_all(cache) < 0) - return NULL; - goto try_again; - } - return dev; -} - -#ifdef TEST_PROGRAM -#ifdef HAVE_GETOPT_H -#include -#else -extern char *optarg; -extern int optind; -#endif - -void usage(char *prog) -{ - fprintf(stderr, "Usage: %s [-f blkid_file] [-m debug_mask] device " - "[type value]\n", - prog); - fprintf(stderr, "\tList all tags for a device and exit\n"); - exit(1); -} - -int main(int argc, char **argv) -{ - blkid_tag_iterate iter; - blkid_cache cache = NULL; - blkid_dev dev; - int c, ret, found; - int flags = BLKID_DEV_FIND; - char *tmp; - char *file = NULL; - char *devname = NULL; - char *search_type = NULL; - char *search_value = NULL; - const char *type, *value; - - while ((c = getopt (argc, argv, "m:f:")) != EOF) - switch (c) { - case 'f': - file = optarg; - break; - case 'm': - { - int mask = strtoul (optarg, &tmp, 0); - if (*tmp) { - fprintf(stderr, "Invalid debug mask: %s\n", - optarg); - exit(1); - } - blkid_init_debug(mask); - break; - } - case '?': - usage(argv[0]); - } - if (argc > optind) - devname = argv[optind++]; - if (argc > optind) - search_type = argv[optind++]; - if (argc > optind) - search_value = argv[optind++]; - if (!devname || (argc != optind)) - usage(argv[0]); - - if ((ret = blkid_get_cache(&cache, file)) != 0) { - fprintf(stderr, "%s: error creating cache (%d)\n", - argv[0], ret); - exit(1); - } - - dev = blkid_get_dev(cache, devname, flags); - if (!dev) { - fprintf(stderr, "%s: Can not find device in blkid cache\n", - devname); - exit(1); - } - if (search_type) { - found = blkid_dev_has_tag(dev, search_type, search_value); - printf("Device %s: (%s, %s) %s\n", blkid_dev_devname(dev), - search_type, search_value ? search_value : "NULL", - found ? "FOUND" : "NOT FOUND"); - return(!found); - } - printf("Device %s...\n", blkid_dev_devname(dev)); - - iter = blkid_tag_iterate_begin(dev); - while (blkid_tag_next(iter, &type, &value) == 0) { - printf("\tTag %s has value %s\n", type, value); - } - blkid_tag_iterate_end(iter); - - blkid_put_cache(cache); - return (0); -} -#endif diff --git a/shlibs/blkid/src/topology/Makefile.am b/shlibs/blkid/src/topology/Makefile.am deleted file mode 100644 index 775fea3e..00000000 --- a/shlibs/blkid/src/topology/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ -include $(top_srcdir)/config/include-Makefile.am - -AM_CPPFLAGS += -I$(ul_libblkid_incdir) -I$(ul_libblkid_srcdir) -libblkid_topology_la_LIBADD = - -noinst_LTLIBRARIES = libblkid_topology.la -libblkid_topology_la_SOURCES = topology.c \ - topology.h - -if LINUX -libblkid_topology_la_SOURCES += sysfs.c \ - dm.c \ - lvm.c \ - ioctl.c \ - md.c \ - evms.c -endif diff --git a/shlibs/blkid/src/topology/dm.c b/shlibs/blkid/src/topology/dm.c deleted file mode 100644 index 8f33911c..00000000 --- a/shlibs/blkid/src/topology/dm.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * device-mapper (dm) topology - * -- this is fallback for old systems where the topology information is not - * exported by sysfs - * - * Copyright (C) 2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "topology.h" - -static int is_dm_device(dev_t devno) -{ - return blkid_driver_has_major("device-mapper", major(devno)); -} - -static int probe_dm_tp(blkid_probe pr, const struct blkid_idmag *mag) -{ - const char *paths[] = { - "/usr/local/sbin/dmsetup", - "/usr/sbin/dmsetup", - "/sbin/dmsetup" - }; - int i, dmpipe[] = { -1, -1 }, stripes, stripesize; - char *cmd = NULL; - FILE *stream = NULL; - long long offset, size; - dev_t devno = blkid_probe_get_devno(pr); - - if (!devno) - goto nothing; /* probably not a block device */ - if (!is_dm_device(devno)) - goto nothing; - - for (i = 0; i < ARRAY_SIZE(paths); i++) { - struct stat sb; - if (stat(paths[i], &sb) == 0) { - cmd = (char *) paths[i]; - break; - } - } - - if (!cmd) - goto nothing; - if (pipe(dmpipe) < 0) { - DBG(DEBUG_LOWPROBE, - printf("Failed to open pipe: errno=%d", errno)); - goto nothing; - } - - switch (fork()) { - case 0: - { - char *dmargv[7], maj[16], min[16]; - - /* Plumbing */ - close(dmpipe[0]); - - if (dmpipe[1] != STDOUT_FILENO) - dup2(dmpipe[1], STDOUT_FILENO); - - /* The libblkid library could linked with setuid programs */ - if (setgid(getgid()) < 0) - exit(1); - if (setuid(getuid()) < 0) - exit(1); - - snprintf(maj, sizeof(maj), "%d", major(devno)); - snprintf(min, sizeof(min), "%d", minor(devno)); - - dmargv[0] = cmd; - dmargv[1] = "table"; - dmargv[2] = "-j"; - dmargv[3] = maj; - dmargv[4] = "-m"; - dmargv[5] = min; - dmargv[6] = NULL; - - execv(dmargv[0], dmargv); - - DBG(DEBUG_LOWPROBE, - printf("Failed to execute %s: errno=%d", cmd, errno)); - exit(1); - } - case -1: - DBG(DEBUG_LOWPROBE, - printf("Failed to forking: errno=%d", errno)); - goto nothing; - default: - break; - } - - stream = fdopen(dmpipe[0], "r"); - if (!stream) - goto nothing; - - i = fscanf(stream, "%lld %lld striped %d %d ", - &offset, &size, &stripes, &stripesize); - if (i != 4) - goto nothing; - - blkid_topology_set_minimum_io_size(pr, stripesize << 9); - blkid_topology_set_optimal_io_size(pr, (stripes * stripesize) << 9); - - fclose(stream); - close(dmpipe[1]); - return 0; - -nothing: - if (stream) - fclose(stream); - else if (dmpipe[0] != -1) - close(dmpipe[0]); - if (dmpipe[1] != -1) - close(dmpipe[1]); - return 1; -} - -const struct blkid_idinfo dm_tp_idinfo = -{ - .name = "dm", - .probefunc = probe_dm_tp, - .magics = BLKID_NONE_MAGIC -}; - diff --git a/shlibs/blkid/src/topology/evms.c b/shlibs/blkid/src/topology/evms.c deleted file mode 100644 index a30d8df7..00000000 --- a/shlibs/blkid/src/topology/evms.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Evms topology - * -- this is fallback for old systems where the toplogy information is not - * exported by sysfs - * - * Copyright (C) 2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "topology.h" - -#define EVMS_MAJOR 117 - -#ifndef _IOT__IOTBASE_u_int32_t -#define _IOT__IOTBASE_u_int32_t IOT_SIMPLE(uint32_t) -#endif -#define _IOT_evms_stripe_info _IOT (_IOTS(uint32_t), 2, 0, 0, 0, 0) -#define EVMS_GET_STRIPE_INFO _IOR(EVMS_MAJOR, 0xF0, struct evms_stripe_info) - -struct evms_stripe_info { - uint32_t size; /* stripe unit 512-byte blocks */ - uint32_t width; /* the number of stripe members or RAID data disks */ -} evms_stripe_info; - -static int is_evms_device(dev_t devno) -{ - if (major(devno) == EVMS_MAJOR) - return 1; - return blkid_driver_has_major("evms", major(devno)); -} - -static int probe_evms_tp(blkid_probe pr, const struct blkid_idmag *mag) -{ - struct evms_stripe_info evms; - dev_t devno = blkid_probe_get_devno(pr); - - if (!devno) - goto nothing; /* probably not a block device */ - - if (!is_evms_device(devno)) - goto nothing; - - memset(&evms, 0, sizeof(evms)); - - if (ioctl(pr->fd, EVMS_GET_STRIPE_INFO, &evms)) - goto nothing; - - blkid_topology_set_minimum_io_size(pr, evms.size << 9); - blkid_topology_set_optimal_io_size(pr, (evms.size * evms.width) << 9); - - return 0; - -nothing: - return 1; -} - -const struct blkid_idinfo evms_tp_idinfo = -{ - .name = "evms", - .probefunc = probe_evms_tp, - .magics = BLKID_NONE_MAGIC -}; - diff --git a/shlibs/blkid/src/topology/ioctl.c b/shlibs/blkid/src/topology/ioctl.c deleted file mode 100644 index 73c18ec9..00000000 --- a/shlibs/blkid/src/topology/ioctl.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * ioctl based topology -- gathers topology information - * - * Copyright (C) 2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "topology.h" - -/* - * ioctl topology values - */ -static struct topology_val { - - long ioc; - - /* functions to set probing result */ - int (*set_ulong)(blkid_probe, unsigned long); - int (*set_int)(blkid_probe, int); - -} topology_vals[] = { - { BLKALIGNOFF, NULL, blkid_topology_set_alignment_offset }, - { BLKIOMIN, blkid_topology_set_minimum_io_size }, - { BLKIOOPT, blkid_topology_set_optimal_io_size }, - { BLKPBSZGET, blkid_topology_set_physical_sector_size } - /* we read BLKSSZGET in topology.c */ -}; - -static int probe_ioctl_tp(blkid_probe pr, const struct blkid_idmag *mag) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(topology_vals); i++) { - struct topology_val *val = &topology_vals[i]; - int rc = 1; - unsigned int data; - - if (ioctl(pr->fd, val->ioc, &data) == -1) - goto nothing; - - if (val->set_int) - rc = val->set_int(pr, (int) data); - else - rc = val->set_ulong(pr, (unsigned long) data); - if (rc) - goto err; - } - - return 0; -nothing: - return 1; -err: - return -1; -} - -const struct blkid_idinfo ioctl_tp_idinfo = -{ - .name = "ioctl", - .probefunc = probe_ioctl_tp, - .magics = BLKID_NONE_MAGIC -}; - diff --git a/shlibs/blkid/src/topology/lvm.c b/shlibs/blkid/src/topology/lvm.c deleted file mode 100644 index 54438b0a..00000000 --- a/shlibs/blkid/src/topology/lvm.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * lvm topology - * -- this is fallback for old systems where the topology information is not - * exported by sysfs - * - * Copyright (C) 2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "topology.h" - -#ifndef LVM_BLK_MAJOR -# define LVM_BLK_MAJOR 58 -#endif - -static int is_lvm_device(dev_t devno) -{ - if (major(devno) == LVM_BLK_MAJOR) - return 1; - return blkid_driver_has_major("lvm", major(devno)); -} - -static int probe_lvm_tp(blkid_probe pr, const struct blkid_idmag *mag) -{ - const char *paths[] = { - "/usr/local/sbin/lvdisplay", - "/usr/sbin/lvdisplay", - "/sbin/lvdisplay" - }; - int i, lvpipe[] = { -1, -1 }, stripes = 0, stripesize = 0; - FILE *stream = NULL; - char *cmd = NULL, *devname = NULL, buf[1024]; - dev_t devno = blkid_probe_get_devno(pr); - - if (!devno) - goto nothing; /* probably not a block device */ - if (!is_lvm_device(devno)) - goto nothing; - - for (i = 0; i < ARRAY_SIZE(paths); i++) { - struct stat sb; - if (stat(paths[i], &sb) == 0) { - cmd = (char *) paths[i]; - break; - } - } - - if (!cmd) - goto nothing; - - devname = blkid_devno_to_devname(devno); - if (!devname) - goto nothing; - - if (pipe(lvpipe) < 0) { - DBG(DEBUG_LOWPROBE, - printf("Failed to open pipe: errno=%d", errno)); - goto nothing; - } - - switch (fork()) { - case 0: - { - char *lvargv[3]; - - /* Plumbing */ - close(lvpipe[0]); - - if (lvpipe[1] != STDOUT_FILENO) - dup2(lvpipe[1], STDOUT_FILENO); - - /* The libblkid library could linked with setuid programs */ - if (setgid(getgid()) < 0) - exit(1); - if (setuid(getuid()) < 0) - exit(1); - - lvargv[0] = cmd; - lvargv[1] = devname; - lvargv[2] = NULL; - - execv(lvargv[0], lvargv); - - DBG(DEBUG_LOWPROBE, - printf("Failed to execute %s: errno=%d", cmd, errno)); - exit(1); - } - case -1: - DBG(DEBUG_LOWPROBE, - printf("Failed to forking: errno=%d", errno)); - goto nothing; - default: - break; - } - - stream = fdopen(lvpipe[0], "r"); - if (!stream) - goto nothing; - - while (fgets(buf, sizeof(buf), stream) != NULL) { - if (!strncmp(buf, "Stripes", 7)) - sscanf(buf, "Stripes %d", &stripes); - - if (!strncmp(buf, "Stripe size", 11)) - sscanf(buf, "Stripe size (KByte) %d", &stripesize); - } - - if (!stripes) - goto nothing; - - blkid_topology_set_minimum_io_size(pr, stripesize << 10); - blkid_topology_set_optimal_io_size(pr, (stripes * stripesize) << 10); - - free(devname); - fclose(stream); - close(lvpipe[1]); - return 0; - -nothing: - free(devname); - if (stream) - fclose(stream); - else if (lvpipe[0] != -1) - close(lvpipe[0]); - if (lvpipe[1] != -1) - close(lvpipe[1]); - return 1; -} - -const struct blkid_idinfo lvm_tp_idinfo = -{ - .name = "lvm", - .probefunc = probe_lvm_tp, - .magics = BLKID_NONE_MAGIC -}; - diff --git a/shlibs/blkid/src/topology/md.c b/shlibs/blkid/src/topology/md.c deleted file mode 100644 index d7275edd..00000000 --- a/shlibs/blkid/src/topology/md.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Linux Software RAID (md) topology - * -- this is fallback for old systems where the topology information is not - * exported by sysfs - * - * Copyright (C) 2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "topology.h" - -#ifndef MD_MAJOR -#define MD_MAJOR 9 -#endif - -#ifndef _IOT__IOTBASE_uint32_t -#define _IOT__IOTBASE_uint32_t IOT_SIMPLE(uint32_t) -#endif -#define _IOT_md_array_info _IOT (_IOTS(uint32_t), 18, 0, 0, 0, 0) -#define GET_ARRAY_INFO _IOR (MD_MAJOR, 0x11, struct md_array_info) - -struct md_array_info { - /* - * Generic constant information - */ - uint32_t major_version; - uint32_t minor_version; - uint32_t patch_version; - 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; - - /* - * Generic state information - */ - uint32_t utime; /* 0 Superblock update time */ - uint32_t state; /* 1 State bits (clean, ...) */ - uint32_t active_disks; /* 2 Number of currently active disks */ - uint32_t working_disks; /* 3 Number of working disks */ - uint32_t failed_disks; /* 4 Number of failed disks */ - uint32_t spare_disks; /* 5 Number of spare disks */ - - /* - * Personality information - */ - uint32_t layout; /* 0 the array's physical layout */ - uint32_t chunk_size; /* 1 chunk size in bytes */ - -}; - -static int is_md_device(dev_t devno) -{ - if (major(devno) == MD_MAJOR) - return 1; - return blkid_driver_has_major("md", major(devno)); -} - -static int probe_md_tp(blkid_probe pr, const struct blkid_idmag *mag) -{ - int fd = -1; - dev_t disk = 0; - dev_t devno = blkid_probe_get_devno(pr); - struct md_array_info md; - - if (!devno) - goto nothing; /* probably not a block device */ - - if (!is_md_device(devno)) - goto nothing; - - if (blkid_devno_to_wholedisk(devno, NULL, 0, &disk)) - goto nothing; - - if (disk == devno) - fd = pr->fd; - else { - char *diskpath = blkid_devno_to_devname(disk); - - if (!diskpath) - goto nothing; - - fd = open(diskpath, O_RDONLY); - free(diskpath); - - if (fd == -1) - goto nothing; - } - - memset(&md, 0, sizeof(md)); - - if (ioctl(fd, GET_ARRAY_INFO, &md)) - goto nothing; - - if (fd != pr->fd) - close(fd); - - /* - * Ignore levels we don't want aligned (e.g. linear) - * and deduct disk(s) from stripe width on RAID4/5/6 - */ - switch (md.level) { - case 6: - md.raid_disks--; - /* fallthrough */ - case 5: - case 4: - md.raid_disks--; - /* fallthrough */ - case 1: - case 0: - case 10: - break; - default: - goto nothing; - } - - blkid_topology_set_minimum_io_size(pr, md.chunk_size); - blkid_topology_set_optimal_io_size(pr, md.chunk_size * md.raid_disks); - - return 0; - -nothing: - if (fd != -1 && fd != pr->fd) - close(fd); - return 1; -} - -const struct blkid_idinfo md_tp_idinfo = -{ - .name = "md", - .probefunc = probe_md_tp, - .magics = BLKID_NONE_MAGIC -}; - diff --git a/shlibs/blkid/src/topology/sysfs.c b/shlibs/blkid/src/topology/sysfs.c deleted file mode 100644 index 588fc7a1..00000000 --- a/shlibs/blkid/src/topology/sysfs.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * sysfs based topology -- gathers topology information from Linux sysfs - * - * Copyright (C) 2009 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * - * For more information see Linux kernel Documentation/ABI/testing/sysfs-block. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sysfs.h" -#include "topology.h" - -/* - * Sysfs topology values (since 2.6.31, May 2009). - */ -static struct topology_val { - - /* /sys/dev/block/:/ */ - const char *attr; - - /* functions to set probing resut */ - int (*set_ulong)(blkid_probe, unsigned long); - int (*set_int)(blkid_probe, int); - -} topology_vals[] = { - { "alignment_offset", NULL, blkid_topology_set_alignment_offset }, - { "queue/minimum_io_size", blkid_topology_set_minimum_io_size }, - { "queue/optimal_io_size", blkid_topology_set_optimal_io_size }, - { "queue/physical_block_size", blkid_topology_set_physical_sector_size }, -}; - -static int probe_sysfs_tp(blkid_probe pr, const struct blkid_idmag *mag) -{ - dev_t dev, disk = 0; - int i, count = 0, rc; - struct sysfs_cxt sysfs, parent; - - dev = blkid_probe_get_devno(pr); - if (!dev || sysfs_init(&sysfs, dev, NULL) != 0) - return 1; - - rc = 1; /* nothing (default) */ - - for (i = 0; i < ARRAY_SIZE(topology_vals); i++) { - struct topology_val *val = &topology_vals[i]; - int ok = sysfs_has_attribute(&sysfs, val->attr); - - rc = 1; /* nothing */ - - if (!ok) { - if (!disk) { - /* - * Read atrributes from "disk" if the current - * device is a partition. - */ - disk = blkid_probe_get_wholedisk_devno(pr); - if (disk && disk != dev) { - if (sysfs_init(&parent, disk, NULL) != 0) - goto done; - - sysfs.parent = &parent; - ok = sysfs_has_attribute(&sysfs, - val->attr); - } - } - if (!ok) - continue; /* attrinute does not exist */ - } - - if (val->set_ulong) { - uint64_t data; - - if (sysfs_read_u64(&sysfs, val->attr, &data) != 0) - continue; - rc = val->set_ulong(pr, (unsigned long) data); - - } else if (val->set_int) { - int64_t data; - - if (sysfs_read_s64(&sysfs, val->attr, &data) != 0) - continue; - rc = val->set_int(pr, (int) data); - } - - if (rc < 0) - goto done; /* error */ - if (rc == 0) - count++; - } - -done: - sysfs_deinit(&sysfs); - if (disk) - sysfs_deinit(&parent); - if (count) - return 0; /* success */ - return rc; /* error or nothing */ -} - -const struct blkid_idinfo sysfs_tp_idinfo = -{ - .name = "sysfs", - .probefunc = probe_sysfs_tp, - .magics = BLKID_NONE_MAGIC -}; - diff --git a/shlibs/blkid/src/topology/topology.c b/shlibs/blkid/src/topology/topology.c deleted file mode 100644 index 27dc755f..00000000 --- a/shlibs/blkid/src/topology/topology.c +++ /dev/null @@ -1,369 +0,0 @@ -/* - * topology - gathers information about device topology - * - * Copyright 2009 Red Hat, Inc. All rights reserved. - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -#include -#include -#include -#include - -#include "topology.h" - -/** - * SECTION:topology - * @title: Topology information - * @short_description: block device topology information. - * - * The topology chain provides details about Linux block devices, for more - * information see: - * - * Linux kernel Documentation/ABI/testing/sysfs-block - * - * NAME=value (tags) interface is enabled by blkid_probe_enable_topology(), - * and provides: - * - * @LOGICAL_SECTOR_SIZE: this is the smallest unit the storage device can - * address. It is typically 512 bytes. - * - * @PHYSICAL_SECTOR_SIZE: this is the smallest unit a physical storage device - * can write atomically. It is usually the same as the - * logical sector size but may be bigger. - * - * @MINIMUM_IO_SIZE: minimum size which is the device's preferred unit of I/O. - * For RAID arrays it is often the stripe chunk size. - * - * @OPTIMAL_IO_SIZE: usually the stripe width for RAID or zero. For RAID arrays - * it is usually the stripe width or the internal track size. - * - * @ALIGNMENT_OFFSET: indicates how many bytes the beginning of the device is - * offset from the disk's natural alignment. - * - * The NAME=value tags are not defined when the corresponding topology value - * is zero. The MINIMUM_IO_SIZE should be always defined if kernel provides - * topology information. - * - * Binary interface: - * - * blkid_probe_get_topology() - * - * blkid_topology_get_'VALUENAME'() - */ -static int topology_probe(blkid_probe pr, struct blkid_chain *chn); -static void topology_free(blkid_probe pr, void *data); -static int topology_is_complete(blkid_probe pr); -static int topology_set_logical_sector_size(blkid_probe pr); - -/* - * Binary interface - */ -struct blkid_struct_topology { - unsigned long alignment_offset; - unsigned long minimum_io_size; - unsigned long optimal_io_size; - unsigned long logical_sector_size; - unsigned long physical_sector_size; -}; - -/* - * Topology chain probing functions - */ -static const struct blkid_idinfo *idinfos[] = -{ -#ifdef __linux__ - &ioctl_tp_idinfo, - &sysfs_tp_idinfo, - &md_tp_idinfo, - &dm_tp_idinfo, - &lvm_tp_idinfo, - &evms_tp_idinfo -#endif -}; - - -/* - * Driver definition - */ -const struct blkid_chaindrv topology_drv = { - .id = BLKID_CHAIN_TOPLGY, - .name = "topology", - .dflt_enabled = FALSE, - .idinfos = idinfos, - .nidinfos = ARRAY_SIZE(idinfos), - .probe = topology_probe, - .safeprobe = topology_probe, - .free_data = topology_free -}; - -/** - * blkid_probe_enable_topology: - * @pr: probe - * @enable: TRUE/FALSE - * - * Enables/disables the topology probing for non-binary interface. - * - * Returns: 0 on success, or -1 in case of error. - */ -int blkid_probe_enable_topology(blkid_probe pr, int enable) -{ - if (!pr) - return -1; - pr->chains[BLKID_CHAIN_TOPLGY].enabled = enable; - return 0; -} - -/** - * blkid_probe_get_topology: - * @pr: probe - * - * This is a binary interface for topology values. See also blkid_topology_* - * functions. - * - * This function is independent on blkid_do_[safe,full]probe() and - * blkid_probe_enable_topology() calls. - * - * WARNING: the returned object will be overwritten by the next - * blkid_probe_get_topology() call for the same @pr. If you want to - * use more blkid_topopogy objects in the same time you have to create - * more blkid_probe handlers (see blkid_new_probe()). - * - * TODO: add blkid_ref() and blkid_unref() to allows to use blkid_topology - * independently on libblkid probing stuff. - * - * Returns: blkid_topopogy, or NULL in case of error. - */ -blkid_topology blkid_probe_get_topology(blkid_probe pr) -{ - return (blkid_topology) blkid_probe_get_binary_data(pr, - &pr->chains[BLKID_CHAIN_TOPLGY]); -} - -/* - * The blkid_do_probe() backend. - */ -static int topology_probe(blkid_probe pr, struct blkid_chain *chn) -{ - int i = 0; - - if (!pr || chn->idx < -1) - return -1; - - if (!S_ISBLK(pr->mode)) - return -1; /* nothing, works with block devices only */ - - if (chn->binary) { - DBG(DEBUG_LOWPROBE, printf("initialize topology binary data\n")); - - if (chn->data) - /* reset binary data */ - memset(chn->data, 0, - sizeof(struct blkid_struct_topology)); - else { - chn->data = calloc(1, - sizeof(struct blkid_struct_topology)); - if (!chn->data) - return -1; - } - } - - blkid_probe_chain_reset_vals(pr, chn); - - DBG(DEBUG_LOWPROBE, - printf("--> starting probing loop [TOPOLOGY idx=%d]\n", - chn->idx)); - - i = chn->idx + 1; - - for ( ; i < ARRAY_SIZE(idinfos); i++) { - const struct blkid_idinfo *id = idinfos[i]; - - chn->idx = i; - - if (id->probefunc) { - DBG(DEBUG_LOWPROBE, printf( - "%s: call probefunc()\n", id->name)); - if (id->probefunc(pr, NULL) != 0) - continue; - } - - if (!topology_is_complete(pr)) - continue; - - /* generic for all probing drivers */ - topology_set_logical_sector_size(pr); - - DBG(DEBUG_LOWPROBE, - printf("<-- leaving probing loop (type=%s) [TOPOLOGY idx=%d]\n", - id->name, chn->idx)); - return 0; - } - - DBG(DEBUG_LOWPROBE, - printf("<-- leaving probing loop (failed) [TOPOLOGY idx=%d]\n", - chn->idx)); - return 1; -} - -static void topology_free(blkid_probe pr, void *data) -{ - free(data); -} - -static int topology_set_value(blkid_probe pr, const char *name, - size_t structoff, unsigned long data) -{ - struct blkid_chain *chn = blkid_probe_get_chain(pr); - - if (!chn) - return -1; - if (!data) - return 0; /* ignore zeros */ - - if (chn->binary) { - unsigned long *v = - (unsigned long *) (chn->data + structoff); - *v = data; - return 0; - } - return blkid_probe_sprintf_value(pr, name, "%llu", data); -} - -/* the topology info is complete when we have at least "minimum_io_size" which - * is provided by all blkid topology drivers */ -static int topology_is_complete(blkid_probe pr) -{ - struct blkid_chain *chn = blkid_probe_get_chain(pr); - - if (!chn) - return FALSE; - - if (chn->binary && chn->data) { - blkid_topology tp = (blkid_topology) chn->data; - if (tp->minimum_io_size) - return TRUE; - } - - return __blkid_probe_lookup_value(pr, "MINIMUM_IO_SIZE") ? TRUE : FALSE; -} - -int blkid_topology_set_alignment_offset(blkid_probe pr, int val) -{ - unsigned long xval; - - /* Welcome to Hell. The kernel is able to return -1 as an - * alignment_offset if no compatible sizes and alignments - * exist for stacked devices. - * - * There is no way how libblkid caller can respond to the value -1, so - * we will hide this corner case... - * - * (TODO: maybe we can export an extra boolean value 'misaligned' rather - * then complete hide this problem.) - */ - xval = val < 0 ? 0 : val; - - return topology_set_value(pr, - "ALIGNMENT_OFFSET", - offsetof(struct blkid_struct_topology, alignment_offset), - xval); -} - -int blkid_topology_set_minimum_io_size(blkid_probe pr, unsigned long val) -{ - return topology_set_value(pr, - "MINIMUM_IO_SIZE", - offsetof(struct blkid_struct_topology, minimum_io_size), - val); -} - -int blkid_topology_set_optimal_io_size(blkid_probe pr, unsigned long val) -{ - return topology_set_value(pr, - "OPTIMAL_IO_SIZE", - offsetof(struct blkid_struct_topology, optimal_io_size), - val); -} - -/* BLKSSZGET is provided on all systems since 2.3.3 -- so we don't have to - * waste time with sysfs. - */ -static int topology_set_logical_sector_size(blkid_probe pr) -{ - unsigned long val = blkid_probe_get_sectorsize(pr); - - if (!val) - return -1; - - return topology_set_value(pr, - "LOGICAL_SECTOR_SIZE", - offsetof(struct blkid_struct_topology, logical_sector_size), - val); -} - -int blkid_topology_set_physical_sector_size(blkid_probe pr, unsigned long val) -{ - return topology_set_value(pr, - "PHYSICAL_SECTOR_SIZE", - offsetof(struct blkid_struct_topology, physical_sector_size), - val); -} - -/** - * blkid_topology_get_alignment_offset: - * @tp: topology - * - * Returns: alignment offset in bytes or 0. - */ -unsigned long blkid_topology_get_alignment_offset(blkid_topology tp) -{ - return tp ? tp->alignment_offset : 0; -} - -/** - * blkid_topology_get_minimum_io_size: - * @tp: topology - * - * Returns: minimum io size in bytes or 0. - */ -unsigned long blkid_topology_get_minimum_io_size(blkid_topology tp) -{ - return tp ? tp->minimum_io_size : 0; -} - -/** - * blkid_topology_get_optimal_io_size - * @tp: topology - * - * Returns: optimal io size in bytes or 0. - */ -unsigned long blkid_topology_get_optimal_io_size(blkid_topology tp) -{ - return tp ? tp->optimal_io_size : 0; -} - -/** - * blkid_topology_get_logical_sector_size - * @tp: topology - * - * Returns: logical sector size (BLKSSZGET ioctl) in bytes or 0. - */ -unsigned long blkid_topology_get_logical_sector_size(blkid_topology tp) -{ - return tp ? tp->logical_sector_size : 0; -} - -/** - * blkid_topology_get_physical_sector_size - * @tp: topology - * - * Returns: logical sector size (BLKSSZGET ioctl) in bytes or 0. - */ -unsigned long blkid_topology_get_physical_sector_size(blkid_topology tp) -{ - return tp ? tp->physical_sector_size : 0; -} - diff --git a/shlibs/blkid/src/topology/topology.h b/shlibs/blkid/src/topology/topology.h deleted file mode 100644 index 6d2f4334..00000000 --- a/shlibs/blkid/src/topology/topology.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef BLKID_TOPOLOGY_H -#define BLKID_TOPOLOGY_H - -#include "blkidP.h" - -extern int blkid_topology_set_alignment_offset(blkid_probe pr, int val); -extern int blkid_topology_set_minimum_io_size(blkid_probe pr, unsigned long val); -extern int blkid_topology_set_optimal_io_size(blkid_probe pr, unsigned long val); -extern int blkid_topology_set_physical_sector_size(blkid_probe pr, unsigned long val); - -/* - * topology probers - */ -#ifdef __linux__ -extern const struct blkid_idinfo ioctl_tp_idinfo; -extern const struct blkid_idinfo md_tp_idinfo; -extern const struct blkid_idinfo evms_tp_idinfo; -extern const struct blkid_idinfo sysfs_tp_idinfo; -extern const struct blkid_idinfo dm_tp_idinfo; -extern const struct blkid_idinfo lvm_tp_idinfo; -#endif - -#endif /* BLKID_TOPOLOGY_H */ - diff --git a/shlibs/blkid/src/tst_types.c b/shlibs/blkid/src/tst_types.c deleted file mode 100644 index ecbc0321..00000000 --- a/shlibs/blkid/src/tst_types.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This testing program makes sure the stdint.h header file - * - * Copyright (C) 2006 by Theodore Ts'o. - * - * %Begin-Header% - * This file may be redistributed under the terms of the GNU Public - * License. - * %End-Header% - */ - -#include -#include - -#include -#include - -int main(int argc, char **argv) -{ - if (sizeof(uint8_t) != 1) { - printf("Sizeof(uint8_t) is %d should be 1\n", - (int)sizeof(uint8_t)); - exit(1); - } - if (sizeof(int8_t) != 1) { - printf("Sizeof(int8_t) is %d should be 1\n", - (int)sizeof(int8_t)); - exit(1); - } - if (sizeof(uint16_t) != 2) { - printf("Sizeof(uint16_t) is %d should be 2\n", - (int)sizeof(uint16_t)); - exit(1); - } - if (sizeof(int16_t) != 2) { - printf("Sizeof(int16_t) is %d should be 2\n", - (int)sizeof(int16_t)); - exit(1); - } - if (sizeof(uint32_t) != 4) { - printf("Sizeof(uint32_t) is %d should be 4\n", - (int)sizeof(uint32_t)); - exit(1); - } - if (sizeof(int32_t) != 4) { - printf("Sizeof(int32_t) is %d should be 4\n", - (int)sizeof(int32_t)); - exit(1); - } - if (sizeof(uint64_t) != 8) { - printf("Sizeof(uint64_t) is %d should be 8\n", - (int)sizeof(uint64_t)); - exit(1); - } - if (sizeof(int64_t) != 8) { - printf("Sizeof(int64_t) is %d should be 8\n", - (int)sizeof(int64_t)); - exit(1); - } - printf("The stdint.h types are correct.\n"); - exit(0); -} - diff --git a/shlibs/blkid/src/verify.c b/shlibs/blkid/src/verify.c deleted file mode 100644 index a0cb3fea..00000000 --- a/shlibs/blkid/src/verify.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (C) 2008 Karel Zak - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#include "blkidP.h" - -static void blkid_probe_to_tags(blkid_probe pr, blkid_dev dev) -{ - const char *data; - const char *name; - int nvals, n; - size_t len; - - nvals = blkid_probe_numof_values(pr); - - for (n = 0; n < nvals; n++) { - if (blkid_probe_get_value(pr, n, &name, &data, &len) == 0) - blkid_set_tag(dev, name, data, len); - } -} - -/* - * Verify that the data in dev is consistent with what is on the actual - * block device (using the devname field only). Normally this will be - * called when finding items in the cache, but for long running processes - * is also desirable to revalidate an item before use. - * - * If we are unable to revalidate the data, we return the old data and - * do not set the BLKID_BID_FL_VERIFIED flag on it. - */ -blkid_dev blkid_verify(blkid_cache cache, blkid_dev dev) -{ - struct stat st; - time_t diff, now; - char *fltr[2]; - int fd; - - if (!dev) - return NULL; - - now = time(0); - diff = now - dev->bid_time; - - if (stat(dev->bid_name, &st) < 0) { - DBG(DEBUG_PROBE, - printf("blkid_verify: error %s (%d) while " - "trying to stat %s\n", strerror(errno), errno, - dev->bid_name)); - open_err: - if ((errno == EPERM) || (errno == EACCES) || (errno == ENOENT)) { - /* We don't have read permission, just return cache data. */ - DBG(DEBUG_PROBE, printf("returning unverified data for %s\n", - dev->bid_name)); - return dev; - } - blkid_free_dev(dev); - return NULL; - } - - if (now >= dev->bid_time && -#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC - (st.st_mtime < dev->bid_time || - (st.st_mtime == dev->bid_time && - st.st_mtim.tv_nsec / 1000 <= dev->bid_utime)) && -#else - st.st_mtime <= dev->bid_time && -#endif - (diff < BLKID_PROBE_MIN || - (dev->bid_flags & BLKID_BID_FL_VERIFIED && - diff < BLKID_PROBE_INTERVAL))) - return dev; - -#ifndef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC - DBG(DEBUG_PROBE, - printf("need to revalidate %s (cache time %lu, stat time %lu,\n\t" - "time since last check %lu)\n", - dev->bid_name, (unsigned long)dev->bid_time, - (unsigned long)st.st_mtime, (unsigned long)diff)); -#else - DBG(DEBUG_PROBE, - printf("need to revalidate %s (cache time %lu.%lu, stat time %lu.%lu,\n\t" - "time since last check %lu)\n", - dev->bid_name, - (unsigned long)dev->bid_time, (unsigned long)dev->bid_utime, - (unsigned long)st.st_mtime, (unsigned long)st.st_mtim.tv_nsec / 1000, - (unsigned long)diff)); -#endif - - if (!cache->probe) { - cache->probe = blkid_new_probe(); - if (!cache->probe) { - blkid_free_dev(dev); - return NULL; - } - } - - fd = open(dev->bid_name, O_RDONLY); - if (fd < 0) { - DBG(DEBUG_PROBE, printf("blkid_verify: error %s (%d) while " - "opening %s\n", strerror(errno), errno, - dev->bid_name)); - goto open_err; - } - - if (blkid_probe_set_device(cache->probe, fd, 0, 0)) { - /* failed to read the device */ - close(fd); - blkid_free_dev(dev); - return NULL; - } - - blkid_probe_enable_superblocks(cache->probe, TRUE); - - blkid_probe_set_superblocks_flags(cache->probe, - BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID | - BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE); - - /* - * If we already know the type, then try that first. - */ - if (dev->bid_type) { - blkid_tag_iterate iter; - const char *type, *value; - - fltr[0] = dev->bid_type; - fltr[1] = NULL; - - blkid_probe_filter_superblocks_type(cache->probe, - BLKID_FLTR_ONLYIN, fltr); - - if (!blkid_do_probe(cache->probe)) - goto found_type; - blkid_probe_invert_superblocks_filter(cache->probe); - - /* - * Zap the device filesystem information and try again - */ - DBG(DEBUG_PROBE, - printf("previous fs type %s not valid, " - "trying full probe\n", dev->bid_type)); - iter = blkid_tag_iterate_begin(dev); - while (blkid_tag_next(iter, &type, &value) == 0) - blkid_set_tag(dev, type, 0, 0); - blkid_tag_iterate_end(iter); - } - - /* - * Probe for all types. - */ - if (blkid_do_safeprobe(cache->probe)) { - /* found nothing or error */ - blkid_free_dev(dev); - dev = NULL; - } - -found_type: - if (dev) { -#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC - struct timeval tv; - if (!gettimeofday(&tv, NULL)) { - dev->bid_time = tv.tv_sec; - dev->bid_utime = tv.tv_usec; - } else -#endif - dev->bid_time = time(0); - - dev->bid_devno = st.st_rdev; - dev->bid_flags |= BLKID_BID_FL_VERIFIED; - cache->bic_flags |= BLKID_BIC_FL_CHANGED; - - blkid_probe_to_tags(cache->probe, dev); - - DBG(DEBUG_PROBE, printf("%s: devno 0x%04llx, type %s\n", - dev->bid_name, (long long)st.st_rdev, dev->bid_type)); - } - - blkid_reset_probe(cache->probe); - blkid_probe_reset_superblocks_filter(cache->probe); - close(fd); - return dev; -} - -#ifdef TEST_PROGRAM -int main(int argc, char **argv) -{ - blkid_dev dev; - blkid_cache cache; - int ret; - - if (argc != 2) { - fprintf(stderr, "Usage: %s device\n" - "Probe a single device to determine type\n", argv[0]); - exit(1); - } - if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) { - fprintf(stderr, "%s: error creating cache (%d)\n", - argv[0], ret); - exit(1); - } - dev = blkid_get_dev(cache, argv[1], BLKID_DEV_NORMAL); - if (!dev) { - printf("%s: %s has an unsupported type\n", argv[0], argv[1]); - return (1); - } - printf("TYPE='%s'\n", dev->bid_type ? dev->bid_type : "(null)"); - if (dev->bid_label) - printf("LABEL='%s'\n", dev->bid_label); - if (dev->bid_uuid) - printf("UUID='%s'\n", dev->bid_uuid); - - blkid_free_dev(dev); - return (0); -} -#endif diff --git a/shlibs/blkid/src/version.c b/shlibs/blkid/src/version.c deleted file mode 100644 index 4c7fa06c..00000000 --- a/shlibs/blkid/src/version.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * version.c --- Return the version of the blkid library - * - * Copyright (C) 2004 Theodore Ts'o. - * - * %Begin-Header% - * This file may be redistributed under the terms of the GNU Public - * License. - * %End-Header% - */ - -#if HAVE_UNISTD_H -#include -#endif -#include -#include -#include - -#include "blkid.h" - -/* LIBBLKID_* defined in the global config.h */ -static const char *lib_version = LIBBLKID_VERSION; /* release version */ -static const char *lib_date = LIBBLKID_DATE; - -/** - * blkid_parse_version_string: - * @ver_string: version string (e.g. "2.16.0") - * - * Returns: release version code. - */ -int blkid_parse_version_string(const char *ver_string) -{ - const char *cp; - int version = 0; - - for (cp = ver_string; *cp; cp++) { - if (*cp == '.') - continue; - if (!isdigit(*cp)) - break; - version = (version * 10) + (*cp - '0'); - } - return version; -} - -/** - * blkid_get_library_version: - * @ver_string: returns relese version (!= SONAME version) - * @date_string: returns date - * - * Returns: release version code. - */ -int blkid_get_library_version(const char **ver_string, - const char **date_string) -{ - if (ver_string) - *ver_string = lib_version; - if (date_string) - *date_string = lib_date; - - return blkid_parse_version_string(lib_version); -} diff --git a/tests/commands.sh.in b/tests/commands.sh.in index e976b997..4f70da73 100644 --- a/tests/commands.sh.in +++ b/tests/commands.sh.in @@ -25,9 +25,9 @@ TS_HELPER_LIBMOUNT_CONTEXT="$top_builddir/libmount/src/test_context" TS_HELPER_LIBMOUNT_TABDIFF="$top_builddir/libmount/src/test_tab_diff" # TODO: use partx -TS_HELPER_PARTITIONS="$top_builddir/shlibs/blkid/samples/partitions" +TS_HELPER_PARTITIONS="$top_builddir/libblkid/samples/partitions" -U_L_LIBRARY_PATH="$top_builddir/shlibs/blkid/src/.libs:$top_builddir/libuuid/src/.libs" +U_L_LIBRARY_PATH="$top_builddir/libblkid/src/.libs:$top_builddir/libuuid/src/.libs" # paths to commands TS_CMD_MOUNT=${TS_CMD_MOUNT:-"$top_builddir/mount/mount"} -- cgit v1.2.3