144
147
grub_uint32_t fileid;
145
148
grub_uint8_t unused2[2];
146
149
grub_uint32_t size;
147
grub_uint8_t unused3[44];
150
grub_uint8_t unused3[18];
152
grub_uint8_t unused4[22];
149
154
/* The first 3 extents of the file. The other extents can be found
150
155
in the extent overflow file. */
240
245
grub_hfs_read_file (struct grub_hfs_data *data,
241
246
void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
242
247
unsigned offset, unsigned length),
243
int pos, grub_size_t len, char *buf)
248
grub_off_t pos, grub_size_t len, char *buf)
248
blockcnt = ((len + pos)
249
+ data->blksz - 1) / data->blksz;
251
for (i = pos / data->blksz; i < blockcnt; i++)
253
blockcnt = grub_divmod64 (((len + pos)
254
+ data->blksz - 1), data->blksz, 0);
256
for (i = grub_divmod64 (pos, data->blksz, 0); i < blockcnt; i++)
254
int blockoff = pos % data->blksz;
255
int blockend = data->blksz;
258
grub_disk_addr_t blknr;
260
grub_off_t blockend = data->blksz;
257
262
int skipfirst = 0;
264
grub_divmod64 (pos, data->blksz, &blockoff);
259
266
blknr = grub_hfs_block (data, data->extents, data->fileid, i, 1);
323
330
/* Check if this is a HFS filesystem. */
324
if (grub_be_to_cpu16 (data->sblock.magic) != GRUB_HFS_MAGIC)
331
if (grub_be_to_cpu16 (data->sblock.magic) != GRUB_HFS_MAGIC
332
|| (data->sblock.blksz & grub_cpu_to_be32_compile_time (0xc00001ff)))
326
334
grub_error (GRUB_ERR_BAD_FS, "not an HFS filesystem");
744
752
entry. In case of a non-leaf mode it will be used to lookup
745
753
the rest of the tree. */
748
grub_uint32_t *node = (grub_uint32_t *) rec->data;
749
found = grub_be_to_cpu32 (*node);
755
found = grub_be_to_cpu32 (grub_get_unaligned32 (rec->data));
751
756
else /* The key can not be found in the tree. */
811
816
struct grub_hfs_catalog_key *ckey = rec->key;
813
818
if (grub_hfs_cmp_catkeys (rec->key, (void *) &key) <= 0)
814
found = grub_be_to_cpu32 (*(grub_uint32_t *) rec->data);
819
found = grub_be_to_cpu32 (grub_get_unaligned32 (rec->data));
816
821
if (hnd->type == 0xFF && ckey->strlen > 0)
859
864
return grub_errno;
867
#define MAX_UTF8_PER_MAC_ROMAN 3
869
static const char macroman[0x80][MAX_UTF8_PER_MAC_ROMAN + 1] =
903
/* A0 */ "\xe2\x80\xa0",
908
/* A5 */ "\xe2\x80\xa2",
913
/* AA */ "\xe2\x84\xa2",
916
/* AD */ "\xe2\x89\xa0",
919
/* B0 */ "\xe2\x88\x9e",
921
/* B2 */ "\xe2\x89\xa4",
922
/* B3 */ "\xe2\x89\xa5",
925
/* B6 */ "\xe2\x88\x82",
926
/* B7 */ "\xe2\x88\x91",
927
/* B8 */ "\xe2\x88\x8f",
929
/* BA */ "\xe2\x88\xab",
938
/* C3 */ "\xe2\x88\x9a",
940
/* C5 */ "\xe2\x89\x88",
941
/* C6 */ "\xe2\x88\x86",
944
/* C9 */ "\xe2\x80\xa6",
951
/* D0 */ "\xe2\x80\x93",
952
/* D1 */ "\xe2\x80\x94",
953
/* D2 */ "\xe2\x80\x9c",
954
/* D3 */ "\xe2\x80\x9d",
955
/* D4 */ "\xe2\x80\x98",
956
/* D5 */ "\xe2\x80\x99",
958
/* D7 */ "\xe2\x97\x8a",
961
/* DA */ "\xe2\x81\x84",
962
/* DB */ "\xe2\x82\xac",
963
/* DC */ "\xe2\x80\xb9",
964
/* DD */ "\xe2\x80\xba",
965
/* DE */ "\xef\xac\x81",
966
/* DF */ "\xef\xac\x82",
967
/* E0 */ "\xe2\x80\xa1",
969
/* E2 */ "\xe2\x80\x9a",
970
/* E3 */ "\xe2\x80\x9e",
971
/* E4 */ "\xe2\x80\xb0",
983
/* F0 */ "\xef\xa3\xbf",
1002
macroman_to_utf8 (char *to, const grub_uint8_t *from, grub_size_t len,
1003
int translate_slash)
1006
const grub_uint8_t *iptr;
1008
for (iptr = from; iptr < from + len && *iptr; iptr++)
1010
/* Translate '/' to ':' as per HFS spec. */
1011
if (*iptr == '/' && translate_slash)
1016
if (!(*iptr & 0x80))
1021
optr = grub_stpcpy (optr, macroman[*iptr & 0x7f]);
1027
utf8_to_macroman (grub_uint8_t *to, const char *from)
1029
grub_uint8_t *end = to + 31;
1030
grub_uint8_t *optr = to;
1031
const char *iptr = from;
1033
while (*iptr && optr < end)
1036
/* Translate ':' to '/' as per HFS spec. */
1043
if (!(*iptr & 0x80))
1049
if ((*iptr & 0xf0) == 0xe0)
1051
for (i = 0; i < 0x80; i++)
1052
if (grub_memcmp (macroman[i], iptr, clen) == 0)
1059
/* Too long or not encodable. */
863
1066
/* Find a file or directory with the pathname PATH in the filesystem
864
1067
DATA. Return the file record in RETDATA when it is non-zero.
894
1097
while (path && grub_strlen (path))
896
1100
if (fdrec.frec.type != GRUB_HFS_FILETYPE_DIR)
898
grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
1102
grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
910
1114
struct grub_hfs_catalog_key key;
912
1116
key.parent_dir = grub_cpu_to_be32 (inode);
913
key.strlen = grub_strlen (path);
914
grub_strcpy ((char *) (key.str), path);
1117
slen = utf8_to_macroman (key.str, path);
1120
grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), path);
916
1125
/* Lookup this node. */
917
1126
if (! grub_hfs_find_node (data, (char *) &key, data->cat_root,
918
1127
0, (char *) &fdrec.frec, sizeof (fdrec.frec)))
920
grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
1129
grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), origpath);
953
1162
int dir_hook (struct grub_hfs_record *rec)
955
char fname[32] = { 0 };
956
char *filetype = rec->data;
1164
struct grub_hfs_dirrec *drec = rec->data;
1165
struct grub_hfs_filerec *frec = rec->data;
957
1166
struct grub_hfs_catalog_key *ckey = rec->key;
1167
char fname[sizeof (ckey->str) * MAX_UTF8_PER_MAC_ROMAN + 1];
958
1168
struct grub_dirhook_info info;
1171
grub_memset (fname, 0, sizeof (fname));
959
1173
grub_memset (&info, 0, sizeof (info));
961
grub_strncpy (fname, (char *) (ckey->str), ckey->strlen);
963
if (*filetype == GRUB_HFS_FILETYPE_DIR
964
|| *filetype == GRUB_HFS_FILETYPE_FILE)
966
info.dir = (*filetype == GRUB_HFS_FILETYPE_DIR);
967
return hook (fname, &info);
1176
if (len > sizeof (ckey->str))
1177
len = sizeof (ckey->str);
1178
macroman_to_utf8 (fname, ckey->str, len, 1);
1180
info.case_insensitive = 1;
1182
if (drec->type == GRUB_HFS_FILETYPE_DIR)
1186
info.mtime = grub_be_to_cpu32 (drec->mtime) - 2082844800;
1187
return hook (fname, &info);
1189
if (frec->type == GRUB_HFS_FILETYPE_FILE)
1193
info.mtime = grub_be_to_cpu32 (frec->mtime) - 2082844800;
1194
return hook (fname, &info);
1065
1293
data = grub_hfs_mount (device->disk);
1068
*label = grub_strndup ((char *) (data->sblock.volname + 1),
1069
*data->sblock.volname);
1297
grub_size_t len = data->sblock.volname[0];
1298
if (len > sizeof (data->sblock.volname) - 1)
1299
len = sizeof (data->sblock.volname) - 1;
1300
*label = grub_malloc (len * MAX_UTF8_PER_MAC_ROMAN + 1);
1302
macroman_to_utf8 (*label, data->sblock.volname + 1,
1077
1312
static grub_err_t
1313
grub_hfs_mtime (grub_device_t device, grub_int32_t *tm)
1315
struct grub_hfs_data *data;
1317
data = grub_hfs_mount (device->disk);
1320
*tm = grub_be_to_cpu32 (data->sblock.mtime) - 2082844800;
1078
1329
grub_hfs_uuid (grub_device_t device, char **uuid)
1080
1331
struct grub_hfs_data *data;