/* minicmd.c - commands for the rescue mode */ /* * GRUB -- GRand Unified Bootloader * Copyright (C) 2003,2005,2006,2007,2009,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GRUB is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GRUB. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include static grub_err_t grub_cmd_testload (struct grub_command *cmd __attribute__ ((unused)), int argc, char *argv[]) { grub_file_t file; char *buf; grub_size_t size; grub_off_t pos; auto void NESTED_FUNC_ATTR read_func (grub_disk_addr_t sector, unsigned offset, unsigned len); void NESTED_FUNC_ATTR read_func (grub_disk_addr_t sector __attribute__ ((unused)), unsigned offset __attribute__ ((unused)), unsigned len __attribute__ ((unused))) { grub_xputs ("."); grub_refresh (); } if (argc < 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified"); file = grub_file_open (argv[0]); if (! file) return grub_errno; size = grub_file_size (file) & ~(GRUB_DISK_SECTOR_SIZE - 1); if (size == 0) { grub_file_close (file); return GRUB_ERR_NONE; } buf = grub_malloc (size); if (! buf) goto fail; grub_printf ("Reading %s sequentially", argv[0]); file->read_hook = read_func; if (grub_file_read (file, buf, size) != (grub_ssize_t) size) goto fail; grub_printf (" Done.\n"); /* Read sequentially again. */ grub_printf ("Reading %s sequentially again", argv[0]); grub_file_seek (file, 0); for (pos = 0; pos < size; pos += GRUB_DISK_SECTOR_SIZE) { char sector[GRUB_DISK_SECTOR_SIZE]; if (grub_file_read (file, sector, GRUB_DISK_SECTOR_SIZE) != GRUB_DISK_SECTOR_SIZE) goto fail; if (grub_memcmp (sector, buf + pos, GRUB_DISK_SECTOR_SIZE) != 0) { grub_printf ("\nDiffers in %lld\n", (unsigned long long) pos); goto fail; } } grub_printf (" Done.\n"); /* Read backwards and compare. */ grub_printf ("Reading %s backwards", argv[0]); pos = size; while (pos > 0) { char sector[GRUB_DISK_SECTOR_SIZE]; pos -= GRUB_DISK_SECTOR_SIZE; grub_file_seek (file, pos); if (grub_file_read (file, sector, GRUB_DISK_SECTOR_SIZE) != GRUB_DISK_SECTOR_SIZE) goto fail; if (grub_memcmp (sector, buf + pos, GRUB_DISK_SECTOR_SIZE) != 0) { int i; grub_printf ("\nDiffers in %lld\n", (unsigned long long) pos); for (i = 0; i < GRUB_DISK_SECTOR_SIZE; i++) { grub_printf ("%02x ", buf[pos + i]); if ((i & 15) == 15) grub_printf ("\n"); } if (i) grub_refresh (); goto fail; } } grub_printf (" Done.\n"); return GRUB_ERR_NONE; fail: grub_file_close (file); grub_free (buf); if (!grub_errno) grub_error (GRUB_ERR_IO, "bad read"); return grub_errno; } static grub_command_t cmd; GRUB_MOD_INIT(testload) { cmd = grub_register_command ("testload", grub_cmd_testload, N_("FILE"), N_("Load the same file in multiple ways.")); } GRUB_MOD_FINI(testload) { grub_unregister_command (cmd); }