chiark / gitweb /
[PATCH] volume_id: version 41
authorkay.sievers@vrfy.org <kay.sievers@vrfy.org>
Fri, 11 Mar 2005 07:02:47 +0000 (08:02 +0100)
committerGreg KH <gregkh@suse.de>
Wed, 27 Apr 2005 06:53:17 +0000 (23:53 -0700)
extras/volume_id/volume_id/iso9660.c
extras/volume_id/volume_id/util.c
extras/volume_id/volume_id/util.h
extras/volume_id/volume_id/volume_id.h

index d4ccb9d..5d4ab92 100644 (file)
 #define ISO_VD_END                     0xff
 #define ISO_VD_MAX                     16
 
-union iso_super_block {
-       struct iso_header {
-               __u8    type;
-               __u8    id[5];
-               __u8    version;
-               __u8    unused1;
-               __u8            system_id[32];
-               __u8            volume_id[32];
-       } __attribute__((__packed__)) iso;
-       struct hs_header {
-               __u8    foo[8];
-               __u8    type;
-               __u8    id[4];
-               __u8    version;
-       } __attribute__((__packed__)) hs;
+struct iso_volume_descriptor {
+       __u8    vd_type;
+       __u8    vd_id[5];
+       __u8    vd_version;
+       __u8    flags;
+       __u8    system_id[32];
+       __u8    volume_id[32];
+       __u8    unused[8];
+       __u8    space_size[8];
+       __u8    escape_sequences[8];
+} __attribute__((__packed__));
+
+struct high_sierra_volume_descriptor {
+       __u8    foo[8];
+       __u8    type;
+       __u8    id[4];
+       __u8    version;
 } __attribute__((__packed__));
 
 int volume_id_probe_iso9660(struct volume_id *id, __u64 off)
 {
-       union iso_super_block *is;
+       __u8 *buf;
+       struct iso_volume_descriptor *is;
+       struct high_sierra_volume_descriptor *hs;
 
        dbg("probing at offset 0x%llx", (unsigned long long) off);
 
-       is = (union iso_super_block *) volume_id_get_buffer(id, off + ISO_SUPERBLOCK_OFFSET, 0x200);
-       if (is == NULL)
+       buf = volume_id_get_buffer(id, off + ISO_SUPERBLOCK_OFFSET, 0x200);
+       if (buf == NULL)
                return -1;
 
-       if (memcmp(is->iso.id, "CD001", 5) == 0) {
-               char root_label[VOLUME_ID_LABEL_SIZE+1];
+       is = (struct iso_volume_descriptor *) buf;
+
+       if (memcmp(is->vd_id, "CD001", 5) == 0) {
                int vd_offset;
                int i;
-               int found_svd;
 
-               memset(root_label, 0, sizeof(root_label));
-               strncpy(root_label, is->iso.volume_id, sizeof(root_label)-1);
+               dbg("read label from PVD");
+               volume_id_set_label_raw(id, is->volume_id, 32);
+               volume_id_set_label_string(id, is->volume_id, 32);
 
-               found_svd = 0;
+               dbg("looking for SVDs");
                vd_offset = ISO_VD_OFFSET;
                for (i = 0; i < ISO_VD_MAX; i++) {
-                       is = (union iso_super_block *) volume_id_get_buffer(id, off + vd_offset, 0x200);
-                       if (is == NULL || is->iso.type == ISO_VD_END)
-                               break;
-                       if (is->iso.type == ISO_VD_SUPPLEMENTARY) {
-                               dbg("found ISO supplementary VD at offset 0x%llx", (unsigned long long) (off + vd_offset));
-                               volume_id_set_label_raw(id, is->iso.volume_id, 32);
-                               volume_id_set_label_unicode16(id, is->iso.volume_id, BE, 32);
-                               found_svd = 1;
+                       char svd_label[64];
+
+                       is = (struct iso_volume_descriptor *) volume_id_get_buffer(id, off + vd_offset, 0x200);
+                       if (is == NULL || is->vd_type == ISO_VD_END)
                                break;
+                       if (is->vd_type != ISO_VD_SUPPLEMENTARY)
+                               continue;
+
+                       dbg("found SVD at offset 0x%llx", (unsigned long long) (off + vd_offset));
+                       if (memcmp(is->escape_sequences, "%/@", 3) == 0||
+                           memcmp(is->escape_sequences, "%/C", 3) == 0||
+                           memcmp(is->escape_sequences, "%/E", 3) == 0) {
+                               dbg("Joliet extension found");
+                               volume_id_set_unicode16(svd_label, sizeof(svd_label), is->volume_id, BE, 32);
+                               if (memcmp(id->label, svd_label, 16) == 0) {
+                                       dbg("SVD label is identical, use the possibly longer PVD one");
+                                       break;
+                               }
+
+                               volume_id_set_label_raw(id, is->volume_id, 32);
+                               volume_id_set_label_string(id, svd_label, 32);
+                               strcpy(id->type_version, "Joliet Extension");
+                               goto found;
                        }
                        vd_offset += ISO_SECTOR_SIZE;
                }
-
-               if (!found_svd ||
-                   (found_svd && !memcmp(root_label, id->label, 16)))
-               {
-                       volume_id_set_label_raw(id, root_label, 32);
-                       volume_id_set_label_string(id, root_label, 32);
-               }
                goto found;
        }
-       if (memcmp(is->hs.id, "CDROM", 5) == 0)
+
+       hs = (struct high_sierra_volume_descriptor *) buf;
+
+       if (memcmp(hs->id, "CDROM", 5) == 0) {
+               strcpy(id->type_version, "High Sierra");
                goto found;
+       }
+
        return -1;
 
 found:
index 22abc9c..7499fc1 100644 (file)
 #include "logging.h"
 #include "util.h"
 
+void volume_id_set_unicode16(char *str, unsigned int len, const __u8 *buf, enum endian endianess, unsigned int count)
+{
+       unsigned int i, j;
+       __u16 c;
+
+       j = 0;
+       for (i = 0; i + 2 <= count; i += 2) {
+               if (endianess == LE)
+                       c = (buf[i+1] << 8) | buf[i];
+               else
+                       c = (buf[i] << 8) | buf[i+1];
+               if (c == 0) {
+                       str[j] = '\0';
+                       break;
+               } else if (c < 0x80) {
+                       if (j+1 >= len)
+                               break;
+                       str[j++] = (__u8) c;
+               } else if (c < 0x800) {
+                       if (j+2 >= len)
+                               break;
+                       str[j++] = (__u8) (0xc0 | (c >> 6));
+                       str[j++] = (__u8) (0x80 | (c & 0x3f));
+               } else {
+                       if (j+3 >= len)
+                               break;
+                       str[j++] = (__u8) (0xe0 | (c >> 12));
+                       str[j++] = (__u8) (0x80 | ((c >> 6) & 0x3f));
+                       str[j++] = (__u8) (0x80 | (c & 0x3f));
+               }
+       }
+       str[j] = '\0';
+}
+
 static char *usage_to_string(enum volume_id_usage usage_id)
 {
        switch (usage_id) {
@@ -98,29 +132,7 @@ void volume_id_set_label_string(struct volume_id *id, const __u8 *buf, unsigned
 
 void volume_id_set_label_unicode16(struct volume_id *id, const __u8 *buf, enum endian endianess, unsigned int count)
 {
-       unsigned int i, j;
-       __u16 c;
-
-       j = 0;
-       for (i = 0; i + 2 <= count; i += 2) {
-               if (endianess == LE)
-                       c = (buf[i+1] << 8) | buf[i];
-               else
-                       c = (buf[i] << 8) | buf[i+1];
-               if (c == 0) {
-                       id->label[j] = '\0';
-                       break;
-               } else if (c < 0x80) {
-                       id->label[j++] = (__u8) c;
-               } else if (c < 0x800) {
-                       id->label[j++] = (__u8) (0xc0 | (c >> 6));
-                       id->label[j++] = (__u8) (0x80 | (c & 0x3f));
-               } else {
-                       id->label[j++] = (__u8) (0xe0 | (c >> 12));
-                       id->label[j++] = (__u8) (0x80 | ((c >> 6) & 0x3f));
-                       id->label[j++] = (__u8) (0x80 | (c & 0x3f));
-               }
-       }
+        volume_id_set_unicode16(id->label, sizeof(id->label), buf, endianess, count);
 }
 
 void volume_id_set_uuid(struct volume_id *id, const __u8 *buf, enum uuid_format format)
index 0357b42..9cea8fc 100644 (file)
@@ -83,6 +83,7 @@ enum endian {
        BE = 1
 };
 
+extern void volume_id_set_unicode16(char *str, unsigned int len, const __u8 *buf, enum endian endianess, unsigned int count);
 extern void volume_id_set_usage(struct volume_id *id, enum volume_id_usage usage_id);
 extern void volume_id_set_usage_part(struct volume_id_partition *part, enum volume_id_usage usage_id);
 extern void volume_id_set_label_raw(struct volume_id *id, const __u8 *buf, unsigned int count);
index 8287de2..0a273fb 100644 (file)
@@ -21,7 +21,7 @@
 #ifndef _VOLUME_ID_H_
 #define _VOLUME_ID_H_
 
-#define VOLUME_ID_VERSION              40
+#define VOLUME_ID_VERSION              41
 
 #define VOLUME_ID_LABEL_SIZE           64
 #define VOLUME_ID_UUID_SIZE            36