grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] support joliet extension in iso9660 filesystem


From: Bean
Subject: Re: [PATCH] support joliet extension in iso9660 filesystem
Date: Tue, 5 Feb 2008 05:16:40 +0800

On Feb 4, 2008 11:52 PM, Marco Gerards <address@hidden> wrote:
> > This patch add joliet extension support for iso9660.
>
> Great!  Hopefully Rockridge still works?

i have tested -R, -J and -R -J to build iso, it all works well.

> > +  int sec;
>
> sec?

changed to block

> Why did the indentation change for the lines above?
I use -b option to create the patch, maybe i can some problem with
indentation, it should be ok now.

> > -      grub_error (GRUB_ERR_BAD_FS, "not a iso9660 filesystem");
> > -      goto fail;
> > +          is_copy = 1;
>
> is_copy?

changed to copy_voldesc

2008-02-04  Bean  <address@hidden>

        * fs/iso9660.c (GRUB_ISO9660_VOLDESC_BOOT): New macro.
        (GRUB_ISO9660_VOLDESC_PRIMARY): Likewise.
        (GRUB_ISO9660_VOLDESC_SUPP): Likewise.
        (GRUB_ISO9660_VOLDESC_PART): Likewise.
        (GRUB_ISO9660_VOLDESC_END): Likewise.
        (grub_iso9660_primary_voldesc): New member escape.
        (grub_iso9660_data): New member joliet.
        (grub_iso9660_convert_string): New function.
        (grub_iso9660_mount): Detect joliet extension.
        (grub_iso9660_iterate_dir): Convert filename when joliet is detected.
        (grub_iso9660_iso9660_label): Likewise.

diff --git a/fs/iso9660.c b/fs/iso9660.c
index 15ce51d..374ec24 100644
--- a/fs/iso9660.c
+++ b/fs/iso9660.c
@@ -38,6 +38,12 @@
 #define GRUB_ISO9660_RR_DOT            2
 #define GRUB_ISO9660_RR_DOTDOT         4

+#define GRUB_ISO9660_VOLDESC_BOOT      0
+#define GRUB_ISO9660_VOLDESC_PRIMARY   1
+#define GRUB_ISO9660_VOLDESC_SUPP      2
+#define GRUB_ISO9660_VOLDESC_PART      3
+#define GRUB_ISO9660_VOLDESC_END       255
+
 /* The head of a volume descriptor.  */
 struct grub_iso9660_voldesc
 {
@@ -67,11 +73,13 @@ struct grub_iso9660_primary_voldesc
   struct grub_iso9660_voldesc voldesc;
   grub_uint8_t unused1[33];
   grub_uint8_t volname[32];
-  grub_uint8_t unused2[60];
+  grub_uint8_t unused2[16];
+  grub_uint8_t escape[32];
+  grub_uint8_t unused3[12];
   grub_uint32_t path_table_size;
-  grub_uint8_t unused3[4];
+  grub_uint8_t unused4[4];
   grub_uint32_t path_table;
-  grub_uint8_t unused4[12];
+  grub_uint8_t unused5[12];
   struct grub_iso9660_dir rootdir;
 } __attribute__ ((packed));

@@ -115,6 +123,7 @@ struct grub_iso9660_data
   unsigned int length;
   int rockridge;
   int susp_skip;
+  int joliet;
 };

 struct grub_fshelp_node
@@ -197,6 +206,23 @@ grub_iso9660_susp_iterate (struct grub_iso9660_data *data,
   return 0;
 }

+static char *
+grub_iso9660_convert_string (grub_uint16_t *us, int len)
+{
+  char *p;
+  int i;
+
+  p = grub_malloc (len * 4 + 1);
+  if (! p)
+    return p;
+
+  for (i=0; i<len; i++)
+    us[i] = grub_be_to_cpu16 (us[i]);
+
+  *grub_utf16_to_utf8 ((grub_uint8_t *) p, us, len) = '\0';
+
+  return p;
+}

 static struct grub_iso9660_data *
 grub_iso9660_mount (grub_disk_t disk)
@@ -207,6 +233,8 @@ grub_iso9660_mount (grub_disk_t disk)
   int sua_size;
   char *sua;
   struct grub_iso9660_susp_entry *entry;
+  struct grub_iso9660_primary_voldesc voldesc;
+  int block;

   auto grub_err_t susp_iterate (struct grub_iso9660_susp_entry *);

@@ -226,24 +254,49 @@ grub_iso9660_mount (grub_disk_t disk)
   if (! data)
     return 0;

-  /* Read the superblock.  */
-  if (grub_disk_read (disk, 16 << GRUB_ISO9660_LOG2_BLKSZ, 0,
-                     sizeof (struct grub_iso9660_primary_voldesc),
-                     (char *) &data->voldesc))
-    {
-      grub_error (GRUB_ERR_BAD_FS, "not a iso9660 filesystem");
-      goto fail;
-    }
-
-  if (grub_strncmp ((char *) data->voldesc.voldesc.magic, "CD001", 5) != 0)
-    {
-      grub_error (GRUB_ERR_BAD_FS, "not a iso9660 filesystem");
-      goto fail;
-    }
-
   data->disk = disk;
   data->rockridge = 0;
-
+  data->joliet = 0;
+
+  block = 16;
+  do
+    {
+      int copy_voldesc = 0;
+
+      /* Read the superblock.  */
+      if (grub_disk_read (disk, block << GRUB_ISO9660_LOG2_BLKSZ, 0,
+                         sizeof (struct grub_iso9660_primary_voldesc),
+                         (char *) &voldesc))
+        {
+          grub_error (GRUB_ERR_BAD_FS, "not a iso9660 filesystem");
+          goto fail;
+        }
+
+      if (grub_strncmp ((char *) voldesc.voldesc.magic, "CD001", 5) != 0)
+        {
+          grub_error (GRUB_ERR_BAD_FS, "not a iso9660 filesystem");
+          goto fail;
+        }
+
+      if (voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_PRIMARY)
+        copy_voldesc = 1;
+      else if ((voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_SUPP) &&
+               (voldesc.escape[0] == 0x25) && (voldesc.escape[1] == 0x2f) &&
+               ((voldesc.escape[2] == 0x40) || /* UCS-2 Level 1.  */
+                (voldesc.escape[2] == 0x43) ||  /* UCS-2 Level 2.  */
+                (voldesc.escape[2] == 0x45)))  /* UCS-2 Level 3.  */
+        {
+          copy_voldesc = 1;
+          data->joliet = 1;
+        }
+
+      if (copy_voldesc)
+        grub_memcpy((char *) &data->voldesc, (char *) &voldesc,
+                    sizeof (struct grub_iso9660_primary_voldesc));
+
+      block++;
+    } while (voldesc.voldesc.type != GRUB_ISO9660_VOLDESC_END);
+
   /* Read the system use area and test it to see if SUSP is
      supported.  */
   if (grub_disk_read (disk, (grub_le_to_cpu32
(data->voldesc.rootdir.first_sector)
@@ -254,14 +307,6 @@ grub_iso9660_mount (grub_disk_t disk)
       goto fail;
     }

-  if (grub_disk_read (disk, (grub_le_to_cpu32
(data->voldesc.rootdir.first_sector)
-                            << GRUB_ISO9660_LOG2_BLKSZ), 0,
-                     sizeof (rootdir), (char *) &rootdir))
-    {
-      grub_error (GRUB_ERR_BAD_FS, "not a iso9660 filesystem");
-      goto fail;
-    }
-
   sua_pos = (sizeof (rootdir) + rootdir.namelen
             + (rootdir.namelen % 2) - 1);
   sua_size = rootdir.len - sua_pos;
@@ -572,6 +617,20 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
              filename = name;
          }
        
+        if (dir->data->joliet)
+          {
+            char *oldname;
+
+            oldname = filename;
+            filename = grub_iso9660_convert_string
+                  ((grub_uint16_t *) oldname, dirent.namelen >> 1);
+
+            if (filename_alloc)
+              grub_free (oldname);
+
+            filename_alloc = 1;
+          }
+
        if (hook (filename, type, node))
          {
            if (filename_alloc)
@@ -740,7 +799,11 @@ grub_iso9660_label (grub_device_t device, char **label)

   if (data)
     {
-      *label = grub_strndup ((char *) data->voldesc.volname, 32);
+      if (data->joliet)
+        *label = grub_iso9660_convert_string
+                 ((grub_uint16_t *) &data->voldesc.volname, 16);
+      else
+        *label = grub_strndup ((char *) data->voldesc.volname, 32);
       grub_free (data);
     }
   else

--
Bean




reply via email to

[Prev in Thread] Current Thread [Next in Thread]