2009-06-22 Robert Millan * commands/search.c: Include `' and `'. (struct grub_arg_option options): Add "disk" option. (enum options): Add `SEARCH_DISK' key. (search_file): Add a new parameter, `restrict_to', which when set will restrict the search to a given disk. (grub_cmd_search): Recognize -d|--disk option, and pass it as parameter to search_file(). Index: commands/search.c =================================================================== --- commands/search.c (revision 2362) +++ commands/search.c (working copy) @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include #include @@ -34,6 +36,7 @@ static const struct grub_arg_option opti {"fs-uuid", 'u', 0, "search devices by a filesystem UUID", 0, 0}, {"set", 's', GRUB_ARG_OPTION_OPTIONAL, "set a variable to the first device found", "VAR", ARG_TYPE_STRING}, {"no-floppy", 'n', 0, "do not probe any floppy drive", 0, 0}, + {"disk", 'd', 0, "only search a file in this disk and its partitions", "VAR", ARG_TYPE_DEVICE}, {0, 0, 0, 0, 0, 0} }; @@ -44,6 +47,7 @@ enum options SEARCH_FS_UUID, SEARCH_SET, SEARCH_NO_FLOPPY, + SEARCH_DISK, }; static void @@ -110,7 +114,7 @@ search_fs (const char *key, const char * } static void -search_file (const char *key, const char *var, int no_floppy) +search_file (const char *key, const char *var, int no_floppy, grub_disk_t restrict_to) { int count = 0; char *buf = 0; @@ -157,7 +161,37 @@ search_file (const char *key, const char return abort; } - grub_device_iterate (iterate_device); + if (restrict_to) + { + unsigned int partcount = 0, i; + grub_size_t len; + char *partname; + int ret; + + auto int hook (struct grub_disk *disk, const grub_partition_t partition); + int hook (struct grub_disk *disk __attribute__ ((unused)), + const grub_partition_t partition __attribute__ ((unused))) + { + partcount++; + return 0; + } + + grub_partition_iterate (restrict_to, hook); + + if (! iterate_device (restrict_to->name)) + for (i = 1; i <= partcount; i++) + { + len = grub_strlen (restrict_to->name); + partname = grub_malloc (len + 4); + grub_sprintf (partname, "%s,%u", restrict_to->name, i); + ret = iterate_device (partname); + grub_free (partname); + if (ret) + break; + } + } + else + grub_device_iterate (iterate_device); grub_free (buf); @@ -170,6 +204,7 @@ grub_cmd_search (grub_extcmd_t cmd, int { struct grub_arg_list *state = cmd->state; const char *var = 0; + grub_disk_t disk = NULL; if (argc == 0) return grub_error (GRUB_ERR_INVALID_COMMAND, "no argument specified"); @@ -177,12 +212,20 @@ grub_cmd_search (grub_extcmd_t cmd, int if (state[SEARCH_SET].set) var = state[SEARCH_SET].arg ? state[SEARCH_SET].arg : "root"; + if (state[SEARCH_DISK].set) + { + if (state[SEARCH_DISK].arg) + disk = grub_disk_open (state[SEARCH_DISK].arg); + else + return grub_error (GRUB_ERR_INVALID_COMMAND, "unspecified disk"); + } + if (state[SEARCH_LABEL].set) search_fs (args[0], var, state[SEARCH_NO_FLOPPY].set, 0); else if (state[SEARCH_FS_UUID].set) search_fs (args[0], var, state[SEARCH_NO_FLOPPY].set, 1); else if (state[SEARCH_FILE].set) - search_file (args[0], var, state[SEARCH_NO_FLOPPY].set); + search_file (args[0], var, state[SEARCH_NO_FLOPPY].set, disk); else return grub_error (GRUB_ERR_INVALID_COMMAND, "unspecified search type"); @@ -196,7 +239,7 @@ GRUB_MOD_INIT(search) cmd = grub_register_extcmd ("search", grub_cmd_search, GRUB_COMMAND_FLAG_BOTH, - "search [-f|-l|-u|-s|-n] NAME", + "search [-f|-l|-u|-s|-n|-d] NAME", "Search devices by file, filesystem label or filesystem UUID." " If --set is specified, the first device found is" " set to a variable. If no variable name is"