diff --git a/ChangeLog b/ChangeLog index 7904263fa..9d430939e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2008-01-24 Bean + + * fs/ufs.c (GRUB_UFS_VOLNAME_LEN): New macro. + (grub_ufs_sblock): New member volume name. + (grub_ufs_find_file): Fix string copy bug. + (grub_ufs_label): Implement this function properly. + + * fs/hfs.c (grub_hfs_cnid_type): New enum. + (grub_hfs_iterate_records): Use the correct file number for extents + and catalog file. Fix problem in next index calculation. + (grub_hfs_find_node): Replace recursive function call with loop. + (grub_hfs_iterate_dir): Replace recursive function call with loop. + 2008-01-23 Robert Millan * include/grub/i386/ieee1275/loader.h: Include `', diff --git a/fs/hfs.c b/fs/hfs.c index e8e9c3e50..43f82eeeb 100644 --- a/fs/hfs.c +++ b/fs/hfs.c @@ -43,6 +43,16 @@ enum GRUB_HFS_FILETYPE_FILE = 2 }; +/* Catalog node ID (CNID). */ +enum grub_hfs_cnid_type + { + GRUB_HFS_CNID_ROOT_PARENT = 1, + GRUB_HFS_CNID_ROOT = 2, + GRUB_HFS_CNID_EXT = 3, + GRUB_HFS_CNID_CAT = 4, + GRUB_HFS_CNID_BAD = 5 + }; + /* A node descriptor. This is the header of every node. */ struct grub_hfs_node { @@ -447,7 +457,8 @@ grub_hfs_iterate_records (struct grub_hfs_data *data, int type, int idx, /* Read the node into memory. */ blk = grub_hfs_block (data, dat, - 0, idx / (data->blksz / nodesize), 0); + (type == 0) ? GRUB_HFS_CNID_CAT : GRUB_HFS_CNID_EXT, + idx / (data->blksz / nodesize), 0); blk += (idx % (data->blksz / nodesize)); if (grub_errno) return grub_errno; @@ -481,10 +492,7 @@ grub_hfs_iterate_records (struct grub_hfs_data *data, int type, int idx, return 0; } - if (idx % (data->blksz / nodesize) == 0) - idx = grub_be_to_cpu32 (node.node.next); - else - idx++; + idx = grub_be_to_cpu32 (node.node.next); } while (idx && this); return 0; @@ -501,6 +509,7 @@ grub_hfs_find_node (struct grub_hfs_data *data, char *key, { int found = -1; int isleaf = 0; + int done = 0; auto int node_found (struct grub_hfs_node *, struct grub_hfs_record *); @@ -532,6 +541,8 @@ grub_hfs_find_node (struct grub_hfs_data *data, char *key, /* Found it!!!! */ if (cmp == 0) { + done = 1; + grub_memcpy (datar, rec->data, rec->datalen < datalen ? rec->datalen : datalen); return 1; @@ -541,16 +552,20 @@ grub_hfs_find_node (struct grub_hfs_data *data, char *key, return 0; } - if (grub_hfs_iterate_records (data, type, idx, 0, node_found)) - return 0; - - if (found == -1) - return 0; + do + { + found = -1; - if (isleaf) - return 1; + if (grub_hfs_iterate_records (data, type, idx, 0, node_found)) + return 0; - return grub_hfs_find_node (data, key, found, type, datar, datalen); + if (found == -1) + return 0; + + idx = found; + } while (! isleaf); + + return done; } @@ -607,21 +622,23 @@ grub_hfs_iterate_dir (struct grub_hfs_data *data, grub_uint32_t root_idx, return hook (rec); } - if (grub_hfs_iterate_records (data, 0, root_idx, 0, node_found)) - return grub_errno; + do + { + found = -1; + + if (grub_hfs_iterate_records (data, 0, root_idx, 0, node_found)) + return grub_errno; - if (found == -1) - return 0; + if (found == -1) + return 0; + root_idx = found; + } while (! isleaf); + /* If there was a matching record in this leaf node, continue the iteration until the last record was found. */ - if (isleaf) - { - grub_hfs_iterate_records (data, 0, next, 1, it_dir); - return grub_errno; - } - - return grub_hfs_iterate_dir (data, found, dir, hook); + grub_hfs_iterate_records (data, 0, next, 1, it_dir); + return grub_errno; } diff --git a/fs/ufs.c b/fs/ufs.c index 917d9a295..25cd1fa34 100644 --- a/fs/ufs.c +++ b/fs/ufs.c @@ -38,6 +38,8 @@ #define GRUB_UFS_ATTR_DIR 040000 +#define GRUB_UFS_VOLNAME_LEN 32 + /* Calculate in which group the inode can be found. */ #define inode_group(inode,sblock) () @@ -86,7 +88,12 @@ struct grub_ufs_sblock /* The frags per cylinder group. */ grub_uint32_t frags_per_group; - grub_uint8_t unused7[1180]; + grub_uint8_t unused7[488]; + + /* Volume name for UFS2. */ + grub_uint8_t volume_name[GRUB_UFS_VOLNAME_LEN]; + + grub_uint8_t unused8[660]; /* Magic value to check if this is really a UFS filesystem. */ grub_uint32_t magic; @@ -393,13 +400,13 @@ grub_ufs_lookup_symlink (struct grub_ufs_data *data, int ino) static grub_err_t grub_ufs_find_file (struct grub_ufs_data *data, const char *path) { - char fpath[grub_strlen (path)]; + char fpath[grub_strlen (path) + 1]; char *name = fpath; char *next; unsigned int pos = 0; int dirino; - grub_strncpy (fpath, path, grub_strlen (path)); + grub_strcpy (fpath, path); /* Skip the first slash. */ if (name[0] == '/') @@ -649,10 +656,30 @@ grub_ufs_close (grub_file_t file) static grub_err_t -grub_ufs_label (grub_device_t device __attribute ((unused)), - char **label __attribute ((unused))) +grub_ufs_label (grub_device_t device, char **label) { - return GRUB_ERR_NONE; + struct grub_ufs_data *data = 0; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + *label = 0; + + data = grub_ufs_mount (device->disk); + if (data) + { + if (data->ufs_type == UFS2) + *label = grub_strdup ((char *) data->sblock.volume_name); + } + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + grub_free (data); + + return grub_errno; }