All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] * grub-core/fs/udf.c: Add support for UUID
@ 2017-04-10 18:35 Pali Rohár
  2017-04-19 17:48 ` Pali Rohár
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Pali Rohár @ 2017-04-10 18:35 UTC (permalink / raw)
  To: grub-devel; +Cc: Pali Rohár

Use same algorithm as in libblkid from util-linux.
---
 grub-core/fs/udf.c |  136 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 131 insertions(+), 5 deletions(-)

diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c
index 839bff8..a4baa4c 100644
--- a/grub-core/fs/udf.c
+++ b/grub-core/fs/udf.c
@@ -321,6 +321,32 @@ struct grub_udf_partmap
   };
 } GRUB_PACKED;
 
+struct grub_udf_pvd
+{
+  struct grub_udf_tag tag;
+  grub_uint32_t seq_num;
+  grub_uint32_t pvd_num;
+  grub_uint8_t ident[32];
+  grub_uint16_t vol_seq_num;
+  grub_uint16_t max_vol_seq_num;
+  grub_uint16_t interchange_level;
+  grub_uint16_t max_interchange_level;
+  grub_uint32_t charset_list;
+  grub_uint32_t max_charset_list;
+  grub_uint8_t volset_ident[128];
+  struct grub_udf_charspec desc_charset;
+  struct grub_udf_charspec expl_charset;
+  struct grub_udf_extent_ad vol_abstract;
+  struct grub_udf_extent_ad vol_copyright;
+  struct grub_udf_regid app_ident;
+  struct grub_udf_timestamp recording_time;
+  struct grub_udf_regid imp_ident;
+  grub_uint8_t imp_use[64];
+  grub_uint32_t pred_vds_loc;
+  grub_uint16_t flags;
+  grub_uint8_t reserved[22];
+} GRUB_PACKED;
+
 struct grub_udf_lvd
 {
   struct grub_udf_tag tag;
@@ -348,6 +374,7 @@ struct grub_udf_aed
 struct grub_udf_data
 {
   grub_disk_t disk;
+  struct grub_udf_pvd pvd;
   struct grub_udf_lvd lvd;
   struct grub_udf_pd pds[GRUB_UDF_MAX_PDS];
   struct grub_udf_partmap *pms[GRUB_UDF_MAX_PMS];
@@ -692,7 +719,17 @@ grub_udf_mount (grub_disk_t disk)
 	}
 
       tag.tag_ident = U16 (tag.tag_ident);
-      if (tag.tag_ident == GRUB_UDF_TAG_IDENT_PD)
+      if (tag.tag_ident == GRUB_UDF_TAG_IDENT_PVD)
+	{
+	  if (grub_disk_read (disk, block << lbshift, 0,
+			      sizeof (struct grub_udf_pvd),
+			      &data->pvd))
+	    {
+	      grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
+	      goto fail;
+	    }
+	}
+      else if (tag.tag_ident == GRUB_UDF_TAG_IDENT_PD)
 	{
 	  if (data->npd >= GRUB_UDF_MAX_PDS)
 	    {
@@ -821,7 +858,7 @@ grub_udf_get_cluster_sector (grub_disk_t disk, grub_uint64_t *sec_per_lcn)
 #endif
 
 static char *
-read_string (const grub_uint8_t *raw, grub_size_t sz, char *outbuf)
+read_string (const grub_uint8_t *raw, grub_size_t sz, char *outbuf, int normalize_utf8)
 {
   grub_uint16_t *utf16 = NULL;
   grub_size_t utf16len = 0;
@@ -832,6 +869,15 @@ read_string (const grub_uint8_t *raw, grub_size_t sz, char *outbuf)
   if (raw[0] != 8 && raw[0] != 16)
     return NULL;
 
+  if (raw[0] == 8 && !normalize_utf8)
+    {
+      if (!outbuf)
+        outbuf = grub_strndup ((char *)raw + 1, sz - 1);
+      else
+        grub_memcpy (outbuf, raw + 1, sz - 1);
+      return outbuf;
+    }
+
   if (raw[0] == 8)
     {
       unsigned i;
@@ -923,7 +969,7 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir,
 		  != dirent.file_ident_length)
 		return 0;
 
-	      filename = read_string (raw, dirent.file_ident_length, 0);
+	      filename = read_string (raw, dirent.file_ident_length, 0, 1);
 	      if (!filename)
 		grub_print_error ();
 
@@ -1009,7 +1055,7 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
 	  /* in 4 + n bytes. out, at most: 1 + 2 * n bytes.  */
 	  if (optr != out)
 	    *optr++ = '/';
-	  if (!read_string (ptr + 4, s - 4, optr))
+	  if (!read_string (ptr + 4, s - 4, optr, 1))
 	    goto fail;
 	  optr += grub_strlen (optr);
 	  break;
@@ -1197,7 +1243,7 @@ grub_udf_label (grub_device_t device, char **label)
 
   if (data)
     {
-      *label = read_string (data->lvd.ident, sizeof (data->lvd.ident), 0);
+      *label = read_string (data->lvd.ident, sizeof (data->lvd.ident), 0, 1);
       grub_free (data);
     }
   else
@@ -1206,6 +1252,85 @@ grub_udf_label (grub_device_t device, char **label)
   return grub_errno;
 }
 
+static char *
+gen_uuid_from_volset (char *volset_ident)
+{
+  grub_size_t i;
+  grub_size_t len;
+  grub_size_t binpos;
+  grub_uint8_t buf[17];
+  char *uuid;
+
+  len = grub_strlen (volset_ident);
+  if (len < 8)
+    return NULL;
+
+  uuid = grub_malloc (17);
+  if (!uuid)
+    return NULL;
+
+  if (len > 16)
+    len = 16;
+
+  grub_memset (buf, 0, sizeof (buf));
+  grub_memcpy (buf, volset_ident, len);
+
+  binpos = 16;
+  for (i = 0; i < len; ++i)
+    {
+      if (!grub_isalnum (buf[i]))
+        {
+          binpos = i;
+          break;
+        }
+    }
+
+  if (binpos < 8)
+    {
+      grub_snprintf (uuid, 17, "%02x%02x%02x%02x%02x%02x%02x%02x",
+                    buf[0], buf[1], buf[2], buf[3],
+                    buf[4], buf[5], buf[6], buf[7]);
+    }
+  else if (binpos < 16)
+    {
+      grub_memcpy (uuid, buf, 8);
+      grub_snprintf (uuid+8, 9, "%02x%02x%02x%02x",
+                    buf[8], buf[9], buf[10], buf[11]);
+    }
+  else
+    {
+      grub_memcpy (uuid, buf, 16);
+      uuid[16] = 0;
+    }
+
+  return uuid;
+}
+
+static grub_err_t
+grub_udf_uuid (grub_device_t device, char **uuid)
+{
+  char *volset_ident;
+  struct grub_udf_data *data;
+  data = grub_udf_mount (device->disk);
+
+  if (data)
+    {
+      volset_ident = read_string (data->pvd.volset_ident, sizeof (data->pvd.volset_ident), 0, 0);
+      if (volset_ident)
+        {
+          *uuid = gen_uuid_from_volset (volset_ident);
+          grub_free (volset_ident);
+        }
+      else
+        *uuid = 0;
+      grub_free (data);
+    }
+  else
+    *uuid = 0;
+
+  return grub_errno;
+}
+
 static struct grub_fs grub_udf_fs = {
   .name = "udf",
   .dir = grub_udf_dir,
@@ -1213,6 +1338,7 @@ static struct grub_fs grub_udf_fs = {
   .read = grub_udf_read,
   .close = grub_udf_close,
   .label = grub_udf_label,
+  .uuid = grub_udf_uuid,
 #ifdef GRUB_UTIL
   .reserved_first_sector = 1,
   .blocklist_install = 1,
-- 
1.7.9.5



^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2017-08-07 15:50 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-04-10 18:35 [PATCH] * grub-core/fs/udf.c: Add support for UUID Pali Rohár
2017-04-19 17:48 ` Pali Rohár
2017-04-19 18:11   ` Andrei Borzenkov
2017-05-08 12:55   ` Pali Rohár
2017-05-08 13:13 ` Vladimir 'phcoder' Serbinenko
2017-05-08 14:24   ` Pali Rohár
2017-05-11 10:59     ` Pali Rohár
2017-05-12 14:39   ` Pali Rohár
2017-06-22 12:42 ` [PATCH v2] " Pali Rohár
2017-08-07 15:50   ` Vladimir 'phcoder' Serbinenko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.