+2002-04-06  Yoshinori K. Okuji  <okuji@enbug.org>
+
+       * stage2/builtins.c [GRUB_UTIL] (dump_func): New function.
+       [GRUB_UTIL] (builtin_dump): New variable.
+       (builtin_table) [GRUB_UTIL]: Added a pointer to BUILTIN_DUMP.
+       * util/grub-install.in: Make sure that GRUB reads the same
+       images as the host operating system by comparing the result of
+       running the command "dump" with the contents of the OS file.
+       
 2002-04-04  Yoshinori K. Okuji  <okuji@enbug.org>
 
        * stage2/builtins.c (setup_func): Don't embed a drive number, if
 
 * A fallback entry is executed immediately after a default entry,
   without prompting a user's intervention, as the manual has ever been
   saying.
+* The utility ``grub-install'' makes sure that GRUB images have been
+  written to a physical disk completely. To assist this feature, a new
+  command "dump" is added.
 
 New in 0.91 - 2002-01-21:
 * Support for Linux DAC960 is added.
 
   " machine is, including all regions of physical RAM installed."
 };
 
+\f
+/* dump FROM TO */
+#ifdef GRUB_UTIL
+static int
+dump_func (char *arg, int flags)
+{
+  char *from, *to;
+  FILE *fp;
+  char c;
+  
+  from = arg;
+  to = skip_to (0, arg);
+  if (! *from || ! *to)
+    {
+      errnum = ERR_BAD_ARGUMENT;
+      return 1;
+    }
+
+  nul_terminate (from);
+  nul_terminate (to);
+  
+  if (! grub_open (from))
+    return 1;
+
+  fp = fopen (to, "w");
+  if (! fp)
+    {
+      errnum = ERR_WRITE;
+      return 1;
+    }
+
+  while (grub_read (&c, 1))
+    if (fputc (c, fp) == EOF)
+      {
+       errnum = ERR_WRITE;
+       fclose (fp);
+       return 1;
+      }
+
+  if (fclose (fp) == EOF)
+    {
+      errnum = ERR_WRITE;
+      return 1;
+    }
+
+  grub_close ();
+  return 0;
+}
+
+static struct builtin builtin_dump =
+  {
+    "dump",
+    dump_func,
+    BUILTIN_CMDLINE,
+    "dump FROM TO",
+    "Dump the contents of the file FROM to the file TO. FROM must be"
+    " a GRUB file and TO must be an OS file."
+  };
+#endif /* GRUB_UTIL */
+
 \f
 static char embed_info[32];
 /* embed */
 #endif /* SUPPORT_NETBOOT */
   &builtin_displayapm,
   &builtin_displaymem,
+#ifdef GRUB_UTIL
+  &builtin_dump,
+#endif /* GRUB_UTIL */
   &builtin_embed,
   &builtin_fallback,
   &builtin_find,
 
 #! /bin/sh
 
 # Install GRUB on your drive.
-#   Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+#   Copyright (C) 1999,2000,2001,2002 Free Software Foundation, Inc.
 #
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
 
 grub_shell=${sbindir}/grub
 log_file=/tmp/grub-install.log.$$
+img_file=/tmp/grub-install.img.$$
 rootdir=
 grub_prefix=/boot/grub
 
 
 # look for secure tempfile creation wrappers on this platform
 if test -x /bin/tempfile; then
-    mkstemp="/bin/tempfile --prefix=grub"
+    mklog="/bin/tempfile --prefix=grub"
+    mkimg="/bin/tempfile --prefix=grub"
 elif test -x /bin/mktemp; then
-    mkstemp="/bin/mktemp /tmp/grub-install.log.XXXXXX"
+    mklog="/bin/mktemp /tmp/grub-install.log.XXXXXX"
+    mkimg="/bin/mktemp /tmp/grub-install.img.XXXXXX"
 else
-    mkstemp=""
+    mklog=""
+    mkimg=""
 fi
 
 # Usage: usage
     :
 else
     # Create a safe temporary file.
-    test -n "$mkstemp" && log_file=`$mkstemp`
+    test -n "$mklog" && log_file=`$mklog`
 
     $grub_shell --batch --device-map=$device_map <<EOF >$log_file
 quit
     cp -f $file ${grubdir} || exit 1
 done
 
+# Make sure that GRUB reads the same images as the host OS.
+test -n "$mkimg" && img_file=`$mkimg`
+test -n "$mklog" && log_file=`$mklog`
+
+for file in ${grubdir}/stage1 ${grubdir}/stage2 ${grubdir}/*stage1_5; do
+    count=5
+    tmp=`echo $file | sed "s|^${grubdir}|${grub_prefix}|"`
+    while test $count -gt 0; do
+       $grub_shell --batch --device-map=$device_map <<EOF >$log_file
+dump ${root_drive}${tmp} ${img_file}
+quit
+EOF
+       if grep "Error [0-9]*: " $log_file >/dev/null; then
+           :
+       elif cmp $file $img_file >/dev/null; then
+           break
+       fi
+       sleep 1
+       count=`expr $count - 1`    
+    done
+    if test $count -eq 0; then
+       echo "The file $file not read correctly." 1>&2
+       exit 1
+    fi
+done
+
+rm -f $img_file
+rm -f $log_file
+
 # Create a safe temporary file.
-test -n "$mkstemp" && log_file=`$mkstemp`
+test -n "$mklog" && log_file=`$mklog`
 
 # Now perform the installation.
 $grub_shell --batch --device-map=$device_map <<EOF >$log_file