From b0574dee64f9c86a6e3a93e3044f7711a9363dd9 Mon Sep 17 00:00:00 2001 From: okuji Date: Sun, 20 Feb 2000 05:27:14 +0000 Subject: [PATCH] add a new command, cmp, and fix a bug in fat_mount. --- ChangeLog | 9 +++++ NEWS | 1 + stage2/builtins.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++ stage2/fsys_fat.c | 19 ++++++---- 4 files changed, 112 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 307cd0052..dad635729 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2000-02-19 OKUJI Yoshinori + + * stage2/builtins.c (cmp_func): New function. + (builtin_cmp): New variable. + (builtin_table): Added a pointer to BUILTIN_CMP. + + * stage2/fsys_fat.c (fat_mount): Check if BPB.SECTS_PER_CLUST is + zero after reading the BPB to avoid zero division. + 2000-02-18 OKUJI Yoshinori * stage2/disk_io.c [!STAGE1_5] (make_saved_active): Make sure diff --git a/NEWS b/NEWS index 343bc313a..1c617700b 100644 --- a/NEWS +++ b/NEWS @@ -41,6 +41,7 @@ New in 0.5.94: * New commands "bootp", "dhcp" and "rarp" can be used to initialize a network device and get IP addresses from a network. * Long filename support in the FAT filesystem is added. +* The command "cmp" compares each bytes in two files. New in 0.5.93 - 1999-10-30: * ELF format of FreeBSD kernel is supported. diff --git a/stage2/builtins.c b/stage2/builtins.c index 590599116..a93040588 100644 --- a/stage2/builtins.c +++ b/stage2/builtins.c @@ -377,6 +377,95 @@ static struct builtin builtin_chainloader = " forcibly, whether the boot loader signature is present or not." }; + +/* This function could be used to debug new filesystem code. Put a file + in the new filesystem and the same file in a well-tested filesystem. + Then, run "cmp" with the files. If no output is obtained, probably + the code is good, otherwise investigate what's wrong... */ +/* cmp FILE1 FILE2 */ +static int +cmp_func (char *arg, int flags) +{ + /* The filenames. */ + char *file1, *file2; + /* The addresses. */ + char *addr1, *addr2; + int i; + /* The size of the file. */ + int size; + + /* Get the filenames from ARG. */ + file1 = arg; + file2 = skip_to (0, arg); + if (! *file1 || ! *file2) + { + errnum = ERR_BAD_ARGUMENT; + return 1; + } + + /* Terminate the filenames for convenience. */ + nul_terminate (file1); + nul_terminate (file2); + + /* Read the whole data from FILE1. */ + addr1 = (char *) RAW_ADDR (0x100000); + if (! grub_open (file1)) + return 1; + + /* Get the size. */ + size = filemax; + if (grub_read (addr1, -1) != size) + { + grub_close (); + return 1; + } + + grub_close (); + + /* Read the whole data from FILE2. */ + addr2 = addr1 + size; + if (! grub_open (file2)) + return 1; + + /* Check if the size of FILE2 is equal to the one of FILE2. */ + if (size != filemax) + { + grub_printf ("Differ in size: 0x%x [%s], 0x%x [%s]\n", + size, file1, filemax, file2); + grub_close (); + return 0; + } + + if (! grub_read (addr2, -1)) + { + grub_close (); + return 1; + } + + grub_close (); + + /* Now compare ADDR1 with ADDR2. */ + for (i = 0; i < size; i++) + { + if (addr1[i] != addr2[i]) + grub_printf ("Differ at the offset %d: 0x%x [%s], 0x%x [%s]\n", + i, (unsigned) addr1[i], file1, + (unsigned) addr2[i], file2); + } + + return 0; +} + +static struct builtin builtin_cmp = +{ + "cmp", + cmp_func, + BUILTIN_CMDLINE, + "cmp FILE1 FILE2", + "Compare the file FILE1 with the FILE2 and inform the different values" + " if any." +}; + /* color */ /* Set new colors used for the menu interface. Support two methods to @@ -2839,6 +2928,7 @@ struct builtin *builtin_table[] = &builtin_bootp, &builtin_cat, &builtin_chainloader, + &builtin_cmp, &builtin_color, &builtin_configfile, &builtin_debug, diff --git a/stage2/fsys_fat.c b/stage2/fsys_fat.c index 7c1be888f..8aecaf298 100644 --- a/stage2/fsys_fat.c +++ b/stage2/fsys_fat.c @@ -67,22 +67,27 @@ fat_mount (void) return 0; /* Read bpb */ - if (!devread (0, 0, sizeof(bpb), (char *) &bpb)) + if (! devread (0, 0, sizeof (bpb), (char *) &bpb)) + return 0; + + /* Check if the number of sectors per cluster is zero here, to avoid + zero division. */ + if (bpb.sects_per_clust == 0) return 0; - for (i = 0; (1 << i) < FAT_CVT_U16(bpb.bytes_per_sect); i++) - {} + for (i = 0; (1 << i) < FAT_CVT_U16 (bpb.bytes_per_sect); i++) + ; FAT_SUPER->sectsize_bits = i; for (i = 0; (1 << i) < bpb.sects_per_clust; i++) - {} + ; FAT_SUPER->clustsize_bits = FAT_SUPER->sectsize_bits + i; /* Fill in info about super block */ - FAT_SUPER->num_sectors = FAT_CVT_U16(bpb.short_sectors) - ? FAT_CVT_U16(bpb.short_sectors) : bpb.long_sectors; + FAT_SUPER->num_sectors = FAT_CVT_U16 (bpb.short_sectors) + ? FAT_CVT_U16 (bpb.short_sectors) : bpb.long_sectors; /* FAT offset and length */ - FAT_SUPER->fat_offset = FAT_CVT_U16(bpb.reserved_sects); + FAT_SUPER->fat_offset = FAT_CVT_U16 (bpb.reserved_sects); FAT_SUPER->fat_length = bpb.fat_length ? bpb.fat_length : bpb.fat32_length;