]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libblkid: Expose more ISO9660 headers
authorZeeshan Ali (Khattak) <zeeshanak@gnome.org>
Mon, 11 Feb 2013 21:22:12 +0000 (23:22 +0200)
committerKarel Zak <kzak@redhat.com>
Thu, 14 Feb 2013 11:11:34 +0000 (12:11 +0100)
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>
libblkid/src/blkidP.h
libblkid/src/probe.c
libblkid/src/superblocks/iso9660.c
libblkid/src/superblocks/superblocks.c
libblkid/src/superblocks/superblocks.h
libblkid/src/verify.c

index b18528d47ff2f6c078c9b2d542c825b13639d653..ed0c68c43ad10383e845d642dbe13c8974904aad 100644 (file)
@@ -120,9 +120,9 @@ struct blkid_chaindrv {
 /*
  * Low-level probe result
  */
-#define BLKID_PROBVAL_BUFSIZ   64
+#define BLKID_PROBVAL_BUFSIZ   128
 
-#define BLKID_NVALS_SUBLKS     14
+#define BLKID_NVALS_SUBLKS     18
 #define BLKID_NVALS_TOPLGY     5
 #define BLKID_NVALS_PARTS      13
 
@@ -504,6 +504,8 @@ extern void blkid_unparse_uuid(const unsigned char *uuid, char *str, size_t len)
                        __attribute__((nonnull));
 extern size_t blkid_rtrim_whitespace(unsigned char *str)
                        __attribute__((nonnull));
+extern size_t blkid_ltrim_whitespace(unsigned char *str)
+                       __attribute__((nonnull));
 
 extern void blkid_probe_set_wiper(blkid_probe pr, blkid_loff_t off,
                                  blkid_loff_t size)
index 9e3f8f6908523fb9ed81c040083b3ed37a0b9525..dd3ebcadeccefc4fce0a42a223a3550b4d3149da 100644 (file)
@@ -1659,6 +1659,24 @@ size_t blkid_rtrim_whitespace(unsigned char *str)
        return i;
 }
 
+/* Removes whitespace from the left-hand side of a string.
+ *
+ * Returns size of the new string (without \0).
+ */
+size_t blkid_ltrim_whitespace(unsigned char *str)
+{
+       size_t len;
+       unsigned char *p;
+
+       for (p = str; p && isspace(*p); p++);
+
+       len = strlen((char *) p);
+
+       if (len && p > str)
+               memmove(str, p, len + 1);
+
+       return len;
+}
 /*
  * Some mkfs-like utils wipe some parts (usually begin) of the device.
  * For example LVM (pvcreate) or mkswap(8). This information could be used
index 33a8597ed6f1fa92ff92c51215ef7c11a7f3f77f..ad7bf3de12370ee045835632dd7d64d39d760b0e 100644 (file)
@@ -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;
index 62aa6625b388b783d49106fb24cd4f2acfd0a24a..384d2cad7796837692bc3b5109386f6231c76fdb 100644 (file)
  * @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);
index 887732a7325d8c5fb1ad041cbce3a48187f897b7..e45dc6a84f246e9b9dc70831004d380f7d2e21ab 100644 (file)
@@ -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 */
index 9383e85706f13df98fee860efd585e9be17230c9..bd756e7a7b2dce92bf1dedaf61ed96dfe799b9ac 100644 (file)
@@ -38,8 +38,10 @@ static void blkid_probe_to_tags(blkid_probe pr, blkid_dev dev)
                                blkid_set_tag(dev, "PARTUUID", data, len);
                        else if (strcmp(name, "PART_ENTRY_NAME") == 0)
                                blkid_set_tag(dev, "PARTLABEL", data, len);
-               } else {
-                       /* superblock UUID, LABEL, ... */
+
+               } else if (!strstr(name, "_ID")) {
+                       /* superblock UUID, LABEL, ...
+                        * but not {SYSTEM,APPLICATION,..._ID} */
                        blkid_set_tag(dev, name, data, len);
                }
        }