/*
* 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
__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)
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
#include <unistd.h>
#include <string.h>
#include <stdint.h>
+#include <ctype.h>
#include "superblocks.h"
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
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)
{
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;
* @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);
return 0;
}
+
int blkid_probe_sprintf_version(blkid_probe pr, const char *fmt, ...)
{
struct blkid_chain *chn = blkid_probe_get_chain(pr);
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);
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 */
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);
}
}