]> git.proxmox.com Git - grub2.git/commitdiff
Make HFS implementation use MacRoman.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sat, 24 Dec 2011 19:20:41 +0000 (20:20 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sat, 24 Dec 2011 19:20:41 +0000 (20:20 +0100)
* grub-core/fs/hfs.c (MAX_UTF8_PER_MAC_ROMAN): New define.
(macroman): New const array.
(macroman_to_utf8): New function.
(utf8_to_macroman): Likewise.
(grub_hfs_find_dir): Use utf8_to_macroman.
(grub_hfs_dir): Use macroman_to_utf8.
Set case_insensitive.

ChangeLog
grub-core/fs/hfs.c

index dea64e198d6d17e779a0e7cc6af15e9d2b609833..ccfe212e7ef0afff6ffd4af45cb1277c2c433003 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2011-12-24  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Make HFS implementation to use MacRoman.
+
+       * grub-core/fs/hfs.c (MAX_UTF8_PER_MAC_ROMAN): New define.
+       (macroman): New const array.
+       (macroman_to_utf8): New function.
+       (utf8_to_macroman): Likewise.
+       (grub_hfs_find_dir): Use utf8_to_macroman.
+       (grub_hfs_dir): Use macroman_to_utf8.
+       Set case_insensitive.
+
 2011-12-24  Vladimir Serbinenko  <phcoder@gmail.com>
 
        * docs/grub.texi (Filesystems): Add IEEE1275 full-path example.
index 6c5c4da3ed6dfd46b9b30667d805474b0cab2fd0..4474ebef7fe8ab78e625153d66cb99f0b5832f1d 100644 (file)
@@ -862,6 +862,190 @@ grub_hfs_iterate_dir (struct grub_hfs_data *data, grub_uint32_t root_idx,
   return grub_errno;
 }
 
+#define MAX_UTF8_PER_MAC_ROMAN 3
+
+static const char macroman[0x80][MAX_UTF8_PER_MAC_ROMAN + 1] =
+  {
+    /* 80 */ "\xc3\x84",
+    /* 81 */ "\xc3\x85",
+    /* 82 */ "\xc3\x87",
+    /* 83 */ "\xc3\x89",
+    /* 84 */ "\xc3\x91",
+    /* 85 */ "\xc3\x96",
+    /* 86 */ "\xc3\x9c",
+    /* 87 */ "\xc3\xa1",
+    /* 88 */ "\xc3\xa0",
+    /* 89 */ "\xc3\xa2",
+    /* 8A */ "\xc3\xa4",
+    /* 8B */ "\xc3\xa3",
+    /* 8C */ "\xc3\xa5",
+    /* 8D */ "\xc3\xa7",
+    /* 8E */ "\xc3\xa9",
+    /* 8F */ "\xc3\xa8",
+    /* 90 */ "\xc3\xaa",
+    /* 91 */ "\xc3\xab",
+    /* 92 */ "\xc3\xad",
+    /* 93 */ "\xc3\xac",
+    /* 94 */ "\xc3\xae",
+    /* 95 */ "\xc3\xaf",
+    /* 96 */ "\xc3\xb1",
+    /* 97 */ "\xc3\xb3",
+    /* 98 */ "\xc3\xb2",
+    /* 99 */ "\xc3\xb4",
+    /* 9A */ "\xc3\xb6",
+    /* 9B */ "\xc3\xb5",
+    /* 9C */ "\xc3\xba",
+    /* 9D */ "\xc3\xb9",
+    /* 9E */ "\xc3\xbb",
+    /* 9F */ "\xc3\xbc",
+    /* A0 */ "\xe2\x80\xa0",
+    /* A1 */ "\xc2\xb0",
+    /* A2 */ "\xc2\xa2",
+    /* A3 */ "\xc2\xa3",
+    /* A4 */ "\xc2\xa7",
+    /* A5 */ "\xe2\x80\xa2",
+    /* A6 */ "\xc2\xb6",
+    /* A7 */ "\xc3\x9f",
+    /* A8 */ "\xc2\xae",
+    /* A9 */ "\xc2\xa9",
+    /* AA */ "\xe2\x84\xa2",
+    /* AB */ "\xc2\xb4",
+    /* AC */ "\xc2\xa8",
+    /* AD */ "\xe2\x89\xa0",
+    /* AE */ "\xc3\x86",
+    /* AF */ "\xc3\x98",
+    /* B0 */ "\xe2\x88\x9e",
+    /* B1 */ "\xc2\xb1",
+    /* B2 */ "\xe2\x89\xa4",
+    /* B3 */ "\xe2\x89\xa5",
+    /* B4 */ "\xc2\xa5",
+    /* B5 */ "\xc2\xb5",
+    /* B6 */ "\xe2\x88\x82",
+    /* B7 */ "\xe2\x88\x91",
+    /* B8 */ "\xe2\x88\x8f",
+    /* B9 */ "\xcf\x80",
+    /* BA */ "\xe2\x88\xab",
+    /* BB */ "\xc2\xaa",
+    /* BC */ "\xc2\xba",
+    /* BD */ "\xce\xa9",
+    /* BE */ "\xc3\xa6",
+    /* BF */ "\xc3\xb8",
+    /* C0 */ "\xc2\xbf",
+    /* C1 */ "\xc2\xa1",
+    /* C2 */ "\xc2\xac",
+    /* C3 */ "\xe2\x88\x9a",
+    /* C4 */ "\xc6\x92",
+    /* C5 */ "\xe2\x89\x88",
+    /* C6 */ "\xe2\x88\x86",
+    /* C7 */ "\xc2\xab",
+    /* C8 */ "\xc2\xbb",
+    /* C9 */ "\xe2\x80\xa6",
+    /* CA */ "\xc2\xa0",
+    /* CB */ "\xc3\x80",
+    /* CC */ "\xc3\x83",
+    /* CD */ "\xc3\x95",
+    /* CE */ "\xc5\x92",
+    /* CF */ "\xc5\x93",
+    /* D0 */ "\xe2\x80\x93",
+    /* D1 */ "\xe2\x80\x94",
+    /* D2 */ "\xe2\x80\x9c",
+    /* D3 */ "\xe2\x80\x9d",
+    /* D4 */ "\xe2\x80\x98",
+    /* D5 */ "\xe2\x80\x99",
+    /* D6 */ "\xc3\xb7",
+    /* D7 */ "\xe2\x97\x8a",
+    /* D8 */ "\xc3\xbf",
+    /* D9 */ "\xc5\xb8",
+    /* DA */ "\xe2\x81\x84",
+    /* DB */ "\xe2\x82\xac",
+    /* DC */ "\xe2\x80\xb9",
+    /* DD */ "\xe2\x80\xba",
+    /* DE */ "\xef\xac\x81",
+    /* DF */ "\xef\xac\x82",
+    /* E0 */ "\xe2\x80\xa1",
+    /* E1 */ "\xc2\xb7",
+    /* E2 */ "\xe2\x80\x9a",
+    /* E3 */ "\xe2\x80\x9e",
+    /* E4 */ "\xe2\x80\xb0",
+    /* E5 */ "\xc3\x82",
+    /* E6 */ "\xc3\x8a",
+    /* E7 */ "\xc3\x81",
+    /* E8 */ "\xc3\x8b",
+    /* E9 */ "\xc3\x88",
+    /* EA */ "\xc3\x8d",
+    /* EB */ "\xc3\x8e",
+    /* EC */ "\xc3\x8f",
+    /* ED */ "\xc3\x8c",
+    /* EE */ "\xc3\x93",
+    /* EF */ "\xc3\x94",
+    /* F0 */ "\xef\xa3\xbf",
+    /* F1 */ "\xc3\x92",
+    /* F2 */ "\xc3\x9a",
+    /* F3 */ "\xc3\x9b",
+    /* F4 */ "\xc3\x99",
+    /* F5 */ "\xc4\xb1",
+    /* F6 */ "\xcb\x86",
+    /* F7 */ "\xcb\x9c",
+    /* F8 */ "\xc2\xaf",
+    /* F9 */ "\xcb\x98",
+    /* FA */ "\xcb\x99",
+    /* FB */ "\xcb\x9a",
+    /* FC */ "\xc2\xb8",
+    /* FD */ "\xcb\x9d",
+    /* FE */ "\xcb\x9b",
+    /* FF */ "\xcb\x87",
+  };
+
+static void
+macroman_to_utf8 (char *to, const grub_uint8_t *from, grub_size_t len)
+{
+  char *optr = to;
+  const grub_uint8_t *iptr;
+
+  for (iptr = from; iptr < from + len && *iptr; iptr++)
+    {
+      if (!(*iptr & 0x80))
+       {
+         *optr++ = *iptr;
+         continue;
+       }
+      optr = grub_stpcpy (optr, macroman[*iptr & 0x7f]);
+    }
+  *optr = 0;
+}
+
+static grub_ssize_t
+utf8_to_macroman (grub_uint8_t *to, const char *from)
+{
+  grub_uint8_t *end = to + 31;
+  grub_uint8_t *optr = to;
+  const char *iptr = from;
+  
+  while (*iptr && optr < end)
+    {
+      int i, clen;
+      if (!(*iptr & 0x80))
+       {
+         *optr++ = *iptr++;
+         continue;
+       }
+      clen = 2;
+      if ((*iptr & 0xf0) == 0xe0)
+       clen++;
+      for (i = 0; i < 0x80; i++)
+       if (grub_memcmp (macroman[i], iptr, clen) == 0)
+         break;
+      if (i == 0x80)
+       break;
+      *optr++ = i | 0x80;
+      iptr += clen;
+    }
+  /* Too long or not encodable.  */
+  if (*iptr)
+    return -1;
+  return optr - to;
+}
+
 
 /* Find a file or directory with the pathname PATH in the filesystem
    DATA.  Return the file record in RETDATA when it is non-zero.
@@ -896,6 +1080,7 @@ grub_hfs_find_dir (struct grub_hfs_data *data, const char *path,
 
   while (path && grub_strlen (path))
     {
+      grub_ssize_t slen;
       if (fdrec.frec.type != GRUB_HFS_FILETYPE_DIR)
        {
          grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
@@ -913,8 +1098,13 @@ grub_hfs_find_dir (struct grub_hfs_data *data, const char *path,
       struct grub_hfs_catalog_key key;
 
       key.parent_dir = grub_cpu_to_be32 (inode);
-      key.strlen = grub_strlen (path);
-      grub_strcpy ((char *) (key.str), path);
+      slen = utf8_to_macroman (key.str, path);
+      if (slen < 0)
+       {
+         grub_error (GRUB_ERR_FILE_NOT_FOUND, "file `%s' not found", path);
+         goto fail;
+       }
+      key.strlen = slen;
 
       /* Lookup this node.  */
       if (! grub_hfs_find_node (data, (char *) &key, data->cat_root,
@@ -955,14 +1145,16 @@ grub_hfs_dir (grub_device_t device, const char *path,
 
   int dir_hook (struct grub_hfs_record *rec)
     {
-      char fname[32] = { 0 };
+      char fname[32 * MAX_UTF8_PER_MAC_ROMAN] = { 0 };
       struct grub_hfs_dirrec *drec = rec->data;
       struct grub_hfs_filerec *frec = rec->data;
       struct grub_hfs_catalog_key *ckey = rec->key;
       struct grub_dirhook_info info;
       grub_memset (&info, 0, sizeof (info));
 
-      grub_strncpy (fname, (char *) (ckey->str), ckey->strlen);
+      macroman_to_utf8 (fname, ckey->str, ckey->strlen);
+
+      info.case_insensitive = 1;
 
       if (drec->type == GRUB_HFS_FILETYPE_DIR)
        {