[Top][All Lists]
[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