summaryrefslogtreecommitdiffstats
path: root/libblkid/src/superblocks
diff options
context:
space:
mode:
authorZeeshan Ali (Khattak)2013-02-11 22:22:12 +0100
committerKarel Zak2013-02-14 12:11:34 +0100
commitfafe46bc266b65ca524909b43701a3d06825d0a8 (patch)
treef76dd96274aacb8bb51f7d3409db1bf187c3d2f4 /libblkid/src/superblocks
parentlibblkid: Don't keep reading same sector of ISO (diff)
downloadkernel-qcow2-util-linux-fafe46bc266b65ca524909b43701a3d06825d0a8.tar.gz
kernel-qcow2-util-linux-fafe46bc266b65ca524909b43701a3d06825d0a8.tar.xz
kernel-qcow2-util-linux-fafe46bc266b65ca524909b43701a3d06825d0a8.zip
libblkid: Expose more ISO9660 headers
In order to kill libosinfo's infamous udev rule[1], we need to make blkid report the following information as udev properties on IS09660 media so that libosinfo can make use of that for detection: 1. Volume ID (already exposed as label). 2. System ID. 3. Publisher ID. 4. Application ID. 5. Boot record's boot system ID, (almost always 'EL TORITO SPECIFICATION' if boot record is present). Example use: $ blkid -p -o udev Fedora-17-x86_64-DVD.iso ID_FS_SYSTEM_ID=LINUX ID_FS_APPLICATION_ID=GENISOIMAGE ISO 9660/HFS FILESYSTEM CREATOR (C) 1993 E.YOUNGDALE ID_FS_UUID=2012-05-22-20-55-32-00 ID_FS_UUID_ENC=2012-05-22-20-55-32-00 ID_FS_BOOT_SYSTEM_ID=EL TORITO SPECIFICATION ID_FS_LABEL=Fedora_17_x86_64 ID_FS_LABEL_ENC=Fedora\x2017\x20x86_64 ID_FS_TYPE=iso9660 ID_PART_TABLE_TYPE=dos [1] https://fedorahosted.org/libosinfo/ticket/1 [kzak@redhat.com: - add blkid_ltrim_whitespace() and use it together with blkid_rtrim_whitespace() to trim white spaces - enlarge blkid values to 128 bytes - add generic blkid_probe_set_id_label() function - always terminate all _ID with \0 - don't export the _IDs to blkid cache] Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libblkid/src/superblocks')
-rw-r--r--libblkid/src/superblocks/iso9660.c65
-rw-r--r--libblkid/src/superblocks/superblocks.c38
-rw-r--r--libblkid/src/superblocks/superblocks.h2
3 files changed, 100 insertions, 5 deletions
diff --git a/libblkid/src/superblocks/iso9660.c b/libblkid/src/superblocks/iso9660.c
index 33a8597ed..ad7bf3de1 100644
--- a/libblkid/src/superblocks/iso9660.c
+++ b/libblkid/src/superblocks/iso9660.c
@@ -16,6 +16,7 @@
#include <unistd.h>
#include <string.h>
#include <stdint.h>
+#include <ctype.h>
#include "superblocks.h"
@@ -41,14 +42,29 @@ struct iso_volume_descriptor {
unsigned char unused[8];
unsigned char space_size[8];
unsigned char escape_sequences[8];
- unsigned char unused1[717];
+ unsigned char unused1[222];
+ unsigned char publisher_id[128];
+ unsigned char unused2[128];
+ unsigned char application_id[128];
+ unsigned char unused3[111];
struct iso9660_date created;
struct iso9660_date modified;
} __attribute__((packed));
+/* Boot Record */
+struct boot_record {
+ unsigned char vd_type;
+ unsigned char vd_id[5];
+ unsigned char vd_version;
+ unsigned char boot_system_id[32];
+ unsigned char boot_id[32];
+ unsigned char unused[1];
+} __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_BOOT_RECORD 0x0
#define ISO_VD_SUPPLEMENTARY 0x2
#define ISO_VD_END 0xff
#define ISO_VD_MAX 16
@@ -136,6 +152,19 @@ static int probe_iso9660_set_uuid (blkid_probe pr, const struct iso9660_date *da
return 1;
}
+static int is_str_empty(const unsigned char *str, size_t len)
+{
+ size_t i;
+
+ if (!str || !*str)
+ return 1;
+
+ for (i = 0; i < len; i++)
+ if (!isspace(str[i]))
+ return 0;
+ return 1;
+}
+
/* iso9660 [+ Microsoft Joliet Extension] */
static int probe_iso9660(blkid_probe pr, const struct blkid_idmag *mag)
{
@@ -153,20 +182,46 @@ static int probe_iso9660(blkid_probe pr, const struct blkid_idmag *mag)
memcpy(label, iso->volume_id, sizeof(label));
+ if (!is_str_empty(iso->system_id, sizeof(iso->system_id)))
+ blkid_probe_set_id_label(pr, "SYSTEM_ID",
+ iso->system_id, sizeof(iso->system_id));
+
+ if (!is_str_empty(iso->publisher_id, sizeof(iso->publisher_id)))
+ blkid_probe_set_id_label(pr, "PUBLISHER_ID",
+ iso->publisher_id, sizeof(iso->publisher_id));
+
+ if (!is_str_empty(iso->application_id, sizeof(iso->application_id)))
+ blkid_probe_set_id_label(pr, "APPLICATION_ID",
+ iso->application_id, sizeof(iso->application_id));
+
/* create an UUID using the modified/created date */
if (! probe_iso9660_set_uuid(pr, &iso->modified))
probe_iso9660_set_uuid(pr, &iso->created);
- /* Joliet Extension */
+ /* Joliet Extension and Boot Record */
off = ISO_VD_OFFSET;
for (i = 0; i < ISO_VD_MAX; i++) {
- iso = (struct iso_volume_descriptor *)
+ struct boot_record *boot= (struct boot_record *)
blkid_probe_get_buffer(pr,
off,
- sizeof(struct iso_volume_descriptor));
+ sizeof(struct boot_record));
- if (iso == NULL || iso->vd_type == ISO_VD_END)
+ if (boot == NULL || boot->vd_type == ISO_VD_END)
break;
+
+ if (boot->vd_type == ISO_VD_BOOT_RECORD) {
+ if (!is_str_empty(boot->boot_system_id,
+ sizeof(boot->boot_system_id)))
+ blkid_probe_set_id_label(pr, "BOOT_SYSTEM_ID",
+ boot->boot_system_id,
+ sizeof(boot->boot_system_id));
+ off += ISO_SECTOR_SIZE;
+ continue;
+ }
+
+ /* Not a Boot record, lets see if its supplemntary volume descriptor */
+ iso = (struct iso_volume_descriptor *) boot;
+
if (iso->vd_type != ISO_VD_SUPPLEMENTARY) {
off += ISO_SECTOR_SIZE;
continue;
diff --git a/libblkid/src/superblocks/superblocks.c b/libblkid/src/superblocks/superblocks.c
index 62aa6625b..384d2cad7 100644
--- a/libblkid/src/superblocks/superblocks.c
+++ b/libblkid/src/superblocks/superblocks.c
@@ -64,6 +64,14 @@
* @SBMAGIC_OFFSET: offset of SBMAGIC
*
* @FSSIZE: size of filessystem [not-implemented yet]
+ *
+ * @SYSTEM_ID: ISO9660 system identifier
+ *
+ * @PUBLISHER_ID: ISO9660 publisher identifier
+ *
+ * @APPLICATION_ID: ISO9660 application identifier
+ *
+ * @BOOT_SYSTEM_ID: ISO9660 boot system identifier
*/
static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn);
@@ -495,6 +503,7 @@ int blkid_probe_set_version(blkid_probe pr, const char *version)
return 0;
}
+
int blkid_probe_sprintf_version(blkid_probe pr, const char *fmt, ...)
{
struct blkid_chain *chn = blkid_probe_get_chain(pr);
@@ -532,6 +541,35 @@ static int blkid_probe_set_usage(blkid_probe pr, int usage)
return blkid_probe_set_value(pr, "USAGE", (unsigned char *) u, strlen(u) + 1);
}
+int blkid_probe_set_id_label(blkid_probe pr, const char *name,
+ unsigned char *data, size_t len)
+{
+ struct blkid_chain *chn = blkid_probe_get_chain(pr);
+ struct blkid_prval *v;
+
+ if (!(chn->flags & BLKID_SUBLKS_LABEL))
+ return 0;
+
+ v = blkid_probe_assign_value(pr, name);
+ if (!v)
+ return -1;
+
+ if (len >= BLKID_PROBVAL_BUFSIZ)
+ len = BLKID_PROBVAL_BUFSIZ - 1; /* make a space for \0 */
+
+ memcpy(v->data, data, len);
+ v->data[len] = '\0';
+
+ /* remove white spaces */
+ v->len = blkid_rtrim_whitespace(v->data) + 1;
+ if (v->len > 1)
+ v->len = blkid_ltrim_whitespace(v->data) + 1;
+
+ if (v->len <= 1)
+ blkid_probe_reset_last_value(pr); /* ignore empty */
+ return 0;
+}
+
int blkid_probe_set_label(blkid_probe pr, unsigned char *label, size_t len)
{
struct blkid_chain *chn = blkid_probe_get_chain(pr);
diff --git a/libblkid/src/superblocks/superblocks.h b/libblkid/src/superblocks/superblocks.h
index 887732a73..e45dc6a84 100644
--- a/libblkid/src/superblocks/superblocks.h
+++ b/libblkid/src/superblocks/superblocks.h
@@ -89,5 +89,7 @@ extern int blkid_probe_strncpy_uuid(blkid_probe pr, unsigned char *str, size_t l
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);
+extern int blkid_probe_set_id_label(blkid_probe pr, const char *name,
+ unsigned char *data, size_t len);
#endif /* _BLKID_SUPERBLOCKS_H */