diff --git a/libr/fs/p/Makefile b/libr/fs/p/Makefile index aa9c6d1540..d98e96dbfa 100644 --- a/libr/fs/p/Makefile +++ b/libr/fs/p/Makefile @@ -6,8 +6,9 @@ LDFLAGS+=${LINK} foo: all -FILESYSTEMS= ext2.mk fat.mk hfs.mk hfsplus.mk iso9660.mk jfs.mk -FILESYSTEMS+= ntfs.mk reiserfs.mk tar.mk udf.mk ufs2.mk ufs.mk xfs.mk +FILESYSTEMS=hfs.mk hfsplus.mk iso9660.mk +FILESYSTEMS+= ext2.mk fat.mk jfs.mk +FILESYSTEMS+= ntfs.mk reiserfs.mk tar.mk udf.mk ufs2.mk ufs.mk xfs.mk include $(FILESYSTEMS) diff --git a/libr/fs/p/grub/Makefile b/libr/fs/p/grub/Makefile index e372544605..ffbed4adee 100644 --- a/libr/fs/p/grub/Makefile +++ b/libr/fs/p/grub/Makefile @@ -10,10 +10,11 @@ KERNFILES+=kern/list.c kern/partition.c KERNFILES+=fs/fshelp.c KERNFILES+=fs/reiserfs.c fs/ext2.c KERNFILES+=fs/fat.c fs/ntfs.c -KERNFILES+=fs/hfs.c fs/hfsplus.c -KERNFILES+=fs/udf.c fs/iso9660.c +#KERNFILES+=fs/hfs.c fs/hfsplus.c +#KERNFILES+=fs/udf.c fs/iso9660.c KERNFILES+=fs/cpio.c fs/tar.c -KERNFILES+=fs/xfs.c fs/jfs.c +KERNFILES+=fs/xfs.c +#fs/jfs.c #KERNFILES+=main.c KERNFILES+=grubfs.c @@ -22,6 +23,7 @@ KERNFILES+=partmap/msdos.c KERNOBJS=$(subst .c,.o,${KERNFILES}) CFLAGS=-Iinclude -g CFLAGS+=-I../../../include +#CFLAGS+=-fnested-functions BIN=test${EXT_EXE} all: ${KERNOBJS} main.o ${BIN} @@ -30,7 +32,6 @@ ${BIN}: ${CC} -o ${BIN} main.o ${CFLAGS} ${KERNOBJS} lib: all libgrubfs.a - libgrubfs.a: rm -f libgrubfs.a diff --git a/libr/fs/p/grub/fs/ext2.c b/libr/fs/p/grub/fs/ext2.c index 3d78633535..3b6d6d5e57 100644 --- a/libr/fs/p/grub/fs/ext2.c +++ b/libr/fs/p/grub/fs/ext2.c @@ -805,42 +805,22 @@ grub_ext2_open (struct grub_file *file, const char *name) return err; } -static grub_err_t -grub_ext2_close (grub_file_t file) -{ +static grub_err_t grub_ext2_close (grub_file_t file) { grub_free (file->data); - grub_dl_unref (my_mod); - return GRUB_ERR_NONE; } /* Read LEN bytes data from FILE into BUF. */ static grub_ssize_t -grub_ext2_read (grub_file_t file, char *buf, grub_size_t len) -{ +grub_ext2_read (grub_file_t file, char *buf, grub_size_t len) { struct grub_ext2_data *data = (struct grub_ext2_data *) file->data; - - return grub_ext2_read_file (&data->diropen, file->read_hook, - file->offset, len, buf); + return grub_ext2_read_file (&data->diropen, file->read_hook, file->offset, len, buf); } - -static grub_err_t -grub_ext2_dir (grub_device_t device, const char *path, - int (*hook) (const char *filename, - const struct grub_dirhook_info *info)) -{ - struct grub_ext2_data *data = 0; - struct grub_fshelp_node *fdiro = 0; - - auto int NESTED_FUNC_ATTR iterate (const char *filename, - enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node); - - int NESTED_FUNC_ATTR iterate (const char *filename, - enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node) +static struct grub_ext2_data *data = 0; +static int (*hook) (const char *filename, const struct grub_dirhook_info *info); +static int iterate (const char *filename, enum grub_fshelp_filetype filetype, grub_fshelp_node_t node) { struct grub_dirhook_info info; grub_memset (&info, 0, sizeof (info)); @@ -862,6 +842,16 @@ grub_ext2_dir (grub_device_t device, const char *path, return hook (filename, &info); } + +static grub_err_t +grub_ext2_dir (grub_device_t device, const char *path, + int (*_hook) (const char *filename, + const struct grub_dirhook_info *info)) +{ + data = 0; +hook = _hook; + struct grub_fshelp_node *fdiro = 0; + grub_dl_ref (my_mod); data = grub_ext2_mount (device->disk); diff --git a/libr/fs/p/grub/fs/fat.c b/libr/fs/p/grub/fs/fat.c index 2e7e87b498..3488895ee5 100644 --- a/libr/fs/p/grub/fs/fat.c +++ b/libr/fs/p/grub/fs/fat.c @@ -465,17 +465,18 @@ grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data, return ret; } +static int (*hook) (const char *filename, struct grub_fat_dir_entry *dir); static grub_err_t grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data, - int (*hook) (const char *filename, - struct grub_fat_dir_entry *dir)) + int (*_hook) (const char *filename, struct grub_fat_dir_entry *dir)) { struct grub_fat_dir_entry dir; char *filename, *filep = 0; grub_uint16_t *unibuf; int slot = -1, slots = -1; int checksum = -1; - grub_ssize_t offset = -sizeof(dir); + grub_ssize_t offset; +hook = _hook; if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY)) return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); @@ -483,19 +484,17 @@ grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data, /* Allocate space enough to hold a long name. */ filename = grub_malloc (0x40 * 13 * 4 + 1); unibuf = (grub_uint16_t *) grub_malloc (0x40 * 13 * 2); - if (! filename || ! unibuf) - { + if (! filename || ! unibuf) { grub_free (filename); grub_free (unibuf); return 0; } - while (1) - { - unsigned i; +for (offset = 0;;offset+= sizeof (dir)) { + unsigned int i; /* Adjust the offset. */ - offset += sizeof (dir); + //offset += sizeof (dir); /* Read a directory entry. */ if ((grub_fat_read_data (disk, data, 0, @@ -597,23 +596,12 @@ grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data, return grub_errno; } +static struct grub_fat_data *data; + static char *dirname, *dirp; + static int call_hook; + static int found = 0; -/* Find the underlying directory or file in PATH and return the - next path. If there is no next path or an error occurs, return NULL. - If HOOK is specified, call it with each file name. */ -static char * -grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data, - const char *path, - int (*hook) (const char *filename, - const struct grub_dirhook_info *info)) -{ - char *dirname, *dirp; - int call_hook; - int found = 0; - - auto int iter_hook (const char *filename, struct grub_fat_dir_entry *dir); - int iter_hook (const char *filename, struct grub_fat_dir_entry *dir) - { + static int iter_hook (const char *filename, struct grub_fat_dir_entry *dir) { struct grub_dirhook_info info; grub_memset (&info, 0, sizeof (info)); @@ -642,6 +630,18 @@ grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data, return 0; } +/* Find the underlying directory or file in PATH and return the + next path. If there is no next path or an error occurs, return NULL. + If HOOK is specified, call it with each file name. */ +static char * +grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *_data, + const char *path, + int (*hook) (const char *filename, + const struct grub_dirhook_info *info)) +{ + found = 0; +data = _data; + if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY)) { grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); @@ -781,14 +781,8 @@ grub_fat_close (grub_file_t file) return grub_errno; } -static grub_err_t -grub_fat_label (grub_device_t device, char **label) -{ - struct grub_fat_data *data; - grub_disk_t disk = device->disk; - - auto int iter_hook (const char *filename, struct grub_fat_dir_entry *dir); - int iter_hook (const char *filename, struct grub_fat_dir_entry *dir) +static char **label; + static int iter_hook2 (const char *filename, struct grub_fat_dir_entry *dir) { if (dir->attr == GRUB_FAT_ATTR_VOLUME_ID) { @@ -797,6 +791,12 @@ grub_fat_label (grub_device_t device, char **label) } return 0; } +static grub_err_t +grub_fat_label (grub_device_t device, char **_label) +{ + struct grub_fat_data *data; + grub_disk_t disk = device->disk; +label = _label; grub_dl_ref (my_mod); @@ -812,7 +812,7 @@ grub_fat_label (grub_device_t device, char **label) *label = 0; - grub_fat_iterate_dir (disk, data, iter_hook); + grub_fat_iterate_dir (disk, data, iter_hook2); fail: diff --git a/libr/fs/p/grub/fs/fshelp.c b/libr/fs/p/grub/fs/fshelp.c index d0b1e493e7..999fa51842 100644 --- a/libr/fs/p/grub/fs/fshelp.c +++ b/libr/fs/p/grub/fs/fshelp.c @@ -23,67 +23,20 @@ #include #include +#define free_node(x) {if (x!=rootnode && x!=currroot)grub_free(x);} -/* Lookup the node PATH. The node ROOTNODE describes the root of the - directory tree. The node found is returned in FOUNDNODE, which is - either a ROOTNODE or a new malloc'ed node. ITERATE_DIR is used to - iterate over all directory entries in the current node. - READ_SYMLINK is used to read the symlink if a node is a symlink. - EXPECTTYPE is the type node that is expected by the called, an - error is generated if the node is not of the expected type. Make - sure you use the NESTED_FUNC_ATTR macro for HOOK, this is required - because GCC has a nasty bug when using regparm=3. */ -grub_err_t -grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode, - grub_fshelp_node_t *foundnode, - int (*iterate_dir) (grub_fshelp_node_t dir, - int NESTED_FUNC_ATTR (*hook) - (const char *filename, - enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node)), - char *(*read_symlink) (grub_fshelp_node_t node), - enum grub_fshelp_filetype expecttype) -{ - grub_err_t err; - enum grub_fshelp_filetype foundtype = GRUB_FSHELP_DIR; - int symlinknest = 0; +static grub_fshelp_node_t currnode; +static grub_fshelp_node_t oldnode; +static enum grub_fshelp_filetype foundtype = GRUB_FSHELP_DIR; +static int symlinknest = 0; +static grub_fshelp_node_t rootnode; +static enum grub_fshelp_filetype type = GRUB_FSHELP_DIR; +static char fpath[4096]; //grub_strlen (currpath) + 1]; +static char *name; - auto grub_err_t NESTED_FUNC_ATTR find_file (const char *currpath, - grub_fshelp_node_t currroot, - grub_fshelp_node_t *currfound); - - grub_err_t NESTED_FUNC_ATTR find_file (const char *currpath, - grub_fshelp_node_t currroot, - grub_fshelp_node_t *currfound) - { - char fpath[grub_strlen (currpath) + 1]; - char *name = fpath; - char *next; - // unsigned int pos = 0; - enum grub_fshelp_filetype type = GRUB_FSHELP_DIR; - grub_fshelp_node_t currnode = currroot; - grub_fshelp_node_t oldnode = currroot; - - auto int NESTED_FUNC_ATTR iterate (const char *filename, - enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node); - - auto void free_node (grub_fshelp_node_t node); - - void free_node (grub_fshelp_node_t node) - { - if (node != rootnode && node != currroot) - grub_free (node); - } - - int NESTED_FUNC_ATTR iterate (const char *filename, - enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node) - { - if (filetype == GRUB_FSHELP_UNKNOWN || - (grub_strcmp (name, filename) && - (! (filetype & GRUB_FSHELP_CASE_INSENSITIVE) || - grub_strncasecmp (name, filename, GRUB_LONG_MAX)))) +static inline int iterate (const char *filename, enum grub_fshelp_filetype filetype, grub_fshelp_node_t node) { + if (filetype == GRUB_FSHELP_UNKNOWN || (grub_strcmp (name, filename) && + (! (filetype & GRUB_FSHELP_CASE_INSENSITIVE) || grub_strncasecmp (name, filename, GRUB_LONG_MAX)))) { grub_free (node); return 0; @@ -95,7 +48,19 @@ grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode, currnode = node; return 1; - } +} + +static char *(*read_symlink) (grub_fshelp_node_t node); +static int (*iterate_dir) (grub_fshelp_node_t dir, int NESTED_FUNC_ATTR (*hook) + (const char *filename, enum grub_fshelp_filetype filetype, grub_fshelp_node_t node)); + +static grub_err_t find_file (const char *currpath, grub_fshelp_node_t currroot, grub_fshelp_node_t *currfound) { + name = fpath; + char *next; + // unsigned int pos = 0; +type = GRUB_FSHELP_DIR; + currnode = currroot; + oldnode = currroot; grub_strncpy (fpath, currpath, grub_strlen (currpath) + 1); @@ -115,8 +80,7 @@ grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode, /* Extract the actual part from the pathname. */ next = grub_strchr (name, '/'); - if (next) - { + if (next) { /* Remove all leading slashes. */ while (*next == '/') *(next++) = '\0'; @@ -124,8 +88,7 @@ grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode, /* At this point it is expected that the current node is a directory, check if this is true. */ - if (type != GRUB_FSHELP_DIR) - { + if (type != GRUB_FSHELP_DIR) { free_node (currnode); return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); } @@ -198,6 +161,34 @@ grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode, return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); } +/* Lookup the node PATH. The node ROOTNODE describes the root of the + directory tree. The node found is returned in FOUNDNODE, which is + either a ROOTNODE or a new malloc'ed node. ITERATE_DIR is used to + iterate over all directory entries in the current node. + READ_SYMLINK is used to read the symlink if a node is a symlink. + EXPECTTYPE is the type node that is expected by the called, an + error is generated if the node is not of the expected type. Make + sure you use the NESTED_FUNC_ATTR macro for HOOK, this is required + because GCC has a nasty bug when using regparm=3. */ +grub_err_t +grub_fshelp_find_file (const char *path, grub_fshelp_node_t _rootnode, + grub_fshelp_node_t *foundnode, + int (*_iterate_dir) (grub_fshelp_node_t dir, + int NESTED_FUNC_ATTR (*hook) + (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node)), + char *(*_read_symlink) (grub_fshelp_node_t node), + enum grub_fshelp_filetype expecttype) +{ + grub_err_t err; + symlinknest = 0; +rootnode = _rootnode; +iterate_dir = _iterate_dir; + read_symlink = _read_symlink; + +foundtype = GRUB_FSHELP_DIR; + if (!path || path[0] != '/') { grub_error (GRUB_ERR_BAD_FILENAME, "bad filename"); @@ -293,23 +284,20 @@ grub_fshelp_read_file (grub_disk_t disk, grub_fshelp_node_t node, return len; } -unsigned int -grub_fshelp_log2blksize (unsigned int blksize, unsigned int *pow) -{ - int mod; +unsigned int grub_fshelp_log2blksize (unsigned int blksize, unsigned int *pow) { + int mod; - *pow = 0; - while (blksize > 1) - { - mod = blksize - ((blksize >> 1) << 1); - blksize >>= 1; + *pow = 0; + while (blksize > 1) { + mod = blksize - ((blksize >> 1) << 1); + blksize >>= 1; - /* Check if it really is a power of two. */ - if (mod) - return grub_error (GRUB_ERR_BAD_NUMBER, - "the blocksize is not a power of two"); - (*pow)++; - } + /* Check if it really is a power of two. */ + if (mod) + return grub_error (GRUB_ERR_BAD_NUMBER, + "the blocksize is not a power of two"); + (*pow)++; + } - return GRUB_ERR_NONE; + return GRUB_ERR_NONE; } diff --git a/libr/fs/p/grub/fs/hfs.c b/libr/fs/p/grub/fs/hfs.c index 91fc68ca81..919efb49d9 100644 --- a/libr/fs/p/grub/fs/hfs.c +++ b/libr/fs/p/grub/fs/hfs.c @@ -20,6 +20,7 @@ /* HFS is documented at http://developer.apple.com/documentation/mac/Files/Files-2.html */ +#include #include #include #include @@ -723,50 +724,37 @@ static int grub_hfs_find_node (struct grub_hfs_data *data, char *key, grub_uint32_t idx, int type, char *datar, int datalen) { - int found = -1; - int isleaf = 0; - int done = 0; +int found = -1; +int isleaf = 0; +int done = 0; - auto int node_found (struct grub_hfs_node *, struct grub_hfs_record *); +int node_found (struct grub_hfs_node *hnd, struct grub_hfs_record *rec) { + int cmp; + if (type == 0) + cmp = grub_hfs_cmp_catkeys (rec->key, (void *) key); + else cmp = grub_hfs_cmp_extkeys (rec->key, (void *) key); - int node_found (struct grub_hfs_node *hnd, struct grub_hfs_record *rec) - { - int cmp = 1; + /* If the key is smaller or equal to the current node, mark the + entry. In case of a non-leaf mode it will be used to lookup + the rest of the tree. */ + if (cmp <= 0) { + grub_uint32_t *node = (grub_uint32_t *) rec->data; + found = grub_be_to_cpu32 (*node); + } else return 1; /* The key can not be found in the tree. */ - if (type == 0) - cmp = grub_hfs_cmp_catkeys (rec->key, (void *) key); - else - cmp = grub_hfs_cmp_extkeys (rec->key, (void *) key); - - /* If the key is smaller or equal to the current node, mark the - entry. In case of a non-leaf mode it will be used to lookup - the rest of the tree. */ - if (cmp <= 0) - { - grub_uint32_t *node = (grub_uint32_t *) rec->data; - found = grub_be_to_cpu32 (*node); + /* Check if this node is a leaf node. */ + if (hnd->type == GRUB_HFS_NODE_LEAF) { + isleaf = 1; + /* Found it!!!! */ + if (cmp == 0) { + done = 1; + memmove (datar, rec->data, + rec->datalen < datalen ? rec->datalen : datalen); + return 1; + } } - else /* The key can not be found in the tree. */ - return 1; - - /* Check if this node is a leaf node. */ - if (hnd->type == GRUB_HFS_NODE_LEAF) - { - isleaf = 1; - - /* Found it!!!! */ - if (cmp == 0) - { - done = 1; - - grub_memcpy (datar, rec->data, - rec->datalen < datalen ? rec->datalen : datalen); - return 1; - } - } - return 0; - } +} do { diff --git a/libr/fs/p/grub/fs/ntfs.c b/libr/fs/p/grub/fs/ntfs.c index 972c0c3a65..2f2b3f3ee2 100644 --- a/libr/fs/p/grub/fs/ntfs.c +++ b/libr/fs/p/grub/fs/ntfs.c @@ -861,64 +861,47 @@ fail: return 0; } -static grub_err_t -grub_ntfs_dir (grub_device_t device, const char *path, - int (*hook) (const char *filename, - const struct grub_dirhook_info *info)) -{ - struct grub_ntfs_data *data = 0; - struct grub_fshelp_node *fdiro = 0; +static int (*hook) (const char *filename, const struct grub_dirhook_info *info); - auto int NESTED_FUNC_ATTR iterate (const char *filename, - enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node); - - int NESTED_FUNC_ATTR iterate (const char *filename, - enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node) - { - struct grub_dirhook_info info; - grub_memset (&info, 0, sizeof (info)); - info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); - grub_free (node); - return hook (filename, &info); - } - - grub_dl_ref (my_mod); - - data = grub_ntfs_mount (device->disk); - if (!data) - goto fail; - - grub_fshelp_find_file (path, &data->cmft, &fdiro, grub_ntfs_iterate_dir, - 0, GRUB_FSHELP_DIR); - - if (grub_errno) - goto fail; - - grub_ntfs_iterate_dir (fdiro, iterate); - -fail: - if ((fdiro) && (fdiro != &data->cmft)) - { - free_file (fdiro); - grub_free (fdiro); - } - if (data) - { - free_file (&data->mmft); - free_file (&data->cmft); - grub_free (data); - } - - grub_dl_unref (my_mod); - - return grub_errno; +static int iterate (const char *filename, enum grub_fshelp_filetype filetype, grub_fshelp_node_t node) { + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + grub_free (node); + return hook (filename, &info); } -static grub_err_t -grub_ntfs_open (grub_file_t file, const char *name) +static grub_err_t grub_ntfs_dir (grub_device_t device, const char *path, + int (*_hook) (const char *filename, const struct grub_dirhook_info *info)) { + struct grub_ntfs_data *data = 0; + struct grub_fshelp_node *fdiro = 0; + + hook = _hook; + grub_dl_ref (my_mod); + data = grub_ntfs_mount (device->disk); + if (!data) + goto fail; + grub_fshelp_find_file (path, &data->cmft, &fdiro, grub_ntfs_iterate_dir, + 0, GRUB_FSHELP_DIR); + if (grub_errno) + goto fail; + grub_ntfs_iterate_dir (fdiro, iterate); +fail: + if ((fdiro) && (fdiro != &data->cmft)) { + free_file (fdiro); + grub_free (fdiro); + } + if (data) { + free_file (&data->mmft); + free_file (&data->cmft); + grub_free (data); + } + grub_dl_unref (my_mod); + return grub_errno; +} + +static grub_err_t grub_ntfs_open (grub_file_t file, const char *name) { struct grub_ntfs_data *data = 0; struct grub_fshelp_node *mft = 0; diff --git a/libr/fs/p/grub/fs/reiserfs.c b/libr/fs/p/grub/fs/reiserfs.c index d395a1b36c..e8858f6e69 100644 --- a/libr/fs/p/grub/fs/reiserfs.c +++ b/libr/fs/p/grub/fs/reiserfs.c @@ -30,6 +30,7 @@ # define GRUB_HEXDUMP #endif +#include #include #include #include @@ -1255,30 +1256,27 @@ grub_reiserfs_close (grub_file_t file) return GRUB_ERR_NONE; } +static int (*hook) (const char *filename, const struct grub_dirhook_info *info); +static int iterate (const char *filename, + enum grub_fshelp_filetype filetype, grub_fshelp_node_t node) +{ + struct grub_dirhook_info info; + memset (&info, 0, sizeof (info)); + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + grub_free (node); + return hook (filename, &info); +} + /* Call HOOK with each file under DIR. */ static grub_err_t grub_reiserfs_dir (grub_device_t device, const char *path, - int (*hook) (const char *filename, - const struct grub_dirhook_info *info)) + int (*_hook) (const char *filename, const struct grub_dirhook_info *info)) { struct grub_reiserfs_data *data = 0; struct grub_fshelp_node root, *found; struct grub_reiserfs_key root_key; +hook = _hook; - auto int NESTED_FUNC_ATTR iterate (const char *filename, - enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node); - - int NESTED_FUNC_ATTR iterate (const char *filename, - enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node) - { - struct grub_dirhook_info info; - grub_memset (&info, 0, sizeof (info)); - info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); - grub_free (node); - return hook (filename, &info); - } grub_dl_ref (my_mod); data = grub_reiserfs_mount (device->disk); if (! data) diff --git a/libr/fs/p/grub/fs/udf.c b/libr/fs/p/grub/fs/udf.c index 4a7e2ea7cc..fc75b64952 100644 --- a/libr/fs/p/grub/fs/udf.c +++ b/libr/fs/p/grub/fs/udf.c @@ -910,29 +910,25 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir, return 0; } + + +static int (*hook) (const char *filename, const struct grub_dirhook_info *info); +static int iterate (const char *filename, enum grub_fshelp_filetype filetype, grub_fshelp_node_t node) { + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + grub_free (node); + return hook (filename, &info); +} + static grub_err_t grub_udf_dir (grub_device_t device, const char *path, - int (*hook) (const char *filename, - const struct grub_dirhook_info *info)) + int (*_hook) (const char *filename, const struct grub_dirhook_info *info)) { struct grub_udf_data *data = 0; struct grub_fshelp_node rootnode; struct grub_fshelp_node *foundnode; - - auto int NESTED_FUNC_ATTR iterate (const char *filename, - enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node); - - int NESTED_FUNC_ATTR iterate (const char *filename, - enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node) - { - struct grub_dirhook_info info; - grub_memset (&info, 0, sizeof (info)); - info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); - grub_free (node); - return hook (filename, &info); - } +hook = _hook; grub_dl_ref (my_mod); diff --git a/libr/fs/p/grub/fs/xfs.c b/libr/fs/p/grub/fs/xfs.c index d8d7381bf8..dc1e65d3b5 100644 --- a/libr/fs/p/grub/fs/xfs.c +++ b/libr/fs/p/grub/fs/xfs.c @@ -17,6 +17,7 @@ * along with GRUB. If not, see . */ +#include #include #include #include @@ -33,118 +34,105 @@ #define XFS_INODE_FORMAT_BTREE 3 -struct grub_xfs_sblock -{ - grub_uint8_t magic[4]; - grub_uint32_t bsize; - grub_uint8_t unused1[24]; - grub_uint16_t uuid[8]; - grub_uint8_t unused2[8]; - grub_uint64_t rootino; - grub_uint8_t unused3[20]; - grub_uint32_t agsize; - grub_uint8_t unused4[20]; - grub_uint8_t label[12]; - grub_uint8_t log2_bsize; - grub_uint8_t log2_sect; - grub_uint8_t log2_inode; - grub_uint8_t log2_inop; - grub_uint8_t log2_agblk; - grub_uint8_t unused6[67]; - grub_uint8_t log2_dirblk; +struct grub_xfs_sblock { + grub_uint8_t magic[4]; + grub_uint32_t bsize; + grub_uint8_t unused1[24]; + grub_uint16_t uuid[8]; + grub_uint8_t unused2[8]; + grub_uint64_t rootino; + grub_uint8_t unused3[20]; + grub_uint32_t agsize; + grub_uint8_t unused4[20]; + grub_uint8_t label[12]; + grub_uint8_t log2_bsize; + grub_uint8_t log2_sect; + grub_uint8_t log2_inode; + grub_uint8_t log2_inop; + grub_uint8_t log2_agblk; + grub_uint8_t unused6[67]; + grub_uint8_t log2_dirblk; } __attribute__ ((packed)); -struct grub_xfs_dir_header -{ - grub_uint8_t count; - grub_uint8_t smallino; - union - { - grub_uint32_t i4; - grub_uint64_t i8; - } parent __attribute__ ((packed)); +struct grub_xfs_dir_header { + grub_uint8_t count; + grub_uint8_t smallino; + union { + grub_uint32_t i4; + grub_uint64_t i8; + } parent __attribute__ ((packed)); } __attribute__ ((packed)); -struct grub_xfs_dir_entry -{ - grub_uint8_t len; - grub_uint16_t offset; - char name[1]; - /* Inode number follows, 32 bits. */ +struct grub_xfs_dir_entry { + grub_uint8_t len; + grub_uint16_t offset; + char name[1]; + /* Inode number follows, 32 bits. */ } __attribute__ ((packed)); -struct grub_xfs_dir2_entry -{ - grub_uint64_t inode; - grub_uint8_t len; +struct grub_xfs_dir2_entry { + grub_uint64_t inode; + grub_uint8_t len; } __attribute__ ((packed)); typedef grub_uint32_t grub_xfs_extent[4]; -struct grub_xfs_btree_node -{ - grub_uint8_t magic[4]; - grub_uint16_t level; - grub_uint16_t numrecs; - grub_uint64_t left; - grub_uint64_t right; - grub_uint64_t keys[1]; +struct grub_xfs_btree_node { + grub_uint8_t magic[4]; + grub_uint16_t level; + grub_uint16_t numrecs; + grub_uint64_t left; + grub_uint64_t right; + grub_uint64_t keys[1]; } __attribute__ ((packed)); -struct grub_xfs_btree_root -{ - grub_uint16_t level; - grub_uint16_t numrecs; - grub_uint64_t keys[1]; +struct grub_xfs_btree_root { + grub_uint16_t level; + grub_uint16_t numrecs; + grub_uint64_t keys[1]; } __attribute__ ((packed)); -struct grub_xfs_inode -{ - grub_uint8_t magic[2]; - grub_uint16_t mode; - grub_uint8_t version; - grub_uint8_t format; - grub_uint8_t unused2[50]; - grub_uint64_t size; - grub_uint64_t nblocks; - grub_uint32_t extsize; - grub_uint32_t nextents; - grub_uint8_t unused3[20]; - union - { - char raw[156]; - struct dir - { - struct grub_xfs_dir_header dirhead; - struct grub_xfs_dir_entry direntry[1]; - } dir; - grub_xfs_extent extents[XFS_INODE_EXTENTS]; - struct grub_xfs_btree_root btree; - } data __attribute__ ((packed)); +struct grub_xfs_inode { + grub_uint8_t magic[2]; + grub_uint16_t mode; + grub_uint8_t version; + grub_uint8_t format; + grub_uint8_t unused2[50]; + grub_uint64_t size; + grub_uint64_t nblocks; + grub_uint32_t extsize; + grub_uint32_t nextents; + grub_uint8_t unused3[20]; + union { + char raw[156]; + struct dir { + struct grub_xfs_dir_header dirhead; + struct grub_xfs_dir_entry direntry[1]; + } dir; + grub_xfs_extent extents[XFS_INODE_EXTENTS]; + struct grub_xfs_btree_root btree; + } data __attribute__ ((packed)); } __attribute__ ((packed)); -struct grub_xfs_dirblock_tail -{ - grub_uint32_t leaf_count; - grub_uint32_t leaf_stale; +struct grub_xfs_dirblock_tail { + grub_uint32_t leaf_count; + grub_uint32_t leaf_stale; } __attribute__ ((packed)); -struct grub_fshelp_node -{ - struct grub_xfs_data *data; - grub_uint64_t ino; - int inode_read; - struct grub_xfs_inode inode; +struct grub_fshelp_node { + struct grub_xfs_data *data; + grub_uint64_t ino; + int inode_read; + struct grub_xfs_inode inode; }; -struct grub_xfs_data -{ - struct grub_xfs_sblock sblock; - grub_disk_t disk; - int pos; - int bsize; - int agsize; - struct grub_fshelp_node diropen; +struct grub_xfs_data { + struct grub_xfs_sblock sblock; + grub_disk_t disk; + int pos; + int bsize; + int agsize; + struct grub_fshelp_node diropen; }; static grub_dl_t my_mod; @@ -185,631 +173,491 @@ static grub_dl_t my_mod; #define GRUB_XFS_NEXT_DIRENT(pos,len) \ (pos) + GRUB_XFS_ROUND_TO_DIRENT (8 + 1 + len + 2) -static inline grub_uint64_t -grub_xfs_inode_block (struct grub_xfs_data *data, - grub_uint64_t ino) -{ - long long int inoinag = GRUB_XFS_INO_INOINAG (data, ino); - long long ag = GRUB_XFS_INO_AG (data, ino); - long long block; - block = (inoinag >> data->sblock.log2_inop) + ag * data->agsize; - block <<= (data->sblock.log2_bsize - GRUB_DISK_SECTOR_BITS); - return block; +static inline grub_uint64_t grub_xfs_inode_block (struct grub_xfs_data *data, grub_uint64_t ino) { + long long int inoinag = GRUB_XFS_INO_INOINAG (data, ino); + long long ag = GRUB_XFS_INO_AG (data, ino); + long long block; + + block = (inoinag >> data->sblock.log2_inop) + ag * data->agsize; + block <<= (data->sblock.log2_bsize - GRUB_DISK_SECTOR_BITS); + return block; } - -static inline int -grub_xfs_inode_offset (struct grub_xfs_data *data, - grub_uint64_t ino) -{ - int inoag = GRUB_XFS_INO_INOINAG (data, ino); - return ((inoag & ((1 << data->sblock.log2_inop) - 1)) << - data->sblock.log2_inode); +static inline int grub_xfs_inode_offset (struct grub_xfs_data *data, grub_uint64_t ino) { + int inoag = GRUB_XFS_INO_INOINAG (data, ino); + return ((inoag & ((1 << data->sblock.log2_inop) - 1)) << + data->sblock.log2_inode); } +static grub_err_t grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino, struct grub_xfs_inode *inode) { + grub_uint64_t block = grub_xfs_inode_block (data, ino); + int offset = grub_xfs_inode_offset (data, ino); -static grub_err_t -grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino, - struct grub_xfs_inode *inode) -{ - grub_uint64_t block = grub_xfs_inode_block (data, ino); - int offset = grub_xfs_inode_offset (data, ino); + /* Read the inode. */ + if (grub_disk_read (data->disk, block, offset, + 1 << data->sblock.log2_inode, inode)) + return grub_errno; - /* Read the inode. */ - if (grub_disk_read (data->disk, block, offset, - 1 << data->sblock.log2_inode, inode)) - return grub_errno; + if (grub_strncmp ((char *) inode->magic, "IN", 2)) + return grub_error (GRUB_ERR_BAD_FS, "not a correct XFS inode"); - if (grub_strncmp ((char *) inode->magic, "IN", 2)) - return grub_error (GRUB_ERR_BAD_FS, "not a correct XFS inode"); - - return 0; + return 0; } +static grub_disk_addr_t grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) { + struct grub_xfs_btree_node *leaf = 0; + int ex, nrec; + grub_xfs_extent *exts; + grub_uint64_t ret = 0; -static grub_disk_addr_t -grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) -{ - struct grub_xfs_btree_node *leaf = 0; - int ex, nrec; - grub_xfs_extent *exts; - grub_uint64_t ret = 0; + if (node->inode.format == XFS_INODE_FORMAT_BTREE) { + grub_uint64_t *keys; - if (node->inode.format == XFS_INODE_FORMAT_BTREE) - { - grub_uint64_t *keys; + leaf = grub_malloc (node->data->sblock.bsize); + if (leaf == 0) + return 0; - leaf = grub_malloc (node->data->sblock.bsize); - if (leaf == 0) - return 0; + nrec = grub_be_to_cpu16 (node->inode.data.btree.numrecs); + keys = &node->inode.data.btree.keys[0]; + do { + int i; - nrec = grub_be_to_cpu16 (node->inode.data.btree.numrecs); - keys = &node->inode.data.btree.keys[0]; - do - { - int i; + for (i = 0; i < nrec; i++) + if (fileblock < grub_be_to_cpu64 (keys[i])) + break; + /* Sparse block. */ + if (i == 0) { + grub_free (leaf); + return 0; + } + if (grub_disk_read (node->data->disk, grub_be_to_cpu64 (keys[i - 1 + nrec]) + << (node->data->sblock.log2_bsize - GRUB_DISK_SECTOR_BITS), + 0, node->data->sblock.bsize, leaf)) + return 0; - for (i = 0; i < nrec; i++) - { - if (fileblock < grub_be_to_cpu64 (keys[i])) - break; - } + if (grub_strncmp ((char *) leaf->magic, "BMAP", 4)) { + grub_free (leaf); + grub_error (GRUB_ERR_BAD_FS, "not a correct XFS BMAP node"); + return 0; + } - /* Sparse block. */ - if (i == 0) - { - grub_free (leaf); - return 0; - } + nrec = grub_be_to_cpu16 (leaf->numrecs); + keys = &leaf->keys[0]; + } while (leaf->level); + exts = (grub_xfs_extent *) keys; + } else if (node->inode.format == XFS_INODE_FORMAT_EXT) { + nrec = grub_be_to_cpu32 (node->inode.nextents); + exts = &node->inode.data.extents[0]; + } else { + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "XFS does not support inode format %d yet", + node->inode.format); + return 0; + } - if (grub_disk_read (node->data->disk, - grub_be_to_cpu64 (keys[i - 1 + nrec]) - << (node->data->sblock.log2_bsize - - GRUB_DISK_SECTOR_BITS), - 0, node->data->sblock.bsize, leaf)) - return 0; + /* Iterate over each extent to figure out which extent has + the block we are looking for. */ + for (ex = 0; ex < nrec; ex++) { + grub_uint64_t start = GRUB_XFS_EXTENT_BLOCK (exts, ex); + grub_uint64_t offset = GRUB_XFS_EXTENT_OFFSET (exts, ex); + grub_uint64_t size = GRUB_XFS_EXTENT_SIZE (exts, ex); - if (grub_strncmp ((char *) leaf->magic, "BMAP", 4)) - { - grub_free (leaf); - grub_error (GRUB_ERR_BAD_FS, "not a correct XFS BMAP node"); - return 0; - } + /* Sparse block. */ + if (fileblock < offset) + break; + if (fileblock < offset + size) { + ret = (fileblock - offset + start); + break; + } + } - nrec = grub_be_to_cpu16 (leaf->numrecs); - keys = &leaf->keys[0]; - } while (leaf->level); - exts = (grub_xfs_extent *) keys; - } - else if (node->inode.format == XFS_INODE_FORMAT_EXT) - { - nrec = grub_be_to_cpu32 (node->inode.nextents); - exts = &node->inode.data.extents[0]; - } - else - { - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "XFS does not support inode format %d yet", - node->inode.format); - return 0; - } + if (leaf) + grub_free (leaf); - /* Iterate over each extent to figure out which extent has - the block we are looking for. */ - for (ex = 0; ex < nrec; ex++) - { - grub_uint64_t start = GRUB_XFS_EXTENT_BLOCK (exts, ex); - grub_uint64_t offset = GRUB_XFS_EXTENT_OFFSET (exts, ex); - grub_uint64_t size = GRUB_XFS_EXTENT_SIZE (exts, ex); - - /* Sparse block. */ - if (fileblock < offset) - break; - else if (fileblock < offset + size) - { - ret = (fileblock - offset + start); - break; - } - } - - if (leaf) - grub_free (leaf); - - return GRUB_XFS_FSB_TO_BLOCK(node->data, ret); + return GRUB_XFS_FSB_TO_BLOCK(node->data, ret); } - /* Read LEN bytes from the file described by DATA starting with byte POS. Return the amount of read bytes in READ. */ -static grub_ssize_t -grub_xfs_read_file (grub_fshelp_node_t node, - void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, - unsigned offset, unsigned length), - int pos, grub_size_t len, char *buf) -{ - return grub_fshelp_read_file (node->data->disk, node, read_hook, - pos, len, buf, grub_xfs_read_block, - grub_be_to_cpu64 (node->inode.size), - node->data->sblock.log2_bsize - - GRUB_DISK_SECTOR_BITS); +static grub_ssize_t grub_xfs_read_file (grub_fshelp_node_t node, + void (*read_hook) (grub_disk_addr_t sector, unsigned offset, unsigned length), + int pos, grub_size_t len, char *buf) { + return grub_fshelp_read_file (node->data->disk, node, read_hook, + pos, len, buf, grub_xfs_read_block, grub_be_to_cpu64 (node->inode.size), + node->data->sblock.log2_bsize - GRUB_DISK_SECTOR_BITS); } - -static char * -grub_xfs_read_symlink (grub_fshelp_node_t node) -{ - int size = grub_be_to_cpu64 (node->inode.size); - - switch (node->inode.format) - { - case XFS_INODE_FORMAT_INO: - return grub_strndup (node->inode.data.raw, size); - - case XFS_INODE_FORMAT_EXT: - { +static char * grub_xfs_read_symlink (grub_fshelp_node_t node) { + int size = grub_be_to_cpu64 (node->inode.size); char *symlink; grub_ssize_t numread; - symlink = grub_malloc (size + 1); - if (!symlink) - return 0; + switch (node->inode.format) { + case XFS_INODE_FORMAT_INO: + return grub_strndup (node->inode.data.raw, size); + case XFS_INODE_FORMAT_EXT: + symlink = grub_malloc (size + 1); + if (!symlink) + return 0; - numread = grub_xfs_read_file (node, 0, 0, size, symlink); - if (numread != size) - { - grub_free (symlink); - return 0; - } - symlink[size] = '\0'; - return symlink; - } - } - - return 0; + numread = grub_xfs_read_file (node, 0, 0, size, symlink); + if (numread != size) { + grub_free (symlink); + return 0; + } + symlink[size] = '\0'; + return symlink; + } + return 0; } - static enum grub_fshelp_filetype -grub_xfs_mode_to_filetype (grub_uint16_t mode) -{ - if ((grub_be_to_cpu16 (mode) - & FILETYPE_INO_MASK) == FILETYPE_INO_DIRECTORY) - return GRUB_FSHELP_DIR; - else if ((grub_be_to_cpu16 (mode) - & FILETYPE_INO_MASK) == FILETYPE_INO_SYMLINK) - return GRUB_FSHELP_SYMLINK; - else if ((grub_be_to_cpu16 (mode) - & FILETYPE_INO_MASK) == FILETYPE_INO_REG) - return GRUB_FSHELP_REG; - return GRUB_FSHELP_UNKNOWN; +grub_xfs_mode_to_filetype (grub_uint16_t mode) { + grub_uint16_t p = grub_be_to_cpu16 (mode); + if ((p & FILETYPE_INO_MASK) == FILETYPE_INO_DIRECTORY) + return GRUB_FSHELP_DIR; + if ((p & FILETYPE_INO_MASK) == FILETYPE_INO_SYMLINK) + return GRUB_FSHELP_SYMLINK; + if ((p & FILETYPE_INO_MASK) == FILETYPE_INO_REG) + return GRUB_FSHELP_REG; + return GRUB_FSHELP_UNKNOWN; } +static int call_hook (grub_fshelp_node_t diro, grub_uint64_t ino, char *filename, + int (*hook) (const char *filename, enum grub_fshelp_filetype filetype, grub_fshelp_node_t node) +) { + struct grub_fshelp_node *fdiro; -static int -grub_xfs_iterate_dir (grub_fshelp_node_t dir, - int NESTED_FUNC_ATTR - (*hook) (const char *filename, - enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node)) + fdiro = grub_malloc (sizeof (struct grub_fshelp_node) + - sizeof (struct grub_xfs_inode) + (1 << diro->data->sblock.log2_inode)); + if (!fdiro) + return 0; + + /* The inode should be read, otherwise the filetype can + not be determined. */ + fdiro->ino = ino; + fdiro->inode_read = 1; + fdiro->data = diro->data; + grub_xfs_read_inode (diro->data, ino, &fdiro->inode); + + return hook (filename, grub_xfs_mode_to_filetype (fdiro->inode.mode), fdiro); +} + +static int grub_xfs_iterate_dir (grub_fshelp_node_t dir, + int (*hook) (const char *filename, enum grub_fshelp_filetype filetype, grub_fshelp_node_t node)) { - struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir; - auto int NESTED_FUNC_ATTR call_hook (grub_uint64_t ino, char *filename); + struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir; - int NESTED_FUNC_ATTR call_hook (grub_uint64_t ino, char *filename) - { - struct grub_fshelp_node *fdiro; + switch (diro->inode.format) { + case XFS_INODE_FORMAT_INO: + { + struct grub_xfs_dir_entry *de = &diro->inode.data.dir.direntry[0]; + int i, smallino = !diro->inode.data.dir.dirhead.smallino; + grub_uint64_t parent; - fdiro = grub_malloc (sizeof (struct grub_fshelp_node) - - sizeof (struct grub_xfs_inode) - + (1 << diro->data->sblock.log2_inode)); - if (!fdiro) + /* If small inode numbers are used to pack the direntry, the + parent inode number is small too. */ + if (smallino) { + parent = grub_be_to_cpu32 (diro->inode.data.dir.dirhead.parent.i4); + parent = grub_cpu_to_be64 (parent); + /* The header is a bit smaller than usual. */ + de = (struct grub_xfs_dir_entry *) ((char *) de - 4); + } else parent = diro->inode.data.dir.dirhead.parent.i8; + + /* Synthesize the direntries for `.' and `..'. */ + if (call_hook (diro, diro->ino, ".", hook)) + return 1; + + if (call_hook (diro, parent, "..", hook)) + return 1; + + for (i = 0; i < diro->inode.data.dir.dirhead.count; i++) { + grub_uint64_t ino; + void *inopos = (((char *) de) + + sizeof (struct grub_xfs_dir_entry) + + de->len - 1); + char name[de->len + 1]; + + if (smallino) + { + ino = grub_be_to_cpu32 (*(grub_uint32_t *) inopos); + ino = grub_cpu_to_be64 (ino); + } + else + ino = *(grub_uint64_t *) inopos; + + grub_memcpy (name, de->name, de->len); + name[de->len] = '\0'; + if (call_hook (diro, ino, name, hook)) + return 1; + de = ((struct grub_xfs_dir_entry *) (((char *) de)+ sizeof (struct grub_xfs_dir_entry) + de->len + + ((smallino ? sizeof (grub_uint32_t) : sizeof (grub_uint64_t))) - 1)); + } + } + break; + case XFS_INODE_FORMAT_BTREE: + case XFS_INODE_FORMAT_EXT: + { + grub_ssize_t numread; + char *dirblock; + grub_uint64_t blk; + int dirblk_size, dirblk_log2; + + dirblk_log2 = (dir->data->sblock.log2_bsize + + dir->data->sblock.log2_dirblk); + dirblk_size = 1 << dirblk_log2; + + dirblock = grub_malloc (dirblk_size); + if (! dirblock) + return 0; + + /* Iterate over every block the directory has. */ + for (blk = 0; + blk < (grub_be_to_cpu64 (dir->inode.size) + >> dirblk_log2); + blk++) + { + /* The header is skipped, the first direntry is stored + from byte 16. */ + int pos = 16; + int entries; + int tail_start = (dirblk_size + - sizeof (struct grub_xfs_dirblock_tail)); + + struct grub_xfs_dirblock_tail *tail; + tail = (struct grub_xfs_dirblock_tail *) &dirblock[tail_start]; + + numread = grub_xfs_read_file (dir, 0, + blk << dirblk_log2, + dirblk_size, dirblock); + if (numread != dirblk_size) + return 0; + + entries = (grub_be_to_cpu32 (tail->leaf_count) + - grub_be_to_cpu32 (tail->leaf_stale)); + + /* Iterate over all entries within this block. */ + while (pos < (dirblk_size - (int) sizeof (struct grub_xfs_dir2_entry))) { + struct grub_xfs_dir2_entry *direntry; + grub_uint16_t *freetag; + char *filename; + + direntry = (struct grub_xfs_dir2_entry *) &dirblock[pos]; + freetag = (grub_uint16_t *) direntry; + + if (*freetag == 0XFFFF) { + grub_uint16_t *skip = (grub_uint16_t *) (freetag + 1); + /* This entry is not used, go to the next one. */ + pos += grub_be_to_cpu16 (*skip); + continue; + } + + filename = &dirblock[pos + sizeof (*direntry)]; + /* The byte after the filename is for the tag, which + is not used by GRUB. So it can be overwritten. */ + filename[direntry->len] = '\0'; + + if (call_hook (diro, direntry->inode, filename, hook)) { + grub_free (dirblock); + return 1; + } + + /* Check if last direntry in this block is + reached. */ + entries--; + if (!entries) + break; + + /* Select the next directory entry. */ + pos = GRUB_XFS_NEXT_DIRENT (pos, direntry->len); + pos = GRUB_XFS_ROUND_TO_DIRENT (pos); + } + } + grub_free (dirblock); + break; + } + default: + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "XFS does not support inode format %d yet", diro->inode.format); + } return 0; - - /* The inode should be read, otherwise the filetype can - not be determined. */ - fdiro->ino = ino; - fdiro->inode_read = 1; - fdiro->data = diro->data; - grub_xfs_read_inode (diro->data, ino, &fdiro->inode); - - return hook (filename, - grub_xfs_mode_to_filetype (fdiro->inode.mode), - fdiro); - } - - switch (diro->inode.format) - { - case XFS_INODE_FORMAT_INO: - { - struct grub_xfs_dir_entry *de = &diro->inode.data.dir.direntry[0]; - int smallino = !diro->inode.data.dir.dirhead.smallino; - int i; - grub_uint64_t parent; - - /* If small inode numbers are used to pack the direntry, the - parent inode number is small too. */ - if (smallino) - { - parent = grub_be_to_cpu32 (diro->inode.data.dir.dirhead.parent.i4); - parent = grub_cpu_to_be64 (parent); - /* The header is a bit smaller than usual. */ - de = (struct grub_xfs_dir_entry *) ((char *) de - 4); - } - else - { - parent = diro->inode.data.dir.dirhead.parent.i8; - } - - /* Synthesize the direntries for `.' and `..'. */ - if (call_hook (diro->ino, ".")) - return 1; - - if (call_hook (parent, "..")) - return 1; - - for (i = 0; i < diro->inode.data.dir.dirhead.count; i++) - { - grub_uint64_t ino; - void *inopos = (((char *) de) - + sizeof (struct grub_xfs_dir_entry) - + de->len - 1); - char name[de->len + 1]; - - if (smallino) - { - ino = grub_be_to_cpu32 (*(grub_uint32_t *) inopos); - ino = grub_cpu_to_be64 (ino); - } - else - ino = *(grub_uint64_t *) inopos; - - grub_memcpy (name, de->name, de->len); - name[de->len] = '\0'; - if (call_hook (ino, name)) - return 1; - - de = ((struct grub_xfs_dir_entry *) - (((char *) de)+ sizeof (struct grub_xfs_dir_entry) + de->len - + ((smallino ? sizeof (grub_uint32_t) - : sizeof (grub_uint64_t))) - 1)); - } - break; - } - - case XFS_INODE_FORMAT_BTREE: - case XFS_INODE_FORMAT_EXT: - { - grub_ssize_t numread; - char *dirblock; - grub_uint64_t blk; - int dirblk_size, dirblk_log2; - - dirblk_log2 = (dir->data->sblock.log2_bsize - + dir->data->sblock.log2_dirblk); - dirblk_size = 1 << dirblk_log2; - - dirblock = grub_malloc (dirblk_size); - if (! dirblock) - return 0; - - /* Iterate over every block the directory has. */ - for (blk = 0; - blk < (grub_be_to_cpu64 (dir->inode.size) - >> dirblk_log2); - blk++) - { - /* The header is skipped, the first direntry is stored - from byte 16. */ - int pos = 16; - int entries; - int tail_start = (dirblk_size - - sizeof (struct grub_xfs_dirblock_tail)); - - struct grub_xfs_dirblock_tail *tail; - tail = (struct grub_xfs_dirblock_tail *) &dirblock[tail_start]; - - numread = grub_xfs_read_file (dir, 0, - blk << dirblk_log2, - dirblk_size, dirblock); - if (numread != dirblk_size) - return 0; - - entries = (grub_be_to_cpu32 (tail->leaf_count) - - grub_be_to_cpu32 (tail->leaf_stale)); - - /* Iterate over all entries within this block. */ - while (pos < (dirblk_size - - (int) sizeof (struct grub_xfs_dir2_entry))) - { - struct grub_xfs_dir2_entry *direntry; - grub_uint16_t *freetag; - char *filename; - - direntry = (struct grub_xfs_dir2_entry *) &dirblock[pos]; - freetag = (grub_uint16_t *) direntry; - - if (*freetag == 0XFFFF) - { - grub_uint16_t *skip = (grub_uint16_t *) (freetag + 1); - - /* This entry is not used, go to the next one. */ - pos += grub_be_to_cpu16 (*skip); - - continue; - } - - filename = &dirblock[pos + sizeof (*direntry)]; - /* The byte after the filename is for the tag, which - is not used by GRUB. So it can be overwritten. */ - filename[direntry->len] = '\0'; - - if (call_hook (direntry->inode, filename)) - { - grub_free (dirblock); - return 1; - } - - /* Check if last direntry in this block is - reached. */ - entries--; - if (!entries) - break; - - /* Select the next directory entry. */ - pos = GRUB_XFS_NEXT_DIRENT (pos, direntry->len); - pos = GRUB_XFS_ROUND_TO_DIRENT (pos); - } - } - grub_free (dirblock); - break; - } - - default: - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "XFS does not support inode format %d yet", - diro->inode.format); - } - return 0; } +static struct grub_xfs_data * grub_xfs_mount (grub_disk_t disk) { + struct grub_xfs_data *data = 0; -static struct grub_xfs_data * -grub_xfs_mount (grub_disk_t disk) + data = grub_zalloc (sizeof (struct grub_xfs_data)); + if (!data) + return 0; + + /* Read the superblock. */ + if (grub_disk_read (disk, 0, 0, sizeof (struct grub_xfs_sblock), &data->sblock)) + goto fail; + + if (grub_strncmp ((char *) (data->sblock.magic), "XFSB", 4)) { + grub_error (GRUB_ERR_BAD_FS, "not a XFS filesystem"); + goto fail; + } + + data = grub_realloc (data, sizeof (struct grub_xfs_data) + - sizeof (struct grub_xfs_inode) + (1 << data->sblock.log2_inode)); + + if (! data) + goto fail; + + data->diropen.data = data; + data->diropen.ino = data->sblock.rootino; + data->diropen.inode_read = 1; + data->bsize = grub_be_to_cpu32 (data->sblock.bsize); + data->agsize = grub_be_to_cpu32 (data->sblock.agsize); + + data->disk = disk; + data->pos = 0; + + grub_xfs_read_inode (data, data->diropen.ino, &data->diropen.inode); + + return data; +fail: + + if (grub_errno == GRUB_ERR_OUT_OF_RANGE) + grub_error (GRUB_ERR_BAD_FS, "not an XFS filesystem"); + + grub_free (data); + + return 0; +} + +static int (*hook) (const char *filename, const struct grub_dirhook_info *info); +static int iterate (const char *filename, enum grub_fshelp_filetype filetype, grub_fshelp_node_t node) { + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + grub_free (node); + return hook (filename, &info); +} + +static grub_err_t grub_xfs_dir (grub_device_t device, const char *path, + int (*_hook) (const char *filename, const struct grub_dirhook_info *info)) { - struct grub_xfs_data *data = 0; + struct grub_xfs_data *data = 0; + struct grub_fshelp_node *fdiro = 0; + hook = _hook; - data = grub_zalloc (sizeof (struct grub_xfs_data)); - if (!data) - return 0; + grub_dl_ref (my_mod); - /* Read the superblock. */ - if (grub_disk_read (disk, 0, 0, - sizeof (struct grub_xfs_sblock), &data->sblock)) - goto fail; + data = grub_xfs_mount (device->disk); + if (!data) + goto mount_fail; - if (grub_strncmp ((char *) (data->sblock.magic), "XFSB", 4)) - { - grub_error (GRUB_ERR_BAD_FS, "not a XFS filesystem"); - goto fail; - } + grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_xfs_iterate_dir, + grub_xfs_read_symlink, GRUB_FSHELP_DIR); + if (grub_errno) + goto fail; - data = grub_realloc (data, - sizeof (struct grub_xfs_data) - - sizeof (struct grub_xfs_inode) - + (1 << data->sblock.log2_inode)); + grub_xfs_iterate_dir (fdiro, iterate); - if (! data) - goto fail; +fail: + if (fdiro != &data->diropen) + grub_free (fdiro); + grub_free (data); - data->diropen.data = data; - data->diropen.ino = data->sblock.rootino; - data->diropen.inode_read = 1; - data->bsize = grub_be_to_cpu32 (data->sblock.bsize); - data->agsize = grub_be_to_cpu32 (data->sblock.agsize); +mount_fail: - data->disk = disk; - data->pos = 0; + grub_dl_unref (my_mod); - grub_xfs_read_inode (data, data->diropen.ino, &data->diropen.inode); - - return data; - fail: - - if (grub_errno == GRUB_ERR_OUT_OF_RANGE) - grub_error (GRUB_ERR_BAD_FS, "not an XFS filesystem"); - - grub_free (data); - - return 0; + return grub_errno; } - -static grub_err_t -grub_xfs_dir (grub_device_t device, const char *path, - int (*hook) (const char *filename, - const struct grub_dirhook_info *info)) -{ - struct grub_xfs_data *data = 0; - struct grub_fshelp_node *fdiro = 0; - - auto int NESTED_FUNC_ATTR iterate (const char *filename, - enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node); - - int NESTED_FUNC_ATTR iterate (const char *filename, - enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node) - { - struct grub_dirhook_info info; - grub_memset (&info, 0, sizeof (info)); - info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); - grub_free (node); - return hook (filename, &info); - } - - grub_dl_ref (my_mod); - - data = grub_xfs_mount (device->disk); - if (!data) - goto mount_fail; - - grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_xfs_iterate_dir, - grub_xfs_read_symlink, GRUB_FSHELP_DIR); - if (grub_errno) - goto fail; - - grub_xfs_iterate_dir (fdiro, iterate); - - fail: - if (fdiro != &data->diropen) - grub_free (fdiro); - grub_free (data); - - mount_fail: - - grub_dl_unref (my_mod); - - return grub_errno; -} - - /* Open a file named NAME and initialize FILE. */ -static grub_err_t -grub_xfs_open (struct grub_file *file, const char *name) -{ - struct grub_xfs_data *data; - struct grub_fshelp_node *fdiro = 0; +static grub_err_t grub_xfs_open (struct grub_file *file, const char *name) { + struct grub_xfs_data *data; + struct grub_fshelp_node *fdiro = 0; - grub_dl_ref (my_mod); + grub_dl_ref (my_mod); - data = grub_xfs_mount (file->device->disk); - if (!data) - goto mount_fail; + data = grub_xfs_mount (file->device->disk); + if (!data) + goto mount_fail; - grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_xfs_iterate_dir, - grub_xfs_read_symlink, GRUB_FSHELP_REG); - if (grub_errno) - goto fail; + grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_xfs_iterate_dir, + grub_xfs_read_symlink, GRUB_FSHELP_REG); + if (grub_errno) + goto fail; - if (!fdiro->inode_read) - { - grub_xfs_read_inode (data, fdiro->ino, &fdiro->inode); - if (grub_errno) - goto fail; - } + if (!fdiro->inode_read) { + grub_xfs_read_inode (data, fdiro->ino, &fdiro->inode); + if (grub_errno) + goto fail; + } - if (fdiro != &data->diropen) - grub_memcpy (&data->diropen, fdiro, - sizeof (struct grub_fshelp_node) - - sizeof (struct grub_xfs_inode) - + (1 << data->sblock.log2_inode)); + if (fdiro != &data->diropen) + memcpy (&data->diropen, fdiro, sizeof (struct grub_fshelp_node) + - sizeof (struct grub_xfs_inode) + (1 << data->sblock.log2_inode)); - file->size = grub_be_to_cpu64 (data->diropen.inode.size); - file->data = data; - file->offset = 0; + file->size = grub_be_to_cpu64 (data->diropen.inode.size); + file->data = data; + file->offset = 0; - return 0; + return 0; - fail: - if (fdiro != &data->diropen) - grub_free (fdiro); - grub_free (data); +fail: + if (fdiro != &data->diropen) + grub_free (fdiro); + grub_free (data); - mount_fail: - grub_dl_unref (my_mod); +mount_fail: + grub_dl_unref (my_mod); - return grub_errno; + return grub_errno; } - -static grub_ssize_t -grub_xfs_read (grub_file_t file, char *buf, grub_size_t len) -{ - struct grub_xfs_data *data = - (struct grub_xfs_data *) file->data; - - return grub_xfs_read_file (&data->diropen, file->read_hook, - file->offset, len, buf); +static grub_ssize_t grub_xfs_read (grub_file_t file, char *buf, grub_size_t len) { + struct grub_xfs_data *data = (struct grub_xfs_data *) file->data; + return grub_xfs_read_file (&data->diropen, file->read_hook, file->offset, len, buf); } - -static grub_err_t -grub_xfs_close (grub_file_t file) -{ - grub_free (file->data); - - grub_dl_unref (my_mod); - - return GRUB_ERR_NONE; +static grub_err_t grub_xfs_close (grub_file_t file) { + grub_free (file->data); + grub_dl_unref (my_mod); + return GRUB_ERR_NONE; } - -static grub_err_t -grub_xfs_label (grub_device_t device, char **label) -{ - struct grub_xfs_data *data; - grub_disk_t disk = device->disk; - - grub_dl_ref (my_mod); - - data = grub_xfs_mount (disk); - if (data) - *label = grub_strndup ((char *) (data->sblock.label), 12); - else - *label = 0; - - grub_dl_unref (my_mod); - - grub_free (data); - - return grub_errno; +static grub_err_t grub_xfs_label (grub_device_t device, char **label) { + struct grub_xfs_data *data; + grub_disk_t disk = device->disk; + grub_dl_ref (my_mod); + data = grub_xfs_mount (disk); + *label = data?grub_strndup ((char *) (data->sblock.label), 12):0; + grub_dl_unref (my_mod); + grub_free (data); + return grub_errno; } -static grub_err_t -grub_xfs_uuid (grub_device_t device, char **uuid) -{ - struct grub_xfs_data *data; - grub_disk_t disk = device->disk; - - grub_dl_ref (my_mod); - - data = grub_xfs_mount (disk); - if (data) - { - *uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x", - grub_be_to_cpu16 (data->sblock.uuid[0]), - grub_be_to_cpu16 (data->sblock.uuid[1]), - grub_be_to_cpu16 (data->sblock.uuid[2]), - grub_be_to_cpu16 (data->sblock.uuid[3]), - grub_be_to_cpu16 (data->sblock.uuid[4]), - grub_be_to_cpu16 (data->sblock.uuid[5]), - grub_be_to_cpu16 (data->sblock.uuid[6]), - grub_be_to_cpu16 (data->sblock.uuid[7])); - } - else - *uuid = NULL; - - grub_dl_unref (my_mod); - - grub_free (data); - - return grub_errno; +static grub_err_t grub_xfs_uuid (grub_device_t device, char **uuid) { + struct grub_xfs_data *data; + grub_disk_t disk = device->disk; + grub_dl_ref (my_mod); + data = grub_xfs_mount (disk); + if (data) { + *uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x", + grub_be_to_cpu16 (data->sblock.uuid[0]), grub_be_to_cpu16 (data->sblock.uuid[1]), + grub_be_to_cpu16 (data->sblock.uuid[2]), grub_be_to_cpu16 (data->sblock.uuid[3]), + grub_be_to_cpu16 (data->sblock.uuid[4]), grub_be_to_cpu16 (data->sblock.uuid[5]), + grub_be_to_cpu16 (data->sblock.uuid[6]), grub_be_to_cpu16 (data->sblock.uuid[7])); + } else *uuid = NULL; + grub_dl_unref (my_mod); + grub_free (data); + return grub_errno; } - - -struct grub_fs grub_xfs_fs = - { - .name = "xfs", - .dir = grub_xfs_dir, - .open = grub_xfs_open, - .read = grub_xfs_read, - .close = grub_xfs_close, - .label = grub_xfs_label, - .uuid = grub_xfs_uuid, -#ifdef GRUB_UTIL - .reserved_first_sector = 0, -#endif - .next = 0 - }; +struct grub_fs grub_xfs_fs = { + .name = "xfs", + .dir = grub_xfs_dir, + .open = grub_xfs_open, + .read = grub_xfs_read, + .close = grub_xfs_close, + .label = grub_xfs_label, + .uuid = grub_xfs_uuid, + .next = 0 +}; diff --git a/libr/fs/p/grub/include/grub/i18n.h b/libr/fs/p/grub/include/grub/i18n.h index a91d73346e..575e6c4b2a 100644 --- a/libr/fs/p/grub/include/grub/i18n.h +++ b/libr/fs/p/grub/include/grub/i18n.h @@ -22,47 +22,16 @@ #include #include -/* NLS can be disabled through the configure --disable-nls option. */ -#if (defined(ENABLE_NLS) && ENABLE_NLS) || !defined (GRUB_UTIL) - extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s); -# ifdef GRUB_UTIL - -# include -# include - -# endif /* GRUB_UTIL */ - -#else /* ! (defined(ENABLE_NLS) && ENABLE_NLS) */ - /* Disabled NLS. The casts to 'const char *' serve the purpose of producing warnings for invalid uses of the value returned from these functions. On pre-ANSI systems without 'const', the config.h file is supposed to contain "#define const". */ static inline const char * __attribute__ ((always_inline)) -gettext (const char *str) -{ +gettext (const char *str) { return str; } -#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ - -#ifdef GRUB_UTIL -static inline const char * __attribute__ ((always_inline)) -_ (const char *str) -{ - return gettext(str); -} -#else -static inline const char * __attribute__ ((always_inline)) -_ (const char *str) -{ - return grub_gettext(str); -} -#endif /* GRUB_UTIL */ - -#define N_(str) str - -#endif /* GRUB_I18N_H */ +#endif diff --git a/libr/fs/p/grub/kern/device.c b/libr/fs/p/grub/kern/device.c index 3db14f50e0..8f106c247c 100644 --- a/libr/fs/p/grub/kern/device.c +++ b/libr/fs/p/grub/kern/device.c @@ -26,144 +26,119 @@ #include #include -grub_device_t -grub_device_open (const char *name) -{ - grub_disk_t disk = 0; - grub_device_t dev = 0; +grub_device_t grub_device_open (const char *name) { + grub_disk_t disk = 0; + grub_device_t dev = 0; - if (! name) - { - name = grub_env_get ("root"); - if (*name == '\0') - { - grub_error (GRUB_ERR_BAD_DEVICE, "no device is set"); - goto fail; + if (!name) { + name = grub_env_get ("root"); + if (*name == '\0') { + grub_error (GRUB_ERR_BAD_DEVICE, "no device is set"); + goto fail; + } } - } - dev = grub_malloc (sizeof (*dev)); - if (! dev) - goto fail; + dev = grub_malloc (sizeof (*dev)); + if (! dev) + goto fail; - /* Try to open a disk. */ - disk = grub_disk_open (name); - if (! disk) - goto fail; + /* Try to open a disk. */ + disk = grub_disk_open (name); + if (! disk) + goto fail; - dev->disk = disk; - dev->net = 0; /* FIXME */ + dev->disk = disk; + dev->net = 0; /* FIXME */ - return dev; + return dev; - fail: - if (disk) - grub_disk_close (disk); +fail: + if (disk) + grub_disk_close (disk); - grub_free (dev); + grub_free (dev); - return 0; + return 0; } -grub_err_t -grub_device_close (grub_device_t device) -{ - if (device->disk) - grub_disk_close (device->disk); - - grub_free (device); - - return grub_errno; +grub_err_t grub_device_close (grub_device_t device) { + if (device->disk) + grub_disk_close (device->disk); + grub_free (device); + return grub_errno; } -int -grub_device_iterate (int (*hook) (const char *name)) -{ - auto int iterate_disk (const char *disk_name); - auto int iterate_partition (grub_disk_t disk, - const grub_partition_t partition); +/* unnested code */ - struct part_ent - { - struct part_ent *next; - char *name; - } *ents; +static struct part_ent { + struct part_ent *next; + char *name; +} *ents; - int iterate_disk (const char *disk_name) - { - grub_device_t dev; +static int iterate_partition (grub_disk_t disk, const grub_partition_t partition) { + struct part_ent *p; + char *part_name; - if (hook (disk_name)) - return 1; + p = grub_malloc (sizeof (*p)); + if (!p) return 1; - dev = grub_device_open (disk_name); - if (! dev) - { - grub_errno = GRUB_ERR_NONE; - return 0; + part_name = grub_partition_get_name (partition); + if (!part_name) { + grub_free (p); + return 1; + } + p->name = grub_xasprintf ("%s,%s", disk->name, part_name); + grub_free (part_name); + if (!p->name) { + grub_free (p); + return 1; } - if (dev->disk) - { - struct part_ent *p; - int ret = 0; + p->next = ents; + ents = p; - ents = NULL; - (void) grub_partition_iterate (dev->disk, iterate_partition); - grub_device_close (dev); - - grub_errno = GRUB_ERR_NONE; - - p = ents; - while (p != NULL) - { - struct part_ent *next = p->next; - - if (!ret) - ret = hook (p->name); - grub_free (p->name); - grub_free (p); - p = next; - } - - return ret; - } - - grub_device_close (dev); - return 0; - } - - int iterate_partition (grub_disk_t disk, const grub_partition_t partition) - { - struct part_ent *p; - char *part_name; - - p = grub_malloc (sizeof (*p)); - if (!p) - { - return 1; - } - - part_name = grub_partition_get_name (partition); - if (!part_name) - { - grub_free (p); - return 1; - } - p->name = grub_xasprintf ("%s,%s", disk->name, part_name); - grub_free (part_name); - if (!p->name) - { - grub_free (p); - return 1; - } - - p->next = ents; - ents = p; - - return 0; - } - - /* Only disk devices are supported at the moment. */ - return grub_disk_dev_iterate (iterate_disk); + return 0; +} + +static int iterate_disk (const char *disk_name) { + grub_device_t dev; + + if (iterate_disk (disk_name)) + return 1; + + dev = grub_device_open (disk_name); + if (! dev) { + grub_errno = GRUB_ERR_NONE; + return 0; + } + + if (dev->disk) { + struct part_ent *p; + int ret = 0; + + ents = NULL; + (void) grub_partition_iterate (dev->disk, iterate_partition); + grub_device_close (dev); + + grub_errno = GRUB_ERR_NONE; + + p = ents; + while (p != NULL) { + struct part_ent *next = p->next; + + if (!ret) + ret = iterate_disk (p->name); + grub_free (p->name); + grub_free (p); + p = next; + } + return ret; + } + grub_device_close (dev); + return 0; +} + +int grub_device_iterate (int (*hook) (const char *name)) { + /* Only disk devices are supported at the moment. */ + return grub_disk_dev_iterate (iterate_disk); } diff --git a/libr/fs/p/grub/kern/err.c b/libr/fs/p/grub/kern/err.c index 9bd850b263..f7b7ea4e32 100644 --- a/libr/fs/p/grub/kern/err.c +++ b/libr/fs/p/grub/kern/err.c @@ -47,7 +47,7 @@ grub_error (grub_err_t n, const char *fmt, ...) grub_errno = n; va_start (ap, fmt); - grub_vsnprintf (grub_errmsg, sizeof (grub_errmsg), _(fmt), ap); + grub_vsnprintf (grub_errmsg, sizeof (grub_errmsg), fmt, ap); va_end (ap); return n; @@ -59,7 +59,7 @@ grub_fatal (const char *fmt, ...) va_list ap; va_start (ap, fmt); - grub_vprintf (_(fmt), ap); + grub_vprintf (fmt, ap); va_end (ap); grub_abort (); diff --git a/libr/fs/p/grub/kern/fs.c b/libr/fs/p/grub/kern/fs.c index cf800f4cc4..a77eba3745 100644 --- a/libr/fs/p/grub/kern/fs.c +++ b/libr/fs/p/grub/kern/fs.c @@ -28,24 +28,17 @@ #include grub_fs_t grub_fs_list = 0; - grub_fs_autoload_hook_t grub_fs_autoload_hook = 0; -grub_fs_t -grub_fs_probe (grub_device_t device) -{ +static int dummy_func (const char *filename __attribute__ ((unused)), + const struct grub_dirhook_info *info __attribute__ ((unused))) { + return 1; +} + +grub_fs_t grub_fs_probe (grub_device_t device) { grub_fs_t p; - auto int dummy_func (const char *filename, - const struct grub_dirhook_info *info); - int dummy_func (const char *filename __attribute__ ((unused)), - const struct grub_dirhook_info *info __attribute__ ((unused))) - { - return 1; - } - - if (device->disk) - { + if (device->disk) { /* Make it sure not to have an infinite recursive calls. */ static int count = 0; diff --git a/libr/fs/p/grub/kern/misc.c b/libr/fs/p/grub/kern/misc.c index b5c4661b8d..c0d5133c88 100644 --- a/libr/fs/p/grub/kern/misc.c +++ b/libr/fs/p/grub/kern/misc.c @@ -21,103 +21,66 @@ #include #include #include +#include #include #include #include -static int -grub_vsnprintf_real (char *str, grub_size_t n, const char *fmt, va_list args); - -static int -grub_iswordseparator (int c) -{ - return (grub_isspace (c) || c == ',' || c == ';' || c == '|' || c == '&'); +static int grub_iswordseparator (int c) { + return (grub_isspace (c) || c == ',' || c == ';' || c == '|' || c == '&'); } -/* grub_gettext_dummy is not translating anything. */ -static const char * -grub_gettext_dummy (const char *s) -{ - return s; +#define grub_gettext(x) (x) + +void * grub_memmove (void *dest, const void *src, grub_size_t n) { + char *d = (char *) dest; + const char *s = (const char *) src; + + if (d < s) { + while (n--) + *d++ = *s++; + } else { + d += n; + s += n; + while (n--) + *--d = *--s; + } + return dest; } -const char* (*grub_gettext) (const char *s) = grub_gettext_dummy; - -void * -grub_memmove (void *dest, const void *src, grub_size_t n) -{ - char *d = (char *) dest; - const char *s = (const char *) src; - - if (d < s) - while (n--) - *d++ = *s++; - else - { - d += n; - s += n; - - while (n--) - *--d = *--s; - } - - return dest; -} - -#ifndef APPLE_CC -void *memmove (void *dest, const void *src, grub_size_t n) - __attribute__ ((alias ("grub_memmove"))); -/* GCC emits references to memcpy() for struct copies etc. */ -void *memcpy (void *dest, const void *src, grub_size_t n) - __attribute__ ((alias ("grub_memmove"))); -#else -void *memcpy (void *dest, const void *src, grub_size_t n) -{ - return grub_memmove (dest, src, n); -} -void *memmove (void *dest, const void *src, grub_size_t n) -{ - return grub_memmove (dest, src, n); -} -#endif - -char * -grub_strcpy (char *dest, const char *src) -{ +char * grub_strcpy (char *dest, const char *src) { char *p = dest; - - while ((*p++ = *src++) != '\0') - ; - + while ((*p++ = *src++) != '\0') ; return dest; } -char * -grub_strncpy (char *dest, const char *src, int c) -{ +char * grub_strncpy (char *dest, const char *src, int c) { char *p = dest; - - while ((*p++ = *src++) != '\0' && --c) - ; - + while ((*p++ = *src++) != '\0' && --c) ; return dest; } -char * -grub_stpcpy (char *dest, const char *src) -{ +char * grub_stpcpy (char *dest, const char *src) { char *d = dest; const char *s = src; - do - *d++ = *s; - while (*s++ != '\0'); + do *d++ = *s; while (*s++ != '\0'); return d - 1; } -int -grub_printf (const char *fmt, ...) +int grub_printf (const char *fmt, ...) { + va_list ap; + int ret; + + va_start (ap, fmt); + ret = grub_vprintf (fmt, ap); + va_end (ap); + + return ret; +} + +int grub_printf_ (const char *fmt, ...) { va_list ap; int ret; @@ -129,45 +92,10 @@ grub_printf (const char *fmt, ...) return ret; } -int -grub_printf_ (const char *fmt, ...) -{ - va_list ap; - int ret; - - va_start (ap, fmt); - ret = grub_vprintf (_(fmt), ap); - va_end (ap); - - return ret; +int grub_puts_ (const char *s) { + return grub_puts (s); } -int -grub_puts_ (const char *s) -{ - return grub_puts (_(s)); -} - -#if defined (APPLE_CC) && ! defined (GRUB_UTIL) -int -grub_err_printf (const char *fmt, ...) -{ - va_list ap; - int ret; - - va_start (ap, fmt); - ret = grub_vprintf (fmt, ap); - va_end (ap); - - return ret; -} -#endif - -#if ! defined (APPLE_CC) && ! defined (GRUB_UTIL) -int grub_err_printf (const char *fmt, ...) -__attribute__ ((alias("grub_printf"))); -#endif - void grub_real_dprintf (const char *file, const int line, const char *condition, const char *fmt, ...) @@ -190,8 +118,7 @@ grub_real_dprintf (const char *file, const int line, const char *condition, #define PREALLOC_SIZE 255 -int -grub_vprintf (const char *fmt, va_list args) +int grub_vprintf (const char *fmt, va_list args) { grub_size_t s; static char buf[PREALLOC_SIZE + 1]; @@ -223,46 +150,30 @@ grub_vprintf (const char *fmt, va_list args) return s; } -int -grub_memcmp (const void *s1, const void *s2, grub_size_t n) -{ - const char *t1 = s1; - const char *t2 = s2; +int grub_memcmp (const void *s1, const void *s2, grub_size_t n) { + const char *t1 = s1; + const char *t2 = s2; - while (n--) - { - if (*t1 != *t2) - return (int) *t1 - (int) *t2; + while (n--) { + if (*t1 != *t2) + return (int) *t1 - (int) *t2; + t1++; + t2++; + } - t1++; - t2++; - } - - return 0; + return 0; } -#ifndef APPLE_CC -int memcmp (const void *s1, const void *s2, grub_size_t n) - __attribute__ ((alias ("grub_memcmp"))); -#else -int memcmp (const void *s1, const void *s2, grub_size_t n) -{ - return grub_memcmp (s1, s2, n); -} -#endif -int -grub_strcmp (const char *s1, const char *s2) -{ - while (*s1 && *s2) - { - if (*s1 != *s2) - break; +int grub_strcmp (const char *s1, const char *s2) { + while (*s1 && *s2) { + if (*s1 != *s2) + break; - s1++; - s2++; - } + s1++; + s2++; + } - return (int) *s1 - (int) *s2; + return (int) *s1 - (int) *s2; } int @@ -283,32 +194,23 @@ grub_strncmp (const char *s1, const char *s2, grub_size_t n) return (int) *s1 - (int) *s2; } -char * -grub_strchr (const char *s, int c) -{ - do - { - if (*s == c) - return (char *) s; - } - while (*s++); - - return 0; +char * grub_strchr (const char *s, int c) { + do { + if (*s == c) + return (char *) s; + } while (*s++); + return 0; } -char * -grub_strrchr (const char *s, int c) -{ - char *p = NULL; +char * grub_strrchr (const char *s, int c) { + char *p = NULL; - do - { - if (*s == c) - p = (char *) s; - } - while (*s++); + do { + if (*s == c) + p = (char *) s; + } while (*s++); - return p; + return p; } /* Copied from gnulib. @@ -523,6 +425,8 @@ grub_strndup (const char *s, grub_size_t n) void * grub_memset (void *s, int c, grub_size_t len) { + return memset(s,c,len); +#if 0 void *p = s; grub_uint8_t pattern8 = c; @@ -534,7 +438,7 @@ grub_memset (void *s, int c, grub_size_t len) for (i = 0; i < sizeof (unsigned long); i++) patternl |= ((unsigned long) pattern8) << (8 * i); - while (len > 0 && (((grub_addr_t) p) & (sizeof (unsigned long) - 1))) + while (len > 0 && (((grub_addr_t) p) & (sizeof (void *) - 1))) { *(grub_uint8_t *) p = pattern8; p = (grub_uint8_t *) p + 1; @@ -556,16 +460,8 @@ grub_memset (void *s, int c, grub_size_t len) } return s; -} -#ifndef APPLE_CC -void *memset (void *s, int c, grub_size_t n) - __attribute__ ((alias ("grub_memset"))); -#else -void *memset (void *s, int c, grub_size_t n) -{ - return grub_memset (s, c, n); -} #endif +} grub_size_t grub_strlen (const char *s) @@ -679,42 +575,29 @@ grub_lltoa (char *str, int c, unsigned long long n) return p; } -static int -grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt, va_list args) -{ +#if 1 +static grub_size_t count, max_len; +static char *str; + +static void write_char(char ch) { + if (count++ fmt) - { + if (p > fmt) { char s[p - fmt + 1]; grub_strncpy (s, fmt, p - fmt); s[p - fmt] = 0; @@ -748,15 +630,13 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt, va_list ar fmt = p; } - if (*p && *p == '.') - { + if (*p && *p == '.') { p++; fmt++; while (*p && grub_isdigit (*p)) p++; - if (p > fmt) - { + if (p > fmt) { char fstr[p - fmt + 1]; grub_strncpy (fstr, fmt, p - fmt); fstr[p - fmt] = 0; @@ -777,58 +657,47 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt, va_list ar } } - switch (c) - { - case 'p': - write_str ("0x"); - c = 'x'; - longlongfmt |= (sizeof (void *) == sizeof (long long)); - /* Fall through. */ - case 'x': - case 'u': - unsig = 1; - /* Fall through. */ - case 'd': - if (longlongfmt) - { - long long ll; + switch (c) { + case 'p': + write_str ("0x"); + c = 'x'; + longlongfmt |= (sizeof (void *) == sizeof (long long)); + /* Fall through. */ + case 'x': + case 'u': + unsig = 1; + /* Fall through. */ + case 'd': + if (longlongfmt) { + long long ll; - ll = va_arg (args, long long); - grub_lltoa (tmp, c, ll); - } - else if (longfmt && unsig) - { - unsigned long l = va_arg (args, unsigned long); - grub_lltoa (tmp, c, l); - } - else if (longfmt) - { - long l = va_arg (args, long); - grub_lltoa (tmp, c, l); - } - else if (unsig) - { - unsigned u = va_arg (args, unsigned); - grub_lltoa (tmp, c, u); - } - else - { + ll = va_arg (args, long long); + grub_lltoa (tmp, c, ll); + } else if (longfmt && unsig) { + unsigned long l = va_arg (args, unsigned long); + grub_lltoa (tmp, c, l); + } else if (longfmt) { + long l = va_arg (args, long); + grub_lltoa (tmp, c, l); + } else if (unsig) { + unsigned u = va_arg (args, unsigned); + grub_lltoa (tmp, c, u); + } else { + n = va_arg (args, int); + grub_lltoa (tmp, c, n); + } + if (! rightfill && grub_strlen (tmp) < format1) + write_fill (zerofill, format1 - grub_strlen (tmp)); + write_str (tmp); + if (rightfill && grub_strlen (tmp) < format1) + write_fill (zerofill, format1 - grub_strlen (tmp)); + break; + case 'c': n = va_arg (args, int); - grub_lltoa (tmp, c, n); - } - if (! rightfill && grub_strlen (tmp) < format1) - write_fill (zerofill, format1 - grub_strlen (tmp)); - write_str (tmp); - if (rightfill && grub_strlen (tmp) < format1) - write_fill (zerofill, format1 - grub_strlen (tmp)); - break; + write_char (n & 0xff); + break; - case 'c': - n = va_arg (args, int); - write_char (n & 0xff); - break; - - case 'C': + case 'C': { grub_uint32_t code = va_arg (args, grub_uint32_t); int shift; @@ -912,6 +781,7 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt, va_list ar return count; } +#endif int grub_vsnprintf (char *str, grub_size_t n, const char *fmt, va_list ap) @@ -983,29 +853,3 @@ grub_abort (void) { grub_printf ("\nAborted."); } - -#if 0 -#if ! defined (APPLE_CC) && !defined (GRUB_UTIL) -/* GCC emits references to abort(). */ -void abort (void) __attribute__ ((alias ("grub_abort"))); -#endif -#endif - -#if NEED_ENABLE_EXECUTE_STACK && !defined(GRUB_UTIL) && !defined(GRUB_MACHINE_EMU) -/* Some gcc versions generate a call to this function - in trampolines for nested functions. */ -void __enable_execute_stack (void *addr __attribute__ ((unused))) -{ -} -#endif - -#if NEED_REGISTER_FRAME_INFO && !defined(GRUB_UTIL) -void __register_frame_info (void) -{ -} - -void __deregister_frame_info (void) -{ -} -#endif - diff --git a/libr/fs/p/grub/kern/partition.c b/libr/fs/p/grub/kern/partition.c index e6b2831d25..faa3e11490 100644 --- a/libr/fs/p/grub/kern/partition.c +++ b/libr/fs/p/grub/kern/partition.c @@ -20,6 +20,7 @@ #include #include #include +#include #ifdef GRUB_UTIL #include @@ -32,218 +33,181 @@ grub_partition_map_t grub_partition_map_list; * start of part is relative to the start of disk->partition. Returns 1 if * disk->partition is null. */ -static int -grub_partition_check_containment (const grub_disk_t disk, - const grub_partition_t part) -{ - if (disk->partition == NULL) - return 1; +static int grub_partition_check_containment (const grub_disk_t disk, const grub_partition_t part) { + if (disk->partition != NULL && ((part->start + part->len > disk->partition->len))) { + char *partname = grub_partition_get_name (disk->partition); + grub_dprintf ("partition", "sub-partition %s%d of (%s,%s) ends after parent.\n", + part->partmap->name, part->number + 1, disk->name, partname); + grub_free (partname); + return 0; + } + return 1; +} - if (part->start + part->len > disk->partition->len) - { - char *partname; +static int partnum = 0; - partname = grub_partition_get_name (disk->partition); - grub_dprintf ("partition", "sub-partition %s%d of (%s,%s) ends after parent.\n", - part->partmap->name, part->number + 1, disk->name, partname); - grub_free (partname); - - return 0; - } - - return 1; +static grub_partition_t p = NULL; +static int find_func (grub_disk_t dsk, const grub_partition_t partition) { + if (partnum != partition->number) + return 0; + if (!(grub_partition_check_containment (dsk, partition))) + return 0; + p = (grub_partition_t) malloc (sizeof (*p)); + if (! p) + return 1; + memcpy (p, partition, sizeof (*p)); + return 1; } static grub_partition_t -grub_partition_map_probe (const grub_partition_map_t partmap, - grub_disk_t disk, int partnum) -{ - grub_partition_t p = 0; - - auto int find_func (grub_disk_t d, const grub_partition_t partition); - - int find_func (grub_disk_t dsk, - const grub_partition_t partition) - { - if (partnum != partition->number) - return 0; - - if (!(grub_partition_check_containment (dsk, partition))) - return 0; - - p = (grub_partition_t) grub_malloc (sizeof (*p)); - if (! p) - return 1; - - grub_memcpy (p, partition, sizeof (*p)); - return 1; - } - - partmap->iterate (disk, find_func); - if (grub_errno) - goto fail; - - return p; - - fail: - grub_free (p); - return 0; +grub_partition_map_probe (const grub_partition_map_t partmap, grub_disk_t disk, int _partnum) { + partnum = _partnum; + partmap->iterate (disk, find_func); + if (grub_errno) { + grub_free (p); + return NULL; + } + return p; } -grub_partition_t -grub_partition_probe (struct grub_disk *disk, const char *str) -{ - grub_partition_t part = 0; - grub_partition_t curpart = 0; - grub_partition_t tail; - const char *ptr; +grub_partition_t grub_partition_probe (struct grub_disk *disk, const char *str) { + grub_partition_t part = 0; + grub_partition_t curpart = 0; + grub_partition_t tail; + const char *ptr; - part = tail = disk->partition; + part = tail = disk->partition; - for (ptr = str; *ptr;) - { - grub_partition_map_t partmap; - int num; - const char *partname, *partname_end; + for (ptr = str; *ptr;) { + grub_partition_map_t partmap; + int num; + const char *partname, *partname_end; - partname = ptr; - while (*ptr && grub_isalpha (*ptr)) - ptr++; - partname_end = ptr; - num = grub_strtoul (ptr, (char **) &ptr, 0) - 1; + partname = ptr; + while (*ptr && grub_isalpha (*ptr)) + ptr++; + partname_end = ptr; + num = grub_strtoul (ptr, (char **) &ptr, 0) - 1; - curpart = 0; - /* Use the first partition map type found. */ - FOR_PARTITION_MAPS(partmap) - { - if (partname_end != partname && - (grub_strncmp (partmap->name, partname, partname_end - partname) - != 0 || partmap->name[partname_end - partname] != 0)) - continue; + curpart = 0; + /* Use the first partition map type found. */ + FOR_PARTITION_MAPS(partmap) { + if (partname_end != partname && + (grub_strncmp (partmap->name, partname, partname_end - partname) + != 0 || partmap->name[partname_end - partname] != 0)) + continue; - disk->partition = part; - curpart = grub_partition_map_probe (partmap, disk, num); - disk->partition = tail; - if (curpart) - break; + disk->partition = part; + curpart = grub_partition_map_probe (partmap, disk, num); + disk->partition = tail; + if (curpart) + break; - if (grub_errno == GRUB_ERR_BAD_PART_TABLE) - { - /* Continue to next partition map type. */ - grub_errno = GRUB_ERR_NONE; - continue; - } + if (grub_errno == GRUB_ERR_BAD_PART_TABLE) { + /* Continue to next partition map type. */ + grub_errno = GRUB_ERR_NONE; + continue; + } + break; + } - break; - } - - if (! curpart) - { - while (part) - { - curpart = part->parent; - grub_free (part); - part = curpart; - } - return 0; + if (! curpart) { + while (part) { + curpart = part->parent; + grub_free (part); + part = curpart; + } + return 0; + } + curpart->parent = part; + part = curpart; + if (! ptr || *ptr != ',') + break; + ptr++; } - curpart->parent = part; - part = curpart; - if (! ptr || *ptr != ',') - break; - ptr++; - } - return part; + return part; } -int -grub_partition_iterate (struct grub_disk *disk, - int (*hook) (grub_disk_t disk, - const grub_partition_t partition)) -{ - int ret = 0; +static int (*hook) (grub_disk_t disk, const grub_partition_t partition); +int part_iterate (grub_disk_t dsk, const grub_partition_t partition) { + int ret = 0; + struct grub_partition p = *partition; - auto int part_iterate (grub_disk_t dsk, const grub_partition_t p); + if (!(grub_partition_check_containment (dsk, partition))) + return 0; - int part_iterate (grub_disk_t dsk, - const grub_partition_t partition) - { - struct grub_partition p = *partition; - - if (!(grub_partition_check_containment (dsk, partition))) - return 0; - - p.parent = dsk->partition; - dsk->partition = 0; - if (hook (dsk, &p)) - { - ret = 1; - return 1; + p.parent = dsk->partition; + dsk->partition = 0; + if (hook (dsk, &p)) { + ret = 1; + return 1; } - if (p.start != 0) - { - const struct grub_partition_map *partmap; - dsk->partition = &p; - FOR_PARTITION_MAPS(partmap) - { - grub_err_t err; - err = partmap->iterate (dsk, part_iterate); - if (err) - grub_errno = GRUB_ERR_NONE; - if (ret) - break; - } + if (p.start != 0) { + const struct grub_partition_map *partmap; + dsk->partition = &p; + FOR_PARTITION_MAPS(partmap) { + grub_err_t err; + err = partmap->iterate (dsk, part_iterate); + if (err) + grub_errno = GRUB_ERR_NONE; + if (ret) + break; + } } - dsk->partition = p.parent; - return ret; - } - - { - const struct grub_partition_map *partmap; - FOR_PARTITION_MAPS(partmap) - { - grub_err_t err; - err = partmap->iterate (disk, part_iterate); - if (err) - grub_errno = GRUB_ERR_NONE; - if (ret) - break; - } - } - - return ret; + dsk->partition = p.parent; + return ret; } -char * -grub_partition_get_name (const grub_partition_t partition) +int grub_partition_iterate (struct grub_disk *disk, + int (*_hook) (grub_disk_t disk, const grub_partition_t partition)) { - char *out = 0; - int curlen = 0; - grub_partition_t part; - for (part = partition; part; part = part->parent) - { - /* Even on 64-bit machines this buffer is enough to hold - longest number. */ - char buf[grub_strlen (part->partmap->name) + 25]; - int strl; - grub_snprintf (buf, sizeof (buf), "%s%d", part->partmap->name, - part->number + 1); - strl = grub_strlen (buf); - if (curlen) + int ret = 0; + hook = _hook; + //auto int part_iterate (grub_disk_t dsk, const grub_partition_t p); + { - out = grub_realloc (out, curlen + strl + 2); - grub_memcpy (out + strl + 1, out, curlen); - out[curlen + 1 + strl] = 0; - grub_memcpy (out, buf, strl); - out[strl] = ','; - curlen = curlen + 1 + strl; + const struct grub_partition_map *partmap; + FOR_PARTITION_MAPS (partmap) { + grub_err_t err; + err = partmap->iterate (disk, part_iterate); + if (err) + grub_errno = GRUB_ERR_NONE; + if (ret) + break; + } } - else - { - curlen = strl; - out = grub_strdup (buf); - } - } - return out; + + return ret; +} + +char * grub_partition_get_name (const grub_partition_t partition) { + char *out = 0; + int curlen = 0; + grub_partition_t part; + for (part = partition; part; part = part->parent) + { + /* Even on 64-bit machines this buffer is enough to hold + longest number. */ + char buf[grub_strlen (part->partmap->name) + 25]; + int strl; + grub_snprintf (buf, sizeof (buf), "%s%d", part->partmap->name, + part->number + 1); + strl = grub_strlen (buf); + if (curlen) + { + out = grub_realloc (out, curlen + strl + 2); + grub_memcpy (out + strl + 1, out, curlen); + out[curlen + 1 + strl] = 0; + grub_memcpy (out, buf, strl); + out[strl] = ','; + curlen = curlen + 1 + strl; + } + else + { + curlen = strl; + out = grub_strdup (buf); + } + } + return out; } diff --git a/libr/fs/p/grub/main.c b/libr/fs/p/grub/main.c index 60a0726653..fb35cda285 100644 --- a/libr/fs/p/grub/main.c +++ b/libr/fs/p/grub/main.c @@ -1,6 +1,7 @@ #include #include #include +#include #include extern struct grub_fs grub_ext2_fs;