diff --git a/ChangeLog b/ChangeLog index b243ea10f..ff3c79041 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +1999-12-30 OKUJI Yoshinori + + * stage2/builtins.c (blocklist_func): New function. + (builtin_blocklist): New variable. + (builtin_table): Added a pointer to BUILTIN_BLOCKLIST. + * docs/user-ref.texi (Command-line-specific commands): Added a + description about the command "blocklist". + 1999-12-30 OKUJI Yoshinori * stage2/disk_io.c (grub_seek): New function. diff --git a/NEWS b/NEWS index f4c306f34..c8c9580ec 100644 --- a/NEWS +++ b/NEWS @@ -26,6 +26,7 @@ New in 0.5.94: * The command "install" can now patch a Stage 2 with a different filename from "/boot/grub/menu.lst" even if a Stage 1.5 is used. * New program, ``grub-install''. +* The command "blocklist" prints the blocklist notation of a file. New in 0.5.93 - 1999-10-30: * ELF format of FreeBSD kernel is supported. diff --git a/docs/user-ref.texi b/docs/user-ref.texi index 50f55bc56..cc7452d78 100644 --- a/docs/user-ref.texi +++ b/docs/user-ref.texi @@ -738,6 +738,11 @@ partitions exist in one disk. These commands are usable only in the command line and in menu entries. If you forget some command, run the command @command{help}. +@deffn Command blocklist file +Print the blocklist notation of the file @var{file} (@pxref{Blocklist +syntax}). +@end deffn + @deffn Command boot This boots the OS/chain-loader which has been loaded. Only necessary if running the fully interactive command line (it is implicit at the end of diff --git a/stage2/builtins.c b/stage2/builtins.c index c90871e6c..79591e07c 100644 --- a/stage2/builtins.c +++ b/stage2/builtins.c @@ -79,6 +79,85 @@ disk_read_print_func (int sector) } +/* blocklist */ +static int +blocklist_func (char *arg, int flags) +{ + char *dummy = (char *) RAW_ADDR (0x100000); + int start_sector; + int num_sectors = 0; + int num_entries = 0; + + /* Collect contiguous blocks into one entry as many as possible, + and print the blocklist notation on the screen. */ + static void disk_read_blocklist_func (int sector) + { + if (debug) + grub_printf ("[%d]", sector); + + if (num_sectors > 0) + { + if (start_sector + num_sectors == sector) + num_sectors++; + else + { + grub_printf ("%s%d+%d", num_entries ? "," : "", + start_sector - part_start, num_sectors); + num_entries++; + num_sectors = 0; + } + } + else + { + start_sector = sector; + num_sectors = 1; + } + } + + /* Open the file. */ + if (! grub_open (arg)) + return 1; + + /* Print the device name. */ + grub_printf ("(%cd%d", + (current_drive & 0x80) ? 'h' : 'f', + current_drive & ~0x80); + + if ((current_partition & 0xFF0000) != 0xFF0000) + grub_printf (",%d", (current_partition >> 16) & 0xFF); + + if ((current_partition & 0x00FF00) != 0x00FF00) + grub_printf (",%c", 'a' + ((current_partition >> 8) & 0xFF)); + + grub_printf (")"); + + /* Read in the whole file to DUMMY. */ + disk_read_hook = disk_read_blocklist_func; + if (! grub_read (dummy, -1)) + goto fail; + + /* The last entry may not be printed yet. */ + if (num_sectors > 0) + grub_printf ("%s%d+%d", num_entries ? "," : "", + start_sector - part_start, num_sectors); + + grub_printf ("\n"); + + fail: + disk_read_hook = 0; + grub_close (); + return errnum; +} + +static struct builtin builtin_blocklist = +{ + "blocklist", + blocklist_func, + BUILTIN_CMDLINE, + "blocklist FILE", + "Print the blocklist notation of the file FILE." +}; + /* boot */ static int boot_func (char *arg, int flags) @@ -2603,6 +2682,7 @@ static struct builtin builtin_uppermem = /* The table of builtin commands. Sorted in dictionary order. */ struct builtin *builtin_table[] = { + &builtin_blocklist, &builtin_boot, &builtin_cat, &builtin_chainloader,