]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Rewrite grub-install, grub-mkrescue, grub-mkstandalone and grub-mknetdir
authorVladimir Serbinenko <phcoder@gmail.com>
Sat, 16 Nov 2013 19:21:16 +0000 (20:21 +0100)
committerVladimir Serbinenko <phcoder@gmail.com>
Sat, 16 Nov 2013 19:21:16 +0000 (20:21 +0100)
the function of these files exceeds what can be sanely handled in shell
in posix-comaptible way. Also writing it in C extends the functionality
to non-UNIX-like OS and minimal environments.

52 files changed:
ChangeLog
Makefile.am
Makefile.util.def
configure.ac
grub-core/Makefile.am
grub-core/kern/emu/hostdisk.c
grub-core/osdep/aros/config.c [new file with mode: 0644]
grub-core/osdep/aros/hostdisk.c
grub-core/osdep/basic/compress.c [new file with mode: 0644]
grub-core/osdep/basic/init.c
grub-core/osdep/basic/no_platform.c [new file with mode: 0644]
grub-core/osdep/basic/platform.c [new file with mode: 0644]
grub-core/osdep/compress.c [new file with mode: 0644]
grub-core/osdep/config.c [new file with mode: 0644]
grub-core/osdep/linux/platform.c [new file with mode: 0644]
grub-core/osdep/platform.c [new file with mode: 0644]
grub-core/osdep/platform_unix.c [new file with mode: 0644]
grub-core/osdep/unix/compress.c [new file with mode: 0644]
grub-core/osdep/unix/config.c [new file with mode: 0644]
grub-core/osdep/unix/exec.c
grub-core/osdep/unix/hostdisk.c
grub-core/osdep/unix/platform.c [new file with mode: 0644]
grub-core/osdep/windows/config.c [new file with mode: 0644]
grub-core/osdep/windows/hostdisk.c
grub-core/osdep/windows/init.c
include/grub/emu/config.h [new file with mode: 0644]
include/grub/emu/getroot.h
include/grub/emu/hostfile.h
include/grub/osdep/exec_unix.h [new file with mode: 0644]
include/grub/osdep/hostfile_aros.h
include/grub/osdep/hostfile_unix.h
include/grub/osdep/hostfile_windows.h
include/grub/util/install.h
po/Makefile.in.in
po/Rules-windowsdir [new file with mode: 0644]
tests/util/grub-shell.in
util/config.c [new file with mode: 0644]
util/grub-install-common.c [new file with mode: 0644]
util/grub-install.c [new file with mode: 0644]
util/grub-install.in [deleted file]
util/grub-install_header [deleted file]
util/grub-mkimage.c
util/grub-mknetdir.c [new file with mode: 0644]
util/grub-mknetdir.in [deleted file]
util/grub-mkrescue.c [new file with mode: 0644]
util/grub-mkrescue.in [deleted file]
util/grub-mkstandalone.c [new file with mode: 0644]
util/grub-mkstandalone.in [deleted file]
util/grub-probe.c
util/misc.c
util/mkimage.c
util/probe.c [new file with mode: 0644]

index 9b0a85937939959c156d0704d8d78f15092ac740..46be8e6d86157e0226f3415247f30e798761901f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2013-11-16  Andrey Borzenkov <arvidjaar@gmail.com>
+
+       * util/grub-install.c (device_map_check_duplicates): Fix incorrect
+       order of qsort arguments (number of elements vs. element size).
+
+2013-11-16  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Rewrite grub-install, grub-mkrescue, grub-mkstandalone and grub-mknetdir
+       the function of these files exceeds what can be sanely handled in shell
+       in posix-comaptible way. Also writing it in C extends the functionality
+       to non-UNIX-like OS and minimal environments.
+
 2013-11-16  Vladimir Serbinenko  <phcoder@gmail.com>
 
        * grub-core/kern/arm/cache.S: Don't switch back to ARM mode when
index 03ef964919e40af6ac4e030f147febae29755776..114c2004598904db7cec686ab3b049c367e51f0e 100644 (file)
@@ -397,5 +397,27 @@ default_payload.elf: grub-mkstandalone grub-mkimage
        pkgdatadir=. ./grub-mkstandalone --grub-mkimage=./grub-mkimage -O i386-coreboot -o $@ --modules='ahci ehci uhci ohci usb_keyboard usbms part_msdos xfs ext2 fat at_keyboard part_gpt usbserial_usbdebug cbfs' --install-modules='ls linux search configfile normal cbtime cbls memrw iorw minicmd lsmmap lspci halt reboot hexdump pcidump setpci lsacpi chain' --fonts= --themes= --locales= -d grub-core/
 endif
 
+windowsdir=$(top_builddir)/$(PACKAGE)-$(VERSION)-for-windows
+windowsdir: $(PROGRAMS) $(starfield_DATA) $(platform_DATA)
+       test -d $(windowsdir) && rm -rf $(windowsdir) || true
+       test -d $(windowsdir) || mkdir $(windowsdir)
+       $(MAKE) -C po $(AM_MAKEFLAGS) windowsdir
+       $(MAKE) -C grub-core $(AM_MAKEFLAGS) windowsdir
+       test -d $(windowsdir)/themes || mkdir $(windowsdir)/themes
+       test -d $(windowsdir)/themes/starfield || mkdir $(windowsdir)/themes/starfield
+       for x in $(PROGRAMS); do \
+               $(STRIP) $$x -o $(windowsdir)/$$x; \
+       done
+       for x in $(pkgdata_DATA); do \
+               cp -fp $$x $(windowsdir)/$$x; \
+       done
+       for x in $(starfield_DATA); do \
+               cp -fp $$x $(windowsdir)/themes/starfield/$$(basename $$x); \
+       done
+
+windowszip=$(top_builddir)/$(PACKAGE)-$(VERSION)-for-windows.zip
+windowszip: windowsdir
+       test -f $(windowszip) && rm $(windowszip) || true
+       zip -r $(windowszip) $(windowsdir)
 
 EXTRA_DIST += linguas.sh
index f2a305fd31c762ab72a6b0263fdae48f2f788286..ede74687e3286bd5bdec6e245885015cccfd0e9f 100644 (file)
@@ -171,6 +171,10 @@ program = {
   common = util/resolve.c;
   common = grub-core/kern/emu/argp_common.c;
   common = grub-core/osdep/init.c;
+  common = grub-core/osdep/config.c;
+  extra_dist = grub-core/osdep/windows/config.c;
+  extra_dist = grub-core/osdep/unix/config.c;
+  common = util/config.c;
 
   common = grub-core/kern/arm/dl_helper.c;
 
@@ -310,6 +314,7 @@ program = {
   installdir = sbin;
   mansection = 8;
   common = util/grub-probe.c;
+  common = util/probe.c;
   common = grub-core/osdep/ofpath.c;
   common = grub-core/kern/emu/argp_common.c;
   common = grub-core/osdep/init.c;
@@ -479,38 +484,165 @@ script = {
   installdir = grubconf;
 };
 
-script = {
+program = {
   mansection = 1;
   name = grub-mkrescue;
-  common = util/grub-install_header;
-  common = util/grub-mkrescue.in;
-  enable = noemu;
+
+  common = util/grub-mkrescue.c;
+  common = util/render-label.c;
+  common = util/glue-efi.c;
+  common = util/mkimage.c;
+  common = util/grub-install-common.c;
+  common = util/setup_bios.c;
+  common = util/setup_sparc.c;
+  common = grub-core/lib/reed_solomon.c;
+  common = grub-core/osdep/random.c;
+  common = grub-core/osdep/ofpath.c;
+  common = grub-core/osdep/platform.c;
+  common = grub-core/osdep/platform_unix.c;
+  common = grub-core/osdep/compress.c;
+  extra_dist = grub-core/osdep/unix/compress.c;
+  extra_dist = grub-core/osdep/basic/compress.c;
+  common = util/editenv.c;
+  common = grub-core/osdep/blocklist.c;
+  common = grub-core/osdep/config.c;
+  common = util/config.c;
+
+  common = grub-core/kern/emu/hostfs.c;
+  common = grub-core/disk/host.c;
+
+  common = grub-core/kern/arm/dl_helper.c;
+
+  common = util/resolve.c;
+
+  common = grub-core/kern/emu/argp_common.c;
+  common = grub-core/osdep/init.c;
+
+  ldadd = '$(LIBLZMA)';
+  ldadd = libgrubmods.a;
+  ldadd = libgrubgcry.a;
+  ldadd = libgrubkern.a;
+  ldadd = grub-core/gnulib/libgnu.a;
+  ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
+
+  condition = COND_HAVE_EXEC;
 };
 
-script = {
+program = {
   mansection = 1;
   name = grub-mkstandalone;
-  common = util/grub-install_header;
-  common = util/grub-mkstandalone.in;
+  common = util/grub-mkstandalone.c;
+
+  common = util/render-label.c;
+  common = util/glue-efi.c;
+  common = util/mkimage.c;
+  common = util/grub-install-common.c;
+  common = util/setup_bios.c;
+  common = util/setup_sparc.c;
+  common = grub-core/lib/reed_solomon.c;
+  common = grub-core/osdep/random.c;
+  common = grub-core/osdep/ofpath.c;
+  common = grub-core/osdep/platform.c;
+  common = grub-core/osdep/platform_unix.c;
+  extra_dist = grub-core/osdep/linux/platform.c;
+  extra_dist = grub-core/osdep/basic/platform.c;
+  extra_dist = grub-core/osdep/basic/no_platform.c;
+  extra_dist = grub-core/osdep/unix/platform.c;
+  common = grub-core/osdep/compress.c;
+  common = util/editenv.c;
+  common = grub-core/osdep/blocklist.c;
+  common = grub-core/osdep/config.c;
+  common = util/config.c;
+
+  common = grub-core/kern/emu/hostfs.c;
+  common = grub-core/disk/host.c;
+
+  common = grub-core/kern/arm/dl_helper.c;
+
+  common = util/resolve.c;
+
+  common = grub-core/kern/emu/argp_common.c;
+  common = grub-core/osdep/init.c;
+
+  ldadd = '$(LIBLZMA)';
+  ldadd = libgrubmods.a;
+  ldadd = libgrubgcry.a;
+  ldadd = libgrubkern.a;
+  ldadd = grub-core/gnulib/libgnu.a;
+  ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
 };
 
-script = {
+program = {
   mansection = 8;
   installdir = sbin;
   name = grub-install;
 
-  common = util/grub-install_header;
-  common = util/grub-install.in;
+  common = util/grub-install.c;
+  common = util/probe.c;
+  common = util/mkimage.c;
+  common = util/grub-install-common.c;
+  common = util/setup_bios.c;
+  common = util/setup_sparc.c;
+  common = grub-core/lib/reed_solomon.c;
+  common = grub-core/osdep/random.c;
+  common = grub-core/osdep/ofpath.c;
+  common = grub-core/osdep/platform.c;
+  common = grub-core/osdep/platform_unix.c;
+  common = grub-core/osdep/compress.c;
+  common = util/editenv.c;
+  common = grub-core/osdep/blocklist.c;
+  common = grub-core/osdep/config.c;
+  common = util/config.c;
+
+  common = grub-core/kern/arm/dl_helper.c;
+
+  common = util/resolve.c;
   enable = noemu;
+  common = grub-core/kern/emu/argp_common.c;
+  common = grub-core/osdep/init.c;
+
+  ldadd = '$(LIBLZMA)';
+  ldadd = libgrubmods.a;
+  ldadd = libgrubgcry.a;
+  ldadd = libgrubkern.a;
+  ldadd = grub-core/gnulib/libgnu.a;
+  ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
 };
 
-script = {
+program = {
   mansection = 1;
   installdir = bin;
   name = grub-mknetdir;
 
-  common = util/grub-install_header;
-  common = util/grub-mknetdir.in;
+  common = util/grub-mknetdir.c;
+
+  common = util/mkimage.c;
+  common = util/grub-install-common.c;
+  common = util/setup_bios.c;
+  common = util/setup_sparc.c;
+  common = grub-core/lib/reed_solomon.c;
+  common = grub-core/osdep/random.c;
+  common = grub-core/osdep/ofpath.c;
+  common = grub-core/osdep/platform.c;
+  common = grub-core/osdep/platform_unix.c;
+  common = grub-core/osdep/compress.c;
+  common = util/editenv.c;
+  common = grub-core/osdep/blocklist.c;
+  common = grub-core/osdep/config.c;
+  common = util/config.c;
+
+  common = grub-core/kern/arm/dl_helper.c;
+
+  common = util/resolve.c;
+  common = grub-core/kern/emu/argp_common.c;
+  common = grub-core/osdep/init.c;
+
+  ldadd = '$(LIBLZMA)';
+  ldadd = libgrubmods.a;
+  ldadd = libgrubgcry.a;
+  ldadd = libgrubkern.a;
+  ldadd = grub-core/gnulib/libgnu.a;
+  ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
 };
 
 script = {
index 18429103b55583c5d5518aae0bb6d82e13d79745..9f8fb8a35b18472ff93caa13b7287401c38e201e 100644 (file)
@@ -75,14 +75,10 @@ if test "x$TARGET_CFLAGS" = x; then
   TARGET_CFLAGS="$TARGET_CFLAGS -Os"
 fi
 
-BUILD_CPPFLAGS="$BUILD_CPPFLAGS -DLOCALEDIR=\\\"\$(localedir)\\\""
-
 # Default HOST_CPPFLAGS
 HOST_CPPFLAGS="$HOST_CPPFLAGS -Wall -W"
 HOST_CPPFLAGS="$HOST_CPPFLAGS -I\$(top_builddir)/include"
 HOST_CPPFLAGS="$HOST_CPPFLAGS -DGRUB_UTIL=1"
-HOST_CPPFLAGS="$HOST_CPPFLAGS -DGRUB_LIBDIR=\\\"\$(pkglibdir)\\\""
-HOST_CPPFLAGS="$HOST_CPPFLAGS -DLOCALEDIR=\\\"\$(localedir)\\\""
 
 TARGET_CPPFLAGS="$TARGET_CPPFLAGS -Wall -W"
 TARGET_CPPFLAGS="$TARGET_CPPFLAGS -I\$(top_srcdir)/include"
@@ -192,6 +188,12 @@ case "$host_os" in
   cygwin | windows* | mingw32*)        host_kernel=windows ;;
 esac
 
+case "$host_os" in
+  cygwin | windows* | mingw32*)        have_exec=n ;;
+  aros*) have_exec=n ;;
+  *) have_exec=y;;
+esac
+
 case "$platform" in
   coreboot)    machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_COREBOOT=1" ;;
   multiboot)   machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MULTIBOOT=1" ;;
@@ -1458,6 +1460,20 @@ AM_CONDITIONAL([COND_HAVE_CXX], [test x$HAVE_CXX = xyes])
 AM_CONDITIONAL([COND_HAVE_ASM_USCORE], [test x$HAVE_ASM_USCORE = x1])
 AM_CONDITIONAL([COND_CYGWIN], [test x$target_os = xcygwin])
 AM_CONDITIONAL([COND_STARFIELD], [test "x$starfield_excuse" = x])
+AM_CONDITIONAL([COND_HAVE_EXEC], [test "x$have_exec" = xy])
+
+test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+datarootdir="$(eval echo "$datarootdir")"
+grub_libdir="$(eval echo "$libdir")"
+grub_localedir="$(eval echo "$localedir")"
+grub_datadir="$(eval echo "$datadir")"
+grub_sysconfdir="$(eval echo "$sysconfdir")"
+AC_DEFINE_UNQUOTED(LOCALEDIR, "$grub_localedir", [Locale dir])
+AC_DEFINE_UNQUOTED(GRUB_LIBDIR, "$grub_libdir", [Library dir])
+AC_DEFINE_UNQUOTED(GRUB_DATADIR, "$grub_datadir", [Data dir])
+AC_DEFINE_UNQUOTED(GRUB_SYSCONFDIR, "$grub_sysconfdir", [Configuration dir])
+
 
 # Output files.
 cpudir="${target_cpu}"
index 025bbded395b4503d0aa60b936afefa55d7eed5d..151b9339a5b8207b09d7adc42a700fc60bedb1b8 100644 (file)
@@ -428,3 +428,10 @@ efiemu64.o: efiemu64_c.o efiemu64_s.o $(TARGET_OBJ2ELEF)
 platform_DATA += efiemu32.o efiemu64.o
 CLEANFILES += efiemu32.o efiemu64.o efiemu64_c.o efiemu64_s.o
 endif
+
+windowsdir=$(top_builddir)/$(PACKAGE)-$(VERSION)-for-windows
+windowsdir: $(PROGRAMS) $(starfield_DATA) $(platform_DATA)
+       test -d $(windowsdir)/$(target_cpu)-$(platform) || mkdir $(windowsdir)/$(target_cpu)-$(platform)
+       for x in $(platform_DATA); do \
+               cp -fp $$x $(windowsdir)/$(target_cpu)-$(platform)/$$x; \
+       done
index e00c8fbed67c4d57e5ad4d814cf970e8c63ed564..08ae65478db56b91e64adbe3a9980879bc7cff9d 100644 (file)
@@ -609,3 +609,78 @@ grub_util_biosdisk_get_osdev (grub_disk_t disk)
 
   return map[disk->id].device;
 }
+
+
+static char *
+grub_util_path_concat_real (size_t n, int ext, va_list ap)
+{
+  size_t totlen = 0;
+  char **l = xmalloc ((n + ext) * sizeof (l[0]));
+  char *r, *p, *pi;
+  size_t i;
+  int first = 1;
+
+  for (i = 0; i < n + ext; i++)
+    {
+      l[i] = va_arg (ap, char *);
+      if (l[i])
+       totlen += strlen (l[i]) + 1;
+    }
+
+  r = xmalloc (totlen + 10);
+
+  p = r;
+  for (i = 0; i < n; i++)
+    {
+      pi = l[i];
+      if (!pi)
+       continue;
+      while (*pi == '/')
+       pi++;
+      if ((p != r || (pi != l[i] && first)) && (p == r || *(p - 1) != '/'))
+       *p++ = '/';
+      first = 0;
+      p = grub_stpcpy (p, pi);
+      while (p != r && p != r + 1 && *(p - 1) == '/')
+       p--;
+    }
+
+  if (ext && l[i])
+    p = grub_stpcpy (p, l[i]);
+
+  *p = '\0';
+
+  free (l);
+
+  return r;
+}
+
+char *
+grub_util_path_concat (size_t n, ...)
+{
+  va_list ap;
+  char *r;
+
+  va_start (ap, n);
+
+  r = grub_util_path_concat_real (n, 0, ap);
+
+  va_end (ap);
+
+  return r;
+}
+
+char *
+grub_util_path_concat_ext (size_t n, ...)
+{
+  va_list ap;
+  char *r;
+
+  va_start (ap, n);
+
+  r = grub_util_path_concat_real (n, 1, ap);
+
+  va_end (ap);
+
+  return r;
+}
diff --git a/grub-core/osdep/aros/config.c b/grub-core/osdep/aros/config.c
new file mode 100644 (file)
index 0000000..99f3009
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013  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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <config-util.h>
+
+#include <grub/emu/hostdisk.h>
+#include <grub/emu/exec.h>
+#include <grub/emu/config.h>
+#include <grub/util/install.h>
+#include <grub/util/misc.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <stdlib.h>
+
+const char *
+grub_util_get_config_filename (void)
+{
+  static char *value = NULL;
+  if (!value)
+    value = grub_util_path_concat (3, GRUB_SYSCONFDIR,
+                                  "default", "grub");
+  return value;
+}
+
+const char *
+grub_util_get_pkgdatadir (void)
+{
+  const char *ret = getenv ("pkgdatadir");
+  if (ret)
+    return ret;
+  return GRUB_DATADIR "/" PACKAGE;
+}
+
+const char *
+grub_util_get_pkglibdir (void)
+{
+  return GRUB_LIBDIR "/" PACKAGE;
+}
+
+const char *
+grub_util_get_localedir (void)
+{
+  return LOCALEDIR;
+}
+
+void
+grub_util_load_config (struct grub_util_config *cfg)
+{
+  const char *cfgfile;
+  FILE *f = NULL;
+  const char *v;
+
+  memset (cfg, 0, sizeof (*cfg));
+
+  v = getenv ("GRUB_ENABLE_CRYPTODISK");
+  if (v && v[0] == 'y' && v[1] == '\0')
+    cfg->is_cryptodisk_enabled = 1;
+
+  v = getenv ("GRUB_DISTRIBUTOR");
+  if (v)
+    cfg->grub_distributor = xstrdup (v);
+
+  cfgfile = grub_util_get_config_filename ();
+  if (!grub_util_is_regular (cfgfile))
+    return;
+
+  f = grub_util_fopen (cfgfile, "r");
+  if (f)
+    {
+      grub_util_parse_config (f, cfg, 0);
+      fclose (f);
+    }
+  else
+    grub_util_warn (_("cannot open config file `%s': %s"),
+                   cfgfile, strerror (errno));
+}
index 3fe442cf59f504f80f4a6e4fea52177804d8e1ec..9c0a6c895e8840919d09b3bb75778cdb222a5cbe 100644 (file)
@@ -41,6 +41,7 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <limits.h>
+#include <time.h>
 
 #include <string.h>
 #include <dos/dos.h>
@@ -516,6 +517,17 @@ grub_util_is_directory (const char *path)
   return S_ISDIR (st.st_mode);
 }
 
+int
+grub_util_is_regular (const char *path)
+{
+  struct stat st;
+
+  if (stat (path, &st) == -1)
+    return 0;
+
+  return S_ISREG (st.st_mode);
+}
+
 int
 grub_util_is_special_file (const char *path)
 {
@@ -525,3 +537,53 @@ grub_util_is_special_file (const char *path)
     return 1;
   return (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode));
 }
+
+static char *
+get_temp_name (void)
+{
+  static int ctr = 0;
+  char *t;
+  struct stat st;
+  
+  while (1)
+    {
+      t = xasprintf ("T:grub.%d.%d.%d.%d", (int) getpid (), (int) getppid (),
+                    ctr++, time (0));
+      if (stat (t, &st) == -1)
+       return t;
+      free (t);
+    }
+}
+
+char *
+grub_util_make_temporary_file (void)
+{
+  char *ret = get_temp_name ();
+  FILE *f;
+
+  f = grub_util_fopen (ret, "wb");
+  if (f)
+    fclose (f);
+  return ret;
+}
+
+char *
+grub_util_make_temporary_dir (void)
+{
+  char *ret = get_temp_name ();
+
+  grub_util_mkdir (ret);
+
+  return ret;
+}
+
+grub_uint32_t
+grub_util_get_mtime (const char *path)
+{
+  struct stat st;
+
+  if (stat (path, &st) == -1)
+    return 0;
+
+  return st.st_mtime;
+}
diff --git a/grub-core/osdep/basic/compress.c b/grub-core/osdep/basic/compress.c
new file mode 100644 (file)
index 0000000..463ce42
--- /dev/null
@@ -0,0 +1,21 @@
+#include <config.h>
+#include <grub/util/install.h>
+#include <grub/util/misc.h>
+
+int 
+grub_install_compress_gzip (const char *src, const char *dest)
+{
+  grub_util_error ("no compression is available for your platform");
+}
+
+int 
+grub_install_compress_xz (const char *src, const char *dest)
+{
+  grub_util_error ("no compression is available for your platform");
+}
+
+int 
+grub_install_compress_lzop (const char *src, const char *dest)
+{
+  grub_util_error ("no compression is available for your platform");
+}
index f4a673b649c901e92cb9cd3ab170b86acf60030c..c54c710dbcb188fee09c37aaf6648786c833b8e2 100644 (file)
@@ -20,6 +20,7 @@
 #include <config-util.h>
 
 #include <grub/util/misc.h>
+#include <grub/i18n.h>
 
 #include "progname.h"
 
@@ -29,7 +30,9 @@ grub_util_host_init (int *argc __attribute__ ((unused)),
 {
   set_program_name ((*argv)[0]);
 
-#ifdef GRUB_UTIL
-  grub_util_init_nls ();
-#endif
+#if (defined (GRUB_UTIL) && defined(ENABLE_NLS) && ENABLE_NLS)
+  setlocale (LC_ALL, "");
+  bindtextdomain (PACKAGE, LOCALEDIR);
+  textdomain (PACKAGE);
+#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */
 }
diff --git a/grub-core/osdep/basic/no_platform.c b/grub-core/osdep/basic/no_platform.c
new file mode 100644 (file)
index 0000000..32be5e8
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/emu/misc.h>
+#include <grub/util/install.h>
+#include <grub/util/misc.h>
+
+#include "platform.c"
+
+void
+grub_install_register_ieee1275 (int is_prep, const char *install_device,
+                               int partno, const char *relpath)
+{
+  grub_util_error ("%s", "no IEEE1275 routines are available for your platform");
+}
+
+void
+grub_install_register_efi (const char *efidir_disk, int efidir_part,
+                          const char *efifile_path,
+                          const char *efi_distributor)
+{
+  grub_util_error ("%s", "no EFI routines are available for your platform");
+}
+
+void
+grub_install_sgi_setup (const char *install_device,
+                       const char *imgfile, const char *destname)
+{
+  grub_util_error ("%s", "no SGI routines are available for your platform");
+}
diff --git a/grub-core/osdep/basic/platform.c b/grub-core/osdep/basic/platform.c
new file mode 100644 (file)
index 0000000..4b5502a
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/util/install.h>
+
+const char *
+grub_install_get_default_x86_platform (void)
+{ 
+  return "i386-pc";
+}
+
diff --git a/grub-core/osdep/compress.c b/grub-core/osdep/compress.c
new file mode 100644 (file)
index 0000000..cc808d0
--- /dev/null
@@ -0,0 +1,5 @@
+#if !defined (__MINGW32__) && !defined (__CYGWIN__) && !defined (__AROS__)
+#include "unix/compress.c"
+#else
+#include "basic/compress.c"
+#endif
diff --git a/grub-core/osdep/config.c b/grub-core/osdep/config.c
new file mode 100644 (file)
index 0000000..b9f7819
--- /dev/null
@@ -0,0 +1,7 @@
+#if defined (__MINGW32__) && !defined (__CYGWIN__)
+#include "windows/config.c"
+#elif defined (__AROS__)
+#include "aros/config.c"
+#else
+#include "unix/config.c"
+#endif
diff --git a/grub-core/osdep/linux/platform.c b/grub-core/osdep/linux/platform.c
new file mode 100644 (file)
index 0000000..ec67aad
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <grub/util/install.h>
+#include <grub/emu/exec.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <string.h>
+
+#include <sys/utsname.h>
+
+static int
+is_not_empty_directory (const char *dir)
+{
+  DIR *d;
+  struct dirent *de;
+
+  d = opendir (dir);
+  if (!d)
+    return 0;
+  while ((de = readdir (d)))
+    {
+      if (strcmp (de->d_name, ".") == 0
+         || strcmp (de->d_name, "..") == 0)
+       continue;
+      closedir (d);
+      return 1;
+    }
+
+  closedir (d);
+  return 0;
+}
+
+static int
+is_64_kernel (void)
+{
+  struct utsname un;
+
+  if (uname (&un) < 0)
+    return 0;
+
+  return strcmp (un.machine, "x86_64") == 0;
+}
+
+const char *
+grub_install_get_default_x86_platform (void)
+{ 
+  /*
+     On Linux, we need the efivars kernel modules.
+     If no EFI is available this module just does nothing
+     besides a small hello and if we detect efi we'll load it
+     anyway later. So it should be safe to
+     try to load it here.
+   */
+  grub_util_exec ((const char * []){ "modprobe", "-q",
+       "efivars", NULL });
+  if (is_not_empty_directory ("/sys/firmware/efi"))
+    {
+      if (is_64_kernel ())
+       return "x86_64-efi";
+      else
+       return "i386-efi";
+    }
+  else if (is_not_empty_directory ("/proc/device-tree"))
+    return "i386-ieee1275";
+  else
+    return "i386-pc";
+}
diff --git a/grub-core/osdep/platform.c b/grub-core/osdep/platform.c
new file mode 100644 (file)
index 0000000..f720264
--- /dev/null
@@ -0,0 +1,7 @@
+#ifdef __linux__
+#include "linux/platform.c"
+#elif defined (__MINGW32__) || defined (__CYGWIN__) || defined (__AROS__)
+#include "basic/no_platform.c"
+#else
+#include "basic/platform.c"
+#endif
diff --git a/grub-core/osdep/platform_unix.c b/grub-core/osdep/platform_unix.c
new file mode 100644 (file)
index 0000000..db6a02d
--- /dev/null
@@ -0,0 +1,3 @@
+#if !defined (__MINGW32__) && !defined (__CYGWIN__) && !defined (__AROS__)
+#include "unix/platform.c"
+#endif
diff --git a/grub-core/osdep/unix/compress.c b/grub-core/osdep/unix/compress.c
new file mode 100644 (file)
index 0000000..dee5620
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/emu/exec.h>
+#include <grub/util/install.h>
+
+int 
+grub_install_compress_gzip (const char *src, const char *dest)
+{
+  return grub_util_exec_redirect ((const char * []) { "gzip", "--best",
+       "--stdout", NULL }, src, dest);
+}
+
+int 
+grub_install_compress_xz (const char *src, const char *dest)
+{
+  return grub_util_exec_redirect ((const char * []) { "xz",
+       "--lzma2=dict=128KiB", "--check=none", "--stdout", NULL }, src, dest);
+}
+
+int 
+grub_install_compress_lzop (const char *src, const char *dest)
+{
+  return grub_util_exec_redirect ((const char * []) { "lzop", "-9",  "-c",
+       NULL }, src, dest);
+}
diff --git a/grub-core/osdep/unix/config.c b/grub-core/osdep/unix/config.c
new file mode 100644 (file)
index 0000000..c093e91
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013  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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <config-util.h>
+
+#include <grub/emu/hostdisk.h>
+#include <grub/emu/exec.h>
+#include <grub/emu/config.h>
+#include <grub/util/install.h>
+#include <grub/util/misc.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <stdlib.h>
+
+const char *
+grub_util_get_config_filename (void)
+{
+  static char *value = NULL;
+  if (!value)
+    value = grub_util_path_concat (3, GRUB_SYSCONFDIR,
+                                  "default", "grub");
+  return value;
+}
+
+const char *
+grub_util_get_pkgdatadir (void)
+{
+  const char *ret = getenv ("pkgdatadir");
+  if (ret)
+    return ret;
+  return GRUB_DATADIR "/" PACKAGE;
+}
+
+const char *
+grub_util_get_pkglibdir (void)
+{
+  return GRUB_LIBDIR "/" PACKAGE;
+}
+
+const char *
+grub_util_get_localedir (void)
+{
+  return LOCALEDIR;
+}
+
+void
+grub_util_load_config (struct grub_util_config *cfg)
+{
+  pid_t pid;
+  const char *argv[4];
+  char *script, *ptr;
+  const char *cfgfile, *iptr;
+  FILE *f = NULL;
+  int fd;
+  const char *v;
+
+  memset (cfg, 0, sizeof (*cfg));
+
+  v = getenv ("GRUB_ENABLE_CRYPTODISK");
+  if (v && v[0] == 'y' && v[1] == '\0')
+    cfg->is_cryptodisk_enabled = 1;
+
+  v = getenv ("GRUB_DISTRIBUTOR");
+  if (v)
+    cfg->grub_distributor = xstrdup (v);
+
+  cfgfile = grub_util_get_config_filename ();
+  if (!grub_util_is_regular (cfgfile))
+    return;
+
+  argv[0] = "sh";
+  argv[1] = "-c";
+
+  script = xmalloc (4 * strlen (cfgfile) + 300);
+
+  ptr = script;
+  memcpy (ptr, ". '", 3);
+  ptr += 3;
+  for (iptr = cfgfile; *iptr; iptr++)
+    {
+      if (*iptr == '\\')
+       {
+         memcpy (ptr, "'\\''", 4);
+         ptr += 4;
+         continue;
+       }
+      *ptr++ = *iptr;
+    }
+
+  strcpy (ptr, "'; printf \"GRUB_ENABLE_CRYPTODISK=%s\\nGRUB_DISTRIBUTOR=%s\\n\", "
+         "\"$GRUB_ENABLE_CRYPTODISK\", \"$GRUB_DISTRIBUTOR\"");
+
+  argv[2] = script;
+  argv[3] = '\0';
+
+  pid = grub_util_exec_pipe (argv, &fd);
+  if (pid)
+    f = fdopen (fd, "r");
+  if (f)
+    {
+      grub_util_parse_config (f, cfg, 1);
+      fclose (f);
+    }
+  if (pid)
+    {
+      close (fd);
+      waitpid (pid, NULL, 0);
+    }
+  if (f)
+    return;
+
+  f = grub_util_fopen (cfgfile, "r");
+  if (f)
+    {
+      grub_util_parse_config (f, cfg, 0);
+      fclose (f);
+    }
+  else
+    grub_util_warn (_("cannot open config file `%s': %s"),
+                   cfgfile, strerror (errno));
+}
index 239a68b32e836d113dae2c48d95b3709aec7fcef..9a50e5b9fa98a283c770fbfeced11f5cb851df10 100644 (file)
@@ -38,6 +38,23 @@ grub_util_exec (const char *const *argv)
 {
   pid_t pid;
   int status = -1;
+  char *str, *pstr;
+  const char *const *ptr;
+  grub_size_t strl = 0;
+  for (ptr = argv; *ptr; ptr++)
+    strl += grub_strlen (*ptr) + 1;
+  pstr = str = xmalloc (strl);
+  for (ptr = argv; *ptr; ptr++)
+    {
+      pstr = grub_stpcpy (pstr, *ptr);
+      *pstr++ = ' ';
+    }
+  if (pstr > str)
+    pstr--;
+  *pstr = '\0';
+
+  grub_util_info ("executing %s", str);
+  grub_free (str);
 
   pid = fork ();
   if (pid < 0)
@@ -71,6 +88,29 @@ grub_util_exec_redirect (const char *const *argv, const char *stdin_file,
 {
   pid_t mdadm_pid;
   int status = -1;
+  char *str, *pstr;
+  const char *const *ptr;
+  grub_size_t strl = 0;
+  for (ptr = argv; *ptr; ptr++)
+    strl += grub_strlen (*ptr) + 1;
+  strl += grub_strlen (stdin_file) + 2;
+  strl += grub_strlen (stdout_file) + 2;
+
+  pstr = str = xmalloc (strl);
+  for (ptr = argv; *ptr; ptr++)
+    {
+      pstr = grub_stpcpy (pstr, *ptr);
+      *pstr++ = ' ';
+    }
+  *pstr++ = '<';
+  pstr = grub_stpcpy (pstr, stdin_file);
+  *pstr++ = ' ';
+  *pstr++ = '>';
+  pstr = grub_stpcpy (pstr, stdout_file);
+  *pstr = '\0';
+
+  grub_util_info ("executing %s", str);
+  grub_free (str);
 
   mdadm_pid = fork ();
   if (mdadm_pid < 0)
@@ -87,6 +127,8 @@ grub_util_exec_redirect (const char *const *argv, const char *stdin_file,
 #endif
 
       in = open (stdin_file, O_RDONLY);
+      if (in < 0)
+       exit (127);
       dup2 (in, STDIN_FILENO);
       close (in);
 
@@ -94,6 +136,9 @@ grub_util_exec_redirect (const char *const *argv, const char *stdin_file,
       dup2 (out, STDOUT_FILENO);
       close (out);
 
+      if (out < 0)
+       exit (127);
+
       /* Ensure child is not localised.  */
       setenv ("LC_ALL", "C", 1);
 
index fe87855e21ffb44dc5fcebcca8f84ac73df14321..1ca1abbfb45435ed2788efb4cafc3ade8036d5d0 100644 (file)
@@ -246,6 +246,17 @@ grub_util_is_regular (const char *path)
   return S_ISREG (st.st_mode);
 }
 
+grub_uint32_t
+grub_util_get_mtime (const char *path)
+{
+  struct stat st;
+
+  if (stat (path, &st) == -1)
+    return 0;
+
+  return st.st_mtime;
+}
+
 int
 grub_util_is_special_file (const char *path)
 {
@@ -256,4 +267,39 @@ grub_util_is_special_file (const char *path)
   return (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode));
 }
 
+
+char *
+grub_util_make_temporary_file (void)
+{
+  const char *t = getenv ("TMPDIR");
+  size_t tl;
+  char *tmp;
+  if (!t)
+    t = "/tmp";
+  tl = strlen (t);
+  tmp = xmalloc (tl + sizeof ("/grub.XXXXXX"));
+  memcpy (tmp, t, tl);
+  memcpy (tmp + tl, "/grub.XXXXXX",
+         sizeof ("/grub.XXXXXX"));
+  mkstemp (tmp);
+  return tmp;
+}
+
+char *
+grub_util_make_temporary_dir (void)
+{
+  const char *t = getenv ("TMPDIR");
+  size_t tl;
+  char *tmp;
+  if (!t)
+    t = "/tmp";
+  tl = strlen (t);
+  tmp = xmalloc (tl + sizeof ("/grub.XXXXXX"));
+  memcpy (tmp, t, tl);
+  memcpy (tmp + tl, "/grub.XXXXXX",
+         sizeof ("/grub.XXXXXX"));
+  mkdtemp (tmp);
+  return tmp;
+}
+
 #endif
diff --git a/grub-core/osdep/unix/platform.c b/grub-core/osdep/unix/platform.c
new file mode 100644 (file)
index 0000000..65c93f1
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <grub/util/install.h>
+#include <grub/util/misc.h>
+#include <grub/misc.h>
+#include <grub/i18n.h>
+#include <grub/emu/exec.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <string.h>
+#include <errno.h>
+
+static char *
+get_ofpathname (const char *dev)
+{
+  char *ret = xmalloc (2 * PATH_MAX);
+  char *end = ret + 2 * PATH_MAX - 1;
+  int fd;
+  pid_t pid;
+  char *ptr = ret;
+
+  pid = grub_util_exec_pipe ((const char * []){ "ofpathname", dev, NULL }, &fd);
+  if (!pid)
+    goto fail;
+
+  FILE *fp = fdopen (fd, "r");
+  if (!fp)
+    goto fail;
+
+  while (!feof (fp) && ptr < end)
+    {
+      size_t r;
+      r = fread (ptr, 1, end - ptr, fp);
+      ptr += r;
+    }
+
+  fclose (fp);
+
+  return ret;
+
+ fail:
+  grub_util_error (_("couldn't find IEEE1275 device tree path for %s.\nYou will have to set `boot-device' variable manually"),
+                  dev);
+}
+
+static void
+grub_install_remove_efi_entries_by_distributor (const char *efi_distributor)
+{
+  int fd;
+  pid_t pid = grub_util_exec_pipe ((const char * []){ "efibootmgr", NULL }, &fd);
+  char *line = NULL;
+  size_t len = 0;
+
+  if (!pid)
+    {
+      grub_util_warn (_("Unable to open stream from %s: %s"),
+                     "efibootmgr", strerror (errno));
+      return;
+    }
+
+  FILE *fp = fdopen (fd, "r");
+  if (!fp)
+    {
+      grub_util_warn (_("Unable to open stream from %s: %s"),
+                     "efibootmgr", strerror (errno));
+      return;
+    }
+
+  line = xmalloc (80);
+  len = 80;
+  while (1)
+    {
+      int ret;
+      char *bootnum;
+      ret = getline (&line, &len, fp);
+      if (ret == -1)
+       break;
+      if (grub_memcmp (line, "Boot", sizeof ("Boot") - 1) != 0
+         || line[sizeof ("Boot") - 1] < '0'
+         || line[sizeof ("Boot") - 1] > '9')
+       continue;
+      if (!strcasestr (line, efi_distributor))
+       continue;
+      bootnum = line + sizeof ("Boot") - 1;
+      bootnum[4] = '\0';
+      if (!verbosity)
+       grub_util_exec ((const char * []){ "efibootmgr", "-q",
+             "-b", bootnum,  "-B", NULL });
+      else
+       grub_util_exec ((const char * []){ "efibootmgr",
+             "-b", bootnum, "-B", NULL });
+    }
+
+  free (line);
+}
+
+void
+grub_install_register_efi (const char *efidir_disk, int efidir_part,
+                          const char *efifile_path,
+                          const char *efi_distributor)
+{
+  if (grub_util_exec_redirect_null ((const char * []){ "efibootmgr", "--version", NULL }))
+    {
+      /* TRANSLATORS: This message is shown when required executable `%s'
+        isn't found.  */
+      grub_util_error (_("%s: not found"), "efibootmgr");
+    }
+
+  /* On Linux, we need the efivars kernel modules.  */
+#ifdef __linux__
+  grub_util_exec ((const char * []){ "modprobe", "-q", "efivars", NULL });
+#endif
+  /* Delete old entries from the same distributor.  */
+  grub_install_remove_efi_entries_by_distributor (efi_distributor);
+
+  char *efidir_part_str = xasprintf ("%d", efidir_part);
+
+  if (!verbosity)
+    grub_util_exec ((const char * []){ "efibootmgr", "-q",
+         "-c", "-d", efidir_disk,
+         "-p", efidir_part_str, "-w",
+         "-L", efi_distributor, "-l", 
+         efifile_path, NULL });
+  else
+    grub_util_exec ((const char * []){ "efibootmgr",
+         "-c", "-d", efidir_disk,
+         "-p", efidir_part_str, "-w",
+         "-L", efi_distributor, "-l", 
+         efifile_path, NULL });
+  free (efidir_part_str);
+}
+
+void
+grub_install_register_ieee1275 (int is_prep, const char *install_device,
+                               int partno, const char *relpath)
+{
+  char *boot_device;
+
+  if (grub_util_exec_redirect_null ((const char * []){ "ofpathname", "--version", NULL }))
+    {
+      /* TRANSLATORS: This message is shown when required executable `%s'
+        isn't found.  */
+      grub_util_error (_("%s: not found"), "ofpathname");
+    }
+
+  /* Get the Open Firmware device tree path translation.  */
+  if (!is_prep)
+    {
+      char *ptr;
+      char *ofpath;
+      const char *iptr;
+
+      ofpath = get_ofpathname (install_device);
+      boot_device = xmalloc (strlen (ofpath) + 1
+                            + sizeof ("XXXXXXXXXXXXXXXXXXXX")
+                            + 1 + strlen (relpath) + 1);
+      ptr = grub_stpcpy (boot_device, ofpath);
+      *ptr++ = ':';
+      grub_snprintf (ptr, sizeof ("XXXXXXXXXXXXXXXXXXXX"), "%d",
+                    partno);
+      ptr += strlen (ptr);
+      *ptr++ = ',';
+      for (iptr = relpath; *iptr; iptr++, ptr++)
+       {
+         if (*iptr == '/')
+           *ptr = '\\';
+         else
+           *ptr = *iptr;
+       }
+      *ptr = '\0';
+    }
+  else
+    boot_device = get_ofpathname (install_device);
+
+  if (grub_util_exec ((const char * []){ "nvsetenv", "boot-device",
+         boot_device, NULL }))
+    {
+      char *cmd = xasprintf ("setenv boot-device %s", boot_device);
+      grub_util_error ("`nvsetenv' failed. \nYou will have to set `boot-device' variable manually.  At the IEEE1275 prompt, type:\n  %s\n", 
+                      cmd);
+      free (cmd);
+    }
+
+  free (boot_device);
+}
+
+void
+grub_install_sgi_setup (const char *install_device,
+                       const char *imgfile, const char *destname)
+{
+  grub_util_exec ((const char * []){ "dvhtool", "-d",
+       install_device, "--unix-to-vh", 
+       imgfile, destname, NULL });
+  grub_util_warn ("%s", _("You will have to set `SystemPartition' and `OSLoader' manually."));
+}
diff --git a/grub-core/osdep/windows/config.c b/grub-core/osdep/windows/config.c
new file mode 100644 (file)
index 0000000..823eac8
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013  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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <config-util.h>
+
+#include <grub/emu/hostfile.h>
+#include <grub/emu/config.h>
+#include <grub/util/install.h>
+#include <grub/util/misc.h>
+
+void
+grub_util_load_config (struct grub_util_config *cfg)
+{
+  const char *cfgfile;
+  FILE *f = NULL;
+  const char *v;
+
+  cfgfile = grub_util_get_config_filename ();
+  if (!grub_util_is_regular (cfgfile))
+    return;
+
+  memset (cfg, 0, sizeof (*cfg));
+
+  v = getenv ("GRUB_ENABLE_CRYPTODISK");
+  if (v && v[0] == 'y' && v[1] == '\0')
+    cfg->is_cryptodisk_enabled = 1;
+
+  v = getenv ("GRUB_DISTRIBUTOR");
+  if (v)
+    cfg->grub_distributor = xstrdup (v);
+
+  f = grub_util_fopen (cfgfile, "r");
+  if (f)
+    {
+      grub_util_parse_config (f, cfg, 0);
+      fclose (f);
+    }
+  else
+    grub_util_warn (_("cannot open config file `%s': %s"),
+                   cfgfile, strerror (errno));
+}
index f396c870084b9f65240bc73417eeae70bf124e49..6d7d12097297fe0ba655fb544941891fc4381f24 100644 (file)
@@ -46,6 +46,7 @@
 
 #include <windows.h>
 #include <winioctl.h>
+#include <wincrypt.h>
 
 #if SIZEOF_TCHAR == 1
 
@@ -411,6 +412,89 @@ grub_util_unlink (const char *name)
   return ret;
 }
 
+int
+grub_util_rmdir (const char *name)
+{
+  LPTSTR name_windows;
+  int ret;
+
+  name_windows = grub_util_get_windows_path (name);
+
+  ret = !RemoveDirectory (name_windows);
+  free (name_windows);
+  return ret;
+}
+
+static char *
+get_temp_name (void)
+{
+  TCHAR rt[1024];
+  TCHAR *ptr;
+  HCRYPTPROV   hCryptProv;
+  grub_uint8_t rnd[5];
+  const size_t sz = sizeof (rnd) * GRUB_CHAR_BIT / 5;
+  int i;
+
+  GetTempPath (ARRAY_SIZE (rt) - 100, rt);
+
+  if (!CryptAcquireContext (&hCryptProv,
+                           NULL,
+                           MS_DEF_PROV,
+                           PROV_RSA_FULL,
+                           CRYPT_VERIFYCONTEXT)
+      || !CryptGenRandom (hCryptProv, 5, rnd))
+    grub_util_error ("%s", _("couldn't retrieve random data"));
+
+  CryptReleaseContext (hCryptProv, 0);
+
+  for (ptr = rt; *ptr; ptr++);
+  memcpy (ptr, TEXT("\\GRUB."), sizeof (TEXT("\\GRUB.")));
+  ptr += sizeof ("\\GRUB.") - 1;
+
+  for (i = 0; i < 8; i++)
+    {
+      grub_size_t b = i * 5;
+      grub_uint8_t r;
+      grub_size_t f1 = GRUB_CHAR_BIT - b % GRUB_CHAR_BIT;
+      grub_size_t f2;
+      if (f1 > 5)
+       f1 = 5;
+      f2 = 5 - f1;
+      r = (rnd[b / GRUB_CHAR_BIT] >> (b % GRUB_CHAR_BIT)) & ((1 << f1) - 1);
+      if (f2)
+       r |= (rnd[b / GRUB_CHAR_BIT + 1] & ((1 << f2) - 1)) << f1;
+      if (r < 10)
+       *ptr++ = '0' + r;
+      else
+       *ptr++ = 'a' + (r - 10);
+    }  
+  *ptr = '\0';
+
+  return grub_util_tchar_to_utf8 (rt);
+}
+
+char *
+grub_util_make_temporary_file (void)
+{
+  char *ret = get_temp_name ();
+  FILE *f;
+
+  f = grub_util_fopen (ret, "wb");
+  if (f)
+    fclose (f);
+  return ret;
+}
+
+char *
+grub_util_make_temporary_dir (void)
+{
+  char *ret = get_temp_name ();
+
+  grub_util_mkdir (ret);
+
+  return ret;
+}
+
 int
 grub_util_is_directory (const char *name)
 {
@@ -444,6 +528,33 @@ grub_util_is_regular (const char *name)
     && !(attr & FILE_ATTRIBUTE_REPARSE_POINT) && attr;
 }
 
+grub_uint32_t
+grub_util_get_mtime (const char *path)
+{
+  LPTSTR name_windows;
+  BOOL b;
+  WIN32_FILE_ATTRIBUTE_DATA attr;
+  ULARGE_INTEGER us_ul;
+
+  name_windows = grub_util_get_windows_path (path);
+  if (!name_windows)
+    return 0;
+
+  b = GetFileAttributesEx (name_windows, GetFileExInfoStandard, &attr);
+  grub_free (name_windows);
+
+  if (!b)
+    return 0;
+
+  us_ul.LowPart = attr.ftLastWriteTime.dwLowDateTime;
+  us_ul.HighPart = attr.ftLastWriteTime.dwHighDateTime;
+
+  return (us_ul.QuadPart / 10000000) 
+    - 86400ULL * 365 * (1970 - 1601)
+    - 86400ULL * ((1970 - 1601) / 4) + 86400ULL * ((1970 - 1601) / 100);
+}
+
+
 #ifdef __MINGW32__
 
 FILE *
index 45554f1b2ec8fb23a5205dc69ba6660ca8eba0f0..98c325c203ddeed4be214539f6f890c0a2cfc0d5 100644 (file)
@@ -21,6 +21,7 @@
 #include <grub/util/misc.h>
 #include <grub/osdep/hostfile.h>
 #include <grub/util/windows.h>
+#include <grub/emu/config.h>
 
 #include <wincon.h>
 #include <windows.h>
@@ -111,10 +112,42 @@ set_console_unicode_font (void)
     }
 }
 
+static char *grub_util_base_directory;
+static char *locale_dir;
+
+const char *
+grub_util_get_config_filename (void)
+{
+  static char *value = NULL;
+  if (!value)
+    value = grub_util_path_concat (2, grub_util_base_directory, "grub.cfg");
+  return value;
+}
+
+const char *
+grub_util_get_pkgdatadir (void)
+{
+  return grub_util_base_directory;
+}
+
+const char *
+grub_util_get_localedir (void)
+{
+  return locale_dir;
+}
+
+const char *
+grub_util_get_pkglibdir (void)
+{
+  return grub_util_base_directory;
+}
+
 void
 grub_util_host_init (int *argc __attribute__ ((unused)),
                     char ***argv)
 {
+  char *ptr;
+
   SetConsoleOutputCP (CP_UTF8);
   SetConsoleCP (CP_UTF8);
 
@@ -137,9 +170,21 @@ grub_util_host_init (int *argc __attribute__ ((unused)),
 #error "Unsupported TCHAR size"
 #endif
 
+  grub_util_base_directory = canonicalize_file_name ((*argv)[0]);
+  if (!grub_util_base_directory)
+    grub_util_base_directory = xstrdup ((*argv)[0]);
+  for (ptr = grub_util_base_directory + strlen (grub_util_base_directory) - 1;
+       ptr >= grub_util_base_directory && *ptr != '/' && *ptr != '\\'; ptr--);
+  if (ptr >= grub_util_base_directory)
+    *ptr = '\0';
+
+  locale_dir = grub_util_path_concat (2, grub_util_base_directory, "locale");
+
   set_program_name ((*argv)[0]);
 
-#ifdef GRUB_UTIL
-  grub_util_init_nls ();
-#endif
+#if (defined (GRUB_UTIL) && defined(ENABLE_NLS) && ENABLE_NLS)
+  setlocale (LC_ALL, "");
+  bindtextdomain (PACKAGE, locale_dir);
+  textdomain (PACKAGE);
+#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */
 }
diff --git a/include/grub/emu/config.h b/include/grub/emu/config.h
new file mode 100644 (file)
index 0000000..875d589
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CONFIG_EMU_HEADER
+#define GRUB_CONFIG_EMU_HEADER 1
+
+#include <grub/disk.h>
+#include <grub/partition.h>
+#include <grub/emu/hostfile.h>
+#include <stdio.h>
+
+const char *
+grub_util_get_config_filename (void);
+const char *
+grub_util_get_pkgdatadir (void);
+const char *
+grub_util_get_pkglibdir (void);
+const char *
+grub_util_get_localedir (void);
+
+struct grub_util_config
+{
+  int is_cryptodisk_enabled;
+  char *grub_distributor;
+};
+
+void
+grub_util_load_config (struct grub_util_config *cfg);
+
+void
+grub_util_parse_config (FILE *f, struct grub_util_config *cfg, int simple);
+
+#endif
index 675cf78be0b15c91ed641801f2d175a36ec4e030..73fa2d34abb656c7a89bfde25cf717178501ab0f 100644 (file)
 #define GRUB_UTIL_GETROOT_HEADER       1
 
 #include <grub/types.h>
+#include <grub/device.h>
 
 #include <sys/types.h>
+#include <stdio.h>
 
 enum grub_dev_abstraction_types {
   GRUB_DEV_ABSTRACTION_NONE,
@@ -89,4 +91,14 @@ grub_util_get_grub_dev_os (const char *os_dev);
 grub_disk_addr_t
 grub_util_find_partition_start_os (const char *dev);
 
+char *
+grub_util_guess_bios_drive (const char *orig_path);
+char *
+grub_util_guess_efi_drive (const char *orig_path);
+char *
+grub_util_guess_baremetal_drive (const char *orig_path);
+void
+grub_util_fprint_full_disk_name (FILE *f,
+                                const char *drive, grub_device_t dev);
+
 #endif /* ! GRUB_UTIL_GETROOT_HEADER */
index 3ca1ab248ff8117a2c013b97f8ff79e5836c76b9..ab01fbce8d41c5970cb890c7cec1181c44f154ac 100644 (file)
@@ -31,6 +31,11 @@ grub_util_is_special_file (const char *path);
 int
 grub_util_is_regular (const char *path);
 
+char *
+grub_util_path_concat (size_t n, ...);
+char *
+grub_util_path_concat_ext (size_t n, ...);
+
 int
 grub_util_fd_seek (grub_util_fd_t fd, grub_uint64_t off);
 ssize_t
@@ -49,5 +54,13 @@ EXPORT_FUNC(grub_util_fd_close) (grub_util_fd_t fd);
 
 grub_uint64_t
 grub_util_get_fd_size (grub_util_fd_t fd, const char *name, unsigned *log_secsize);
+char *
+grub_util_make_temporary_file (void);
+char *
+grub_util_make_temporary_dir (void);
+void
+grub_util_unlink_recursive (const char *name);
+grub_uint32_t
+grub_util_get_mtime (const char *name);
 
 #endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */
diff --git a/include/grub/osdep/exec_unix.h b/include/grub/osdep/exec_unix.h
new file mode 100644 (file)
index 0000000..ecc3adc
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_EMU_EXEC_H
+#define GRUB_EMU_EXEC_H 1
+
+#include <config.h>
+#include <stdarg.h>
+
+#include <sys/types.h>
+pid_t
+grub_util_exec_pipe (const char *const *argv, int *fd);
+pid_t
+grub_util_exec_pipe_stderr (const char *const *argv, int *fd);
+
+int
+grub_util_exec (const char *const *argv);
+int
+grub_util_exec_redirect (const char *const *argv, const char *stdin_file,
+                        const char *stdout_file);
+int
+grub_util_exec_redirect_null (const char *const *argv);
+
+#endif
index 3a5043587cd509df988e4d096e5e267997112487..4ec211b48bcafea8b21efb627780e14da1aa07d9 100644 (file)
@@ -50,6 +50,12 @@ grub_util_fd_readdir (grub_util_fd_dir_t dirp)
   return readdir (dirp);
 }
 
+static inline int
+grub_util_rmdir (const char *pathname)
+{
+  return rmdir (pathname);
+}
+
 static inline int
 grub_util_unlink (const char *pathname)
 {
@@ -62,7 +68,7 @@ grub_util_rename (const char *from, const char *to)
   return rename (from, to);
 }
 
-#define grub_util_mkdir(a) mkdir (a)
+#define grub_util_mkdir(a) mkdir (a, 0700)
 
 struct grub_util_fd
 {
@@ -86,7 +92,7 @@ enum grub_util_fd_open_flags_t
     GRUB_UTIL_FD_O_RDONLY = O_RDONLY,
     GRUB_UTIL_FD_O_WRONLY = O_WRONLY,
     GRUB_UTIL_FD_O_RDWR = O_RDWR,
-    GRUB_UTIL_FD_O_CREAT = O_CREAT,
+    GRUB_UTIL_FD_O_CREATTRUNC = O_CREAT | O_TRUNC,
     GRUB_UTIL_FD_O_SYNC = (0
 #ifdef O_SYNC
                           | O_SYNC
index 50883f44fd4310670e40a28964516d02fb510e01..e4e89398ca6a9f5f3493676a4b8aa4cc27175c0f 100644 (file)
@@ -59,6 +59,12 @@ grub_util_unlink (const char *pathname)
   return unlink (pathname);
 }
 
+static inline int
+grub_util_rmdir (const char *pathname)
+{
+  return rmdir (pathname);
+}
+
 static inline int
 grub_util_rename (const char *from, const char *to)
 {
index ff21b6f93cf12fe01510b2868fdc7bd0c267bc9c..e928b3f96415eae91188d58a330a7838714e81b3 100644 (file)
@@ -55,6 +55,9 @@ grub_util_fd_closedir (grub_util_fd_dir_t dirp);
 grub_util_fd_dirent_t
 grub_util_fd_readdir (grub_util_fd_dir_t dirp);
 
+int
+grub_util_rmdir (const char *pathname);
+
 enum grub_util_fd_open_flags_t
   {
     GRUB_UTIL_FD_O_RDONLY = 1,
index 7eb6141a56c7a385b6e10f47c8cc4e9ed699df7d..c1cd6b33969cf1c86293229d807adc4f79d40a9c 100644 (file)
 #include <grub/disk.h>
 #include <grub/emu/hostfile.h>
 
+#define GRUB_INSTALL_OPTIONS                                     \
+  { "modules",      GRUB_INSTALL_OPTIONS_MODULES, N_("MODULES"),         \
+    0, N_("pre-load specified modules MODULES"), 1 },                    \
+  { "install-modules", GRUB_INSTALL_OPTIONS_INSTALL_MODULES,     \
+    N_("MODULES"), 0,                                                    \
+    N_("install only MODULES and their dependencies [default=all]"), 1 }, \
+  { "themes", GRUB_INSTALL_OPTIONS_INSTALL_THEMES, N_("THEMES"),   \
+    0, N_("install THEMES [default=%s]"), 1 },                           \
+  { "fonts", GRUB_INSTALL_OPTIONS_INSTALL_FONTS, N_("FONTS"),    \
+    0, N_("install FONTS [default=%s]"), 1  },                           \
+  { "locales", GRUB_INSTALL_OPTIONS_INSTALL_LOCALES, N_("LOCALES"),\
+    0, N_("install only LOCALES [default=all]"), 1 },                    \
+  { "compress", GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS,           \
+    "no,xz,gz,lzo", OPTION_ARG_OPTIONAL,                                 \
+    N_("compress GRUB files [optional]"), 1 },                           \
+    /* TRANSLATORS: platform here isn't identifier. It can be translated. */ \
+  { "directory", 'd', N_("DIR"), 0,                                    \
+    N_("use images and modules under DIR [default=%s/<platform>]"), 1 },  \
+  { "override-directory", GRUB_INSTALL_OPTIONS_DIRECTORY2,             \
+      N_("DIR"), OPTION_HIDDEN,                                                \
+    N_("use images and modules under DIR [default=%s/<platform>]"), 1 },  \
+  { "grub-mkimage", GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE,         \
+      "FILE", OPTION_HIDDEN, 0, 1 },                                   \
+    /* TRANSLATORS: "embed" is a verb (command description).  "*/      \
+  { "pubkey",   'k', N_("FILE"), 0,                                    \
+      N_("embed FILE as public key for signature checking"), 0},       \
+  { "verbose", 'v', 0, 0,                                              \
+    N_("increase verbosity"), 1 }
+
+int
+grub_install_parse (int key, char *arg);
+
+void
+grub_install_push_module (const char *val);
+
+void
+grub_install_pop_module (void);
+
+char *
+grub_install_help_filter (int key, const char *text,
+                         void *input __attribute__ ((unused)));
+
+enum grub_install_plat
+  {
+    GRUB_INSTALL_PLATFORM_I386_PC,
+    GRUB_INSTALL_PLATFORM_I386_EFI,
+    GRUB_INSTALL_PLATFORM_I386_QEMU,
+    GRUB_INSTALL_PLATFORM_I386_COREBOOT,
+    GRUB_INSTALL_PLATFORM_I386_MULTIBOOT,
+    GRUB_INSTALL_PLATFORM_I386_IEEE1275,
+    GRUB_INSTALL_PLATFORM_X86_64_EFI,
+    GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON,
+    GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275,
+    GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275,
+    GRUB_INSTALL_PLATFORM_MIPSEL_ARC,
+    GRUB_INSTALL_PLATFORM_MIPS_ARC,
+    GRUB_INSTALL_PLATFORM_IA64_EFI,
+    GRUB_INSTALL_PLATFORM_ARM_UBOOT,
+    GRUB_INSTALL_PLATFORM_ARM_EFI,
+    GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS,
+    GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS,
+    GRUB_INSTALL_PLATFORM_MAX
+  };
+
+enum grub_install_options {
+  GRUB_INSTALL_OPTIONS_DIRECTORY = 'd',
+  GRUB_INSTALL_OPTIONS_VERBOSITY = 'v',
+  GRUB_INSTALL_OPTIONS_MODULES = 0x201,
+  GRUB_INSTALL_OPTIONS_INSTALL_MODULES,
+  GRUB_INSTALL_OPTIONS_INSTALL_THEMES,
+  GRUB_INSTALL_OPTIONS_INSTALL_FONTS,
+  GRUB_INSTALL_OPTIONS_INSTALL_LOCALES,
+  GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS,
+  GRUB_INSTALL_OPTIONS_DIRECTORY2,
+  GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE
+};
+
+extern char *grub_install_source_directory;
+
+enum grub_install_plat
+grub_install_get_target (const char *src);
+void
+grub_install_mkdir_p (const char *dst);
+
+void
+grub_install_copy_files (const char *src,
+                        const char *dst,
+                        enum grub_install_plat platid);
+char *
+grub_install_get_platform_name (enum grub_install_plat platid);
+
+const char *
+grub_install_get_platform_cpu (enum grub_install_plat platid);
+
+const char *
+grub_install_get_platform_platform (enum grub_install_plat platid);
+
+
 typedef enum {
   GRUB_COMPRESSION_AUTO,
   GRUB_COMPRESSION_NONE,
@@ -33,6 +131,25 @@ typedef enum {
   GRUB_COMPRESSION_LZMA
 } grub_compression_t;
 
+void
+grub_install_make_image_wrap (const char *dir, const char *prefix,
+                             const char *outname, char *memdisk_path,
+                             char *config_path,
+                             const char *format, int note,
+                             grub_compression_t comp);
+void
+grub_install_make_image_wrap_file (const char *dir, const char *prefix,
+                                  FILE *fp, const char *outname,
+                                  char *memdisk_path,
+                                  char *config_path,
+                                  const char *mkimage_target, int note,
+                                  grub_compression_t comp);
+
+int
+grub_install_copy_file (const char *src,
+                       const char *dst,
+                       int is_critical);
+
 struct grub_install_image_target_desc;
 
 void
@@ -66,6 +183,32 @@ grub_install_get_image_targets_string (void);
 const char *
 grub_util_get_target_dirname (const struct grub_install_image_target_desc *t);
 
+void
+grub_install_create_envblk_file (const char *name);
+
+const char *
+grub_install_get_default_x86_platform (void);
+
+void
+grub_install_register_efi (const char *efidir_disk, int efidir_part,
+                          const char *efifile_path,
+                          const char *efi_distributor);
+
+void
+grub_install_register_ieee1275 (int is_prep, const char *install_device,
+                               int partno, const char *relpath);
+
+void
+grub_install_sgi_setup (const char *install_device,
+                       const char *imgfile, const char *destname);
+
+int 
+grub_install_compress_gzip (const char *src, const char *dest);
+int 
+grub_install_compress_lzop (const char *src, const char *dest);
+int 
+grub_install_compress_xz (const char *src, const char *dest);
+
 void
 grub_install_get_blocklist (grub_device_t root_dev,
                            const char *core_path, const char *core_img,
@@ -89,4 +232,10 @@ grub_util_render_label (const char *label_font,
                        const char *label_string,
                        const char *label);
 
+const char *
+grub_util_get_target_name (const struct grub_install_image_target_desc *t);
+
+extern char *grub_install_copy_buffer;
+#define GRUB_INSTALL_COPY_BUFFER_SIZE 1048576
+
 #endif
index 83a3220d6e69e4160979f9ca106e2d96ca4e13fa..3619458e85f2bed3f92a76a9d919c26a30116dee 100644 (file)
@@ -68,10 +68,10 @@ UPDATEPOFILES = @UPDATEPOFILES@
 DUMMYPOFILES = @DUMMYPOFILES@
 DISTFILES.common = Makefile.in.in remove-potcdate.sin \
 $(DISTFILES.common.extra1) $(DISTFILES.common.extra2) \
-$(DISTFILES.common.extra3) $(DISTFILES.common.extra4)
+$(DISTFILES.common.extra3) $(DISTFILES.common.extra4) $(DISTFILES.common.extra5)
 DISTFILES = $(DISTFILES.common) Makevars POTFILES.in POTFILES-shell.in \
 $(POFILES) $(GMOFILES) \
-$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3) $(DISTFILES.extra4) grub.d.sed README
+$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3) $(DISTFILES.extra4) $(DISTFILES.extra5) grub.d.sed README
 
 POTFILES = \
 
diff --git a/po/Rules-windowsdir b/po/Rules-windowsdir
new file mode 100644 (file)
index 0000000..fe47b10
--- /dev/null
@@ -0,0 +1,11 @@
+# generate windowsdir
+
+DISTFILES.common.extra5 = Rules-windowsdir
+
+windowsdir="$(top_builddir)/$(PACKAGE)-$(VERSION)-for-windows"
+windowsdir: $(GMOFILES)
+       test -d "$(windowsdir)/locale" || mkdir "$(windowsdir)/locale"
+       for x in $(CATALOGS); do \
+               test -d "$(windowsdir)/locale/$${x%.gmo}" || mkdir "$(windowsdir)/locale/$${x%.gmo}"; \
+               cp -fp "$(srcdir)/$$x" "$(windowsdir)/locale/$${x%.gmo}/grub.mo"; \
+       done
index fc435b68af6ed66c1dbe9dd9af010943cae15948..22277fbdfabaeff5f3d7f4c63a71e745d9e8814b 100644 (file)
@@ -347,8 +347,8 @@ fi
 
 if [ x$boot != xnet ] && [ x$boot != xemu ]; then
     cp -R "@srcdir@/themes" "@builddir@"
-    pkgdatadir="@builddir@" sh "@builddir@/grub-mkrescue" "--grub-mkimage=${builddir}/grub-mkimage" "--grub-render-label=${builddir}/grub-render-label" "--output=${isofile}" "--override-directory=${builddir}/grub-core" \
-       --rom-directory="${rom_directory}" "--grub-mkimage-extra=$mkimage_extra_arg" ${mkrescue_args} \
+    pkgdatadir="@builddir@" "@builddir@/grub-mkrescue" "--output=${isofile}" "--override-directory=${builddir}/grub-core" \
+       --rom-directory="${rom_directory}" $mkimage_extra_arg ${mkrescue_args} \
        "/boot/grub/grub.cfg=${cfgfile}" "/boot/grub/testcase.cfg=${source}" \
        ${files} >/dev/null 2>&1
 fi
@@ -418,7 +418,7 @@ do_trim ()
 
 if [ x$boot = xnet ]; then
     netdir=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1
-    pkgdatadir="@builddir@" sh "@builddir@/grub-mknetdir" "--grub-mkimage=${builddir}/grub-mkimage" "--directory=${builddir}/grub-core" "--net-directory=$netdir" ${mkrescue_args} > /dev/null
+    pkgdatadir="@builddir@" "@builddir@/grub-mknetdir" "--grub-mkimage=${builddir}/grub-mkimage" "--directory=${builddir}/grub-core" "--net-directory=$netdir" ${mkrescue_args} > /dev/null
     cp "${cfgfile}" "$netdir/boot/grub/grub.cfg"
     cp "${source}" "$netdir/boot/grub/testcase.cfg"
     timeout -s KILL $timeout "${qemu}" ${qemuopts} ${serial_null} -serial file:/dev/stdout -boot n -net "user,tftp=$netdir,bootfile=/boot/grub/${grub_modinfo_target_cpu}-${grub_modinfo_platform}/core.$netbootext"  -net nic  | cat | tr -d "\r" | do_trim
diff --git a/util/config.c b/util/config.c
new file mode 100644 (file)
index 0000000..f313714
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <grub/emu/config.h>
+#include <grub/util/misc.h>
+
+void
+grub_util_parse_config (FILE *f, struct grub_util_config *cfg, int simple)
+{
+  char *buffer = NULL;
+  size_t sz = 0;
+  while (getline (&buffer, &sz, f) >= 0)
+    {
+      const char *ptr;
+      for (ptr = buffer; *ptr && grub_isspace (*ptr); ptr++);
+      if (grub_strncmp (ptr, "GRUB_ENABLE_CRYPTODISK=",
+                       sizeof ("GRUB_ENABLE_CRYPTODISK=") - 1) == 0)
+       {
+         ptr += sizeof ("GRUB_ENABLE_CRYPTODISK=") - 1;
+         if (*ptr == '"' || *ptr == '\'')
+           ptr++;
+         if (*ptr == 'y')
+           cfg->is_cryptodisk_enabled = 1;
+         continue;
+       }
+      if (grub_strncmp (ptr, "GRUB_DISTRIBUTOR=",
+                       sizeof ("GRUB_DISTRIBUTOR=") - 1) == 0)
+       {
+         char *optr;
+         enum { NONE, SNGLQUOT, DBLQUOT } state;
+         if (simple)
+           {
+             free (cfg->grub_distributor);
+             cfg->grub_distributor = xstrdup (ptr);
+             continue;
+           }
+         free (cfg->grub_distributor);
+         cfg->grub_distributor = xmalloc (strlen (ptr) + 1);
+         optr = cfg->grub_distributor;
+         state = NONE;
+
+         for (; *ptr; ptr++)
+           switch (*ptr)
+             {
+             case '\\':
+               if (state == SNGLQUOT)
+                 {
+                   *optr++ = *ptr;
+                   continue;
+                 }
+               if (ptr[1])
+                 {
+                   *optr++ = ptr[1];
+                   ptr++;
+                   continue;
+                 }
+               ptr++;
+               break;
+             case '"':
+               if (state == NONE)
+                 {
+                   state = DBLQUOT;
+                   continue;
+                 }
+               if (state == DBLQUOT)
+                 {
+                   state = NONE;
+                   continue;
+                 }
+               *optr++ = *ptr;
+               continue;
+             case '\'':
+               if (state == SNGLQUOT)
+                 {
+                   state = NONE;
+                   continue;
+                 }
+               if (state == NONE)
+                 {
+                   state = SNGLQUOT;
+                   continue;
+                 }
+               *optr++ = *ptr;
+               continue;
+             default:
+               *optr++ = *ptr;
+               continue;
+             }
+         *optr = '\0';
+       }
+    }
+}
+
diff --git a/util/grub-install-common.c b/util/grub-install-common.c
new file mode 100644 (file)
index 0000000..75a315d
--- /dev/null
@@ -0,0 +1,863 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/types.h>
+#include <grub/emu/misc.h>
+#include <grub/util/misc.h>
+#include <grub/misc.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/file.h>
+#include <grub/fs.h>
+#include <grub/env.h>
+#include <grub/term.h>
+#include <grub/mm.h>
+#include <grub/lib/hexdump.h>
+#include <grub/crypto.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+#include <grub/zfs/zfs.h>
+#include <grub/util/install.h>
+#include <grub/util/resolve.h>
+#include <grub/emu/hostfile.h>
+#include <grub/emu/config.h>
+#include <grub/emu/hostfile.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+char *
+grub_install_help_filter (int key, const char *text,
+                                void *input __attribute__ ((unused)))
+{
+  switch (key)
+    {
+    case GRUB_INSTALL_OPTIONS_INSTALL_THEMES:
+      return xasprintf(text, "starfield");
+    case GRUB_INSTALL_OPTIONS_INSTALL_FONTS:
+      return xasprintf(text, "unicode");
+    case GRUB_INSTALL_OPTIONS_DIRECTORY:
+    case GRUB_INSTALL_OPTIONS_DIRECTORY2:
+      return xasprintf(text, grub_util_get_pkglibdir ());      
+    default:
+      return (char *) text;
+    }
+}
+
+static int (*compress_func) (const char *src, const char *dest) = NULL;
+char *grub_install_copy_buffer;
+
+int
+grub_install_copy_file (const char *src,
+                       const char *dst,
+                       int is_needed)
+{
+  grub_util_fd_t in, out;  
+  ssize_t r;
+
+  grub_util_info ("copying `%s' -> `%s'", src, dst);
+
+  in = grub_util_fd_open (src, GRUB_UTIL_FD_O_RDONLY);
+  if (!GRUB_UTIL_FD_IS_VALID (in))
+    {
+      if (is_needed)
+       grub_util_error (_("cannot open `%s': %s"), src, grub_util_fd_strerror ());
+      else
+       grub_util_info (_("cannot open `%s': %s"), src, grub_util_fd_strerror ());
+      return 0;
+    }
+  out = grub_util_fd_open (dst, GRUB_UTIL_FD_O_WRONLY
+                          | GRUB_UTIL_FD_O_CREATTRUNC);
+  if (!GRUB_UTIL_FD_IS_VALID (out))
+    {
+      grub_util_error (_("cannot open `%s': %s"), dst,
+                      grub_util_fd_strerror ());
+      grub_util_fd_close (in);
+      return 0;
+    }
+
+  if (!grub_install_copy_buffer)
+    grub_install_copy_buffer = xmalloc (GRUB_INSTALL_COPY_BUFFER_SIZE);
+  while (1)
+    {
+      r = grub_util_fd_read (in, grub_install_copy_buffer, GRUB_INSTALL_COPY_BUFFER_SIZE);
+      if (r <= 0)
+       break;
+      grub_util_fd_write (out, grub_install_copy_buffer, r);
+    }
+  grub_util_fd_sync (out);
+  grub_util_fd_close (in);
+  grub_util_fd_close (out);
+
+  if (r < 0)
+    grub_util_error ("cannot copy `%s' to `%s': %s",
+                    src, dst, grub_util_fd_strerror ());
+
+  return 1;
+}
+
+int
+grub_install_compress_file (const char *in_name,
+                           const char *out_name,
+                           int is_needed)
+{
+  int ret;
+
+  if (!compress_func)
+    ret = grub_install_copy_file (in_name, out_name, is_needed);
+  else
+    {
+      grub_util_info ("compressing `%s' -> `%s'", in_name, out_name);
+      ret = !compress_func (in_name, out_name);
+      if (!ret && is_needed)
+       grub_util_warn ("can't compress `%s' to `%s'", in_name, out_name);
+    }
+
+  if (!ret && is_needed)
+    grub_util_error ("cannot copy `%s' to `%s': %s",
+                    in_name, out_name, grub_util_fd_strerror ());
+
+  return ret;
+}
+
+static int
+is_path_separator (char c)
+{
+#if defined (__MINGW32__) || defined (__CYGWIN__)
+  if (c == '\\')
+    return 1;
+#endif
+  if (c == '/')
+    return 1;
+  return 0;
+}
+
+void
+grub_install_mkdir_p (const char *dst)
+{
+  char *t = xstrdup (dst);
+  char *p;
+  for (p = t; *p; p++)
+    {
+      if (is_path_separator (*p))
+       {
+         char s = *p;
+         *p = '\0';
+         grub_util_mkdir (t);
+         *p = s;
+       }
+    }
+  grub_util_mkdir (t);
+  free (t);
+}
+
+static void
+clean_grub_dir (const char *di)
+{
+  grub_util_fd_dir_t d;
+  grub_util_fd_dirent_t de;
+
+  d = grub_util_fd_opendir (di);
+  if (!d)
+    grub_util_error (_("cannot open directory `%s': %s"),
+                    di, grub_util_fd_strerror ());
+
+  while ((de = grub_util_fd_readdir (d)))
+    {
+      const char *ext = strrchr (de->d_name, '.');
+      if ((ext && (strcmp (ext, ".mod") == 0
+                  || strcmp (ext, ".lst") == 0
+                  || strcmp (ext, ".img") == 0
+                  || strcmp (ext, ".mo") == 0)
+          && strcmp (de->d_name, "menu.lst") != 0)
+         || strcmp (de->d_name, "efiemu32.o") == 0
+         || strcmp (de->d_name, "efiemu64.o") == 0)
+       {
+         char *x = grub_util_path_concat (2, di, de->d_name);
+         if (grub_util_unlink (x) < 0)
+           grub_util_error ("cannont delete `%s': %s", x,
+                            grub_util_fd_strerror ());
+         free (x);
+       }
+    }
+  grub_util_fd_closedir (d);
+}
+
+struct install_list
+{
+  int is_default;
+  char **entries;
+  size_t n_entries;
+  size_t n_alloc;
+};
+
+struct install_list install_modules = { 1, 0, 0, 0 };
+struct install_list modules = { 1, 0, 0, 0 };
+struct install_list install_locales = { 1, 0, 0, 0 };
+struct install_list install_fonts = { 1, 0, 0, 0 };
+struct install_list install_themes = { 1, 0, 0, 0 };
+char *grub_install_source_directory = NULL;
+
+void
+grub_install_push_module (const char *val)
+{
+  modules.is_default = 0;
+  if (modules.n_entries + 1 >= modules.n_alloc)
+    {
+      modules.n_alloc <<= 1;
+      if (modules.n_alloc < 16)
+       modules.n_alloc = 16;
+      modules.entries = xrealloc (modules.entries,
+                                 modules.n_alloc * sizeof (modules.entries));
+    }
+  modules.entries[modules.n_entries++] = xstrdup (val);
+  modules.entries[modules.n_entries] = NULL;
+}
+
+void
+grub_install_pop_module (void)
+{
+  modules.n_entries--;
+  free (modules.entries[modules.n_entries]);
+  modules.entries[modules.n_entries] = NULL;
+}
+
+
+static void
+handle_install_list (struct install_list *il, const char *val,
+                    int default_all)
+{
+  const char *ptr;
+  char **ce;
+  il->is_default = 0;
+  free (il->entries);
+  il->entries = NULL;
+  il->n_entries = 0;
+  if (strcmp (val, "all") == 0 && default_all)
+    {
+      il->is_default = 1;
+      return;
+    }
+  ptr = val;
+  while (1)
+    {
+      while (*ptr && grub_isspace (*ptr))
+       ptr++;
+      if (!*ptr)
+       break;
+      while (*ptr && !grub_isspace (*ptr))
+       ptr++;
+      il->n_entries++;
+    }
+  il->n_alloc = il->n_entries + 1;
+  il->entries = xmalloc (il->n_alloc * sizeof (il->entries[0]));
+  for (ce = il->entries; ; ce++)
+    {
+      const char *bptr;
+      while (*ptr && grub_isspace (*ptr))
+       ptr++;
+      if (!*ptr)
+       break;
+      bptr = ptr;
+      while (*ptr && !grub_isspace (*ptr))
+       ptr++;
+      *ce = xmalloc (ptr - bptr + 1);
+      memcpy (*ce, bptr, ptr - bptr);
+      (*ce)[ptr - bptr] = '\0';
+      ce++;
+    }
+  *ce = NULL;
+}
+
+static char **pubkeys;
+static size_t npubkeys;
+
+int
+grub_install_parse (int key, char *arg)
+{
+  switch (key)
+    {
+    case 'k':
+      pubkeys = xrealloc (pubkeys,
+                         sizeof (pubkeys[0])
+                         * (npubkeys + 1));
+      pubkeys[npubkeys++] = xstrdup (arg);
+      return 1;
+
+    case GRUB_INSTALL_OPTIONS_VERBOSITY:
+      verbosity++;
+      return 1;
+
+    case GRUB_INSTALL_OPTIONS_DIRECTORY:
+    case GRUB_INSTALL_OPTIONS_DIRECTORY2:
+      free (grub_install_source_directory);
+      grub_install_source_directory = xstrdup (arg);
+      return 1;
+    case GRUB_INSTALL_OPTIONS_INSTALL_MODULES:
+      handle_install_list (&install_modules, arg, 0);
+      return 1;
+    case GRUB_INSTALL_OPTIONS_MODULES:
+      handle_install_list (&modules, arg, 0);
+      return 1;
+    case GRUB_INSTALL_OPTIONS_INSTALL_LOCALES:
+      handle_install_list (&install_locales, arg, 0);
+      return 1;
+    case GRUB_INSTALL_OPTIONS_INSTALL_THEMES:
+      handle_install_list (&install_themes, arg, 0);
+      return 1;
+    case GRUB_INSTALL_OPTIONS_INSTALL_FONTS:
+      handle_install_list (&install_fonts, arg, 0);
+      return 1;
+    case GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS:
+      if (strcmp (arg, "no") == 0)
+       {
+         compress_func = NULL;
+         return 1;
+       }
+      if (strcmp (arg, "gz") == 0)
+       {
+         compress_func = grub_install_compress_gzip;
+         return 1;
+       }
+      if (strcmp (arg, "xz") == 0)
+       {
+         compress_func = grub_install_compress_xz;
+         return 1;
+       }
+      if (strcmp (arg, "lzo") == 0)
+       {
+         compress_func = grub_install_compress_lzop;
+         return 1;
+       }
+      grub_util_error (_("Unrecognized compression `%s'"), arg);
+    case GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE:
+      return 1;
+    default:
+      return 0;
+    }
+}
+
+static int
+decompressors (void)
+{
+  if (compress_func == grub_install_compress_gzip)
+    {
+      grub_install_push_module ("gzio");
+      return 1;
+    }
+  if (compress_func == grub_install_compress_xz)
+    {
+      grub_install_push_module ("xzio");
+      grub_install_push_module ("gcry_crc");
+      return 2;
+    }
+  if (compress_func == grub_install_compress_lzop)
+    {
+      grub_install_push_module ("lzopio");
+      grub_install_push_module ("adler32");
+      grub_install_push_module ("gcry_crc");
+      return 3;
+    }
+  return 0;
+}
+
+void
+grub_install_make_image_wrap_file (const char *dir, const char *prefix,
+                                  FILE *fp, const char *outname,
+                                  char *memdisk_path,
+                                  char *config_path,
+                                  const char *mkimage_target, int note,
+                                  grub_compression_t comp)
+{
+  const struct grub_install_image_target_desc *tgt;
+  const char *const compnames[] = 
+    {
+      [GRUB_COMPRESSION_AUTO] = "auto",
+      [GRUB_COMPRESSION_NONE] = "none",
+      [GRUB_COMPRESSION_XZ] = "xz",
+      [GRUB_COMPRESSION_LZMA] = "lzma",
+    };
+  grub_size_t slen = 1;
+  char *s, *p;
+  char **pk, **md;
+  int dc = decompressors ();
+
+  if (memdisk_path)
+    slen += 20 + grub_strlen (memdisk_path);
+  if (config_path)
+    slen += 20 + grub_strlen (config_path);
+
+  for (pk = pubkeys; pk < pubkeys + npubkeys; pk++)
+    slen += 20 + grub_strlen (*pk);
+
+  for (md = modules.entries; *md; md++)
+    {
+      slen += 10 + grub_strlen (*md);
+    }
+
+  p = s = xmalloc (slen);
+  if (memdisk_path)
+    {
+      p = grub_stpcpy (p, "--memdisk '");
+      p = grub_stpcpy (p, memdisk_path);
+      *p++ = '\'';
+      *p++ = ' ';
+    }
+  if (config_path)
+    {
+      p = grub_stpcpy (p, "--config '");
+      p = grub_stpcpy (p, config_path);
+      *p++ = '\'';
+      *p++ = ' ';
+    }
+  for (pk = pubkeys; pk < pubkeys + npubkeys; pk++)
+    {
+      p = grub_stpcpy (p, "--pubkey '");
+      p = grub_stpcpy (p, *pk);
+      *p++ = '\'';
+      *p++ = ' ';
+    }
+
+  for (md = modules.entries; *md; md++)
+    {
+      *p++ = '\'';
+      p = grub_stpcpy (p, *md);
+      *p++ = '\'';
+      *p++ = ' ';
+    }
+
+  *p = '\0';
+
+  grub_util_info ("grub-mkimage --directory '%s' --prefix '%s'"
+                 " --output '%s' "
+                 "--format '%s' --compression '%s' %s %s\n",
+                 dir, prefix,
+                 outname, mkimage_target,
+                 compnames[comp], note ? "--note" : "", s);
+
+  tgt = grub_install_get_image_target (mkimage_target);
+  if (!tgt)
+    grub_util_error (_("unknown target format %s\n"), mkimage_target);
+
+  grub_install_generate_image (dir, prefix, fp, outname,
+                              modules.entries, memdisk_path,
+                              pubkeys, npubkeys, config_path, tgt,
+                              note, comp);
+  while (dc--)
+    grub_install_pop_module ();
+}
+
+void
+grub_install_make_image_wrap (const char *dir, const char *prefix,
+                             const char *outname, char *memdisk_path,
+                             char *config_path,
+                             const char *mkimage_target, int note,
+                             grub_compression_t comp)
+{
+  FILE *fp;
+
+  fp = grub_util_fopen (outname, "wb");
+  if (! fp)
+    grub_util_error (_("cannot open `%s': %s"), outname,
+                    strerror (errno));
+  grub_install_make_image_wrap_file (dir, prefix, fp, outname,
+                                    memdisk_path, config_path,
+                                    mkimage_target, note, comp);
+  fflush (fp);
+  fsync (fileno (fp));
+  fclose (fp);
+}
+
+static void
+copy_by_ext (const char *srcd,
+            const char *dstd,
+            const char *extf,
+            int req)
+{
+  grub_util_fd_dir_t d;
+  grub_util_fd_dirent_t de;
+
+  d = grub_util_fd_opendir (srcd);
+  if (!d && !req)
+    return;
+  if (!d)
+    grub_util_error (_("cannot open directory `%s': %s"),
+                    srcd, grub_util_fd_strerror ());
+
+  while ((de = grub_util_fd_readdir (d)))
+    {
+      const char *ext = strrchr (de->d_name, '.');
+      if (ext && strcmp (ext, extf) == 0)
+       {
+         char *srcf = grub_util_path_concat (2, srcd, de->d_name);
+         char *dstf = grub_util_path_concat (2, dstd, de->d_name);
+         grub_install_compress_file (srcf, dstf, 1);
+         free (srcf);
+         free (dstf);
+       }
+    }
+  grub_util_fd_closedir (d);
+}
+
+static void
+copy_all (const char *srcd,
+            const char *dstd)
+{
+  grub_util_fd_dir_t d;
+  grub_util_fd_dirent_t de;
+
+  d = grub_util_fd_opendir (srcd);
+  if (!d)
+    grub_util_error (_("cannot open directory `%s': %s"),
+                    srcd, grub_util_fd_strerror ());
+
+  while ((de = grub_util_fd_readdir (d)))
+    {
+      char *srcf;
+      char *dstf;
+      if (strcmp (de->d_name, ".") == 0
+         || strcmp (de->d_name, "..") == 0)
+       continue;
+      srcf = grub_util_path_concat (2, srcd, de->d_name);
+      if (grub_util_is_special_file (srcf)
+         || grub_util_is_directory (srcf))
+       continue;
+      dstf = grub_util_path_concat (2, dstd, de->d_name);
+      grub_install_compress_file (srcf, dstf, 1);
+      free (srcf);
+      free (dstf);
+    }
+  grub_util_fd_closedir (d);
+}
+
+static void
+copy_locales (const char *dstd)
+{
+  grub_util_fd_dir_t d;
+  grub_util_fd_dirent_t de;
+  const char *locale_dir = grub_util_get_localedir ();
+
+  d = grub_util_fd_opendir (LOCALEDIR);
+  if (!d)
+    {
+      grub_util_warn (_("cannot open directory `%s': %s"),
+                     locale_dir, grub_util_fd_strerror ());
+      return;
+    }
+
+  while ((de = grub_util_fd_readdir (d)))
+    {
+      char *srcf;
+      char *dstf;
+      if (strcmp (de->d_name, ".") == 0)
+       continue;
+      if (strcmp (de->d_name, "..") == 0)
+       continue;
+      srcf = grub_util_path_concat_ext (4, locale_dir, de->d_name,
+                                       "LC_MESSAGES", PACKAGE, ".mo");
+      dstf = grub_util_path_concat_ext (2, dstd, de->d_name, ".mo");
+      grub_install_compress_file (srcf, dstf, 0);
+      free (srcf);
+      free (dstf);
+    }
+  grub_util_fd_closedir (d);
+}
+
+static struct
+{
+  enum grub_install_plat val;
+  const char *cpu;
+  const char *platform;
+} platforms[] =
+  {
+    { GRUB_INSTALL_PLATFORM_I386_PC,          "i386",    "pc"        },
+    { GRUB_INSTALL_PLATFORM_I386_EFI,         "i386",    "efi"       },
+    { GRUB_INSTALL_PLATFORM_I386_QEMU,        "i386",    "qemu"      },
+    { GRUB_INSTALL_PLATFORM_I386_COREBOOT,    "i386",    "coreboot"  },
+    { GRUB_INSTALL_PLATFORM_I386_MULTIBOOT,   "i386",    "multiboot" },
+    { GRUB_INSTALL_PLATFORM_I386_IEEE1275,    "i386",    "ieee1275"  },
+    { GRUB_INSTALL_PLATFORM_X86_64_EFI,       "x86_64",  "efi"       },
+    { GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON,  "mipsel",  "loongson"  },
+    { GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS, "mipsel",  "qemu_mips" },
+    { GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS,   "mips",    "qemu_mips" },
+    { GRUB_INSTALL_PLATFORM_MIPSEL_ARC,       "mipsel",  "arc"       },
+    { GRUB_INSTALL_PLATFORM_MIPS_ARC,         "mips",    "arc"       },
+    { GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275, "sparc64", "ieee1275"  },
+    { GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275, "powerpc", "ieee1275"  },
+    { GRUB_INSTALL_PLATFORM_IA64_EFI,         "ia64",    "efi"       },
+    { GRUB_INSTALL_PLATFORM_ARM_EFI,          "arm",     "efi"       },
+    { GRUB_INSTALL_PLATFORM_ARM_UBOOT,        "arm",     "uboot"     },
+  }; 
+
+char *
+grub_install_get_platform_name (enum grub_install_plat platid)
+{
+  return xasprintf ("%s-%s", platforms[platid].cpu,
+                   platforms[platid].platform);
+}
+
+const char *
+grub_install_get_platform_cpu (enum grub_install_plat platid)
+{
+  return platforms[platid].cpu;
+}
+
+const char *
+grub_install_get_platform_platform (enum grub_install_plat platid)
+{
+  return platforms[platid].platform;
+}
+
+
+void
+grub_install_copy_files (const char *src,
+                        const char *dst,
+                        enum grub_install_plat platid)
+{
+  char *dst_platform, *dst_locale, *dst_fonts;
+  const char *pkgdatadir = grub_util_get_pkgdatadir ();
+
+  {
+    char *platform;
+    platform = xasprintf ("%s-%s", platforms[platid].cpu,
+                         platforms[platid].platform);
+    dst_platform = grub_util_path_concat (2, dst, platform);
+    free (platform);
+  }
+  dst_locale = grub_util_path_concat (2, dst, "locale");
+  dst_fonts = grub_util_path_concat (2, dst, "fonts");
+  grub_install_mkdir_p (dst_platform);
+  grub_install_mkdir_p (dst_locale);
+  clean_grub_dir (dst);
+  clean_grub_dir (dst_platform);
+  clean_grub_dir (dst_locale);
+
+  if (install_modules.is_default)
+    copy_by_ext (src, dst_platform, ".mod", 1);
+  else
+    {
+      struct grub_util_path_list *path_list, *p;
+
+      path_list = grub_util_resolve_dependencies (src, "moddep.lst",
+                                                 install_modules.entries);
+      for (p = path_list; p; p = p->next)
+       {
+         char *srcf = grub_util_path_concat_ext (2, src, p->name, ".mo");
+         char *dstf = grub_util_path_concat_ext (2, dst, p->name, ".mo");
+         grub_install_compress_file (srcf, dstf, 1);
+         free (srcf);
+         free (dstf);
+       }
+    }
+
+  const char *pkglib_DATA[] = {"efiemu32.o", "efiemu64.o",
+                              "moddep.lst", "command.lst",
+                              "fs.lst", "partmap.lst",
+                              "parttool.lst",
+                              "video.lst", "crypto.lst",
+                              "terminal.lst" };
+  size_t i;
+
+  for (i = 0; i < ARRAY_SIZE (pkglib_DATA); i++)
+    {
+      char *srcf = grub_util_path_concat (2, src, pkglib_DATA[i]);
+      char *dstf = grub_util_path_concat (2, dst_platform, pkglib_DATA[i]);
+      if (i == 0 || i == 1)
+       grub_install_compress_file (srcf, dstf, 0);
+      else
+       grub_install_compress_file (srcf, dstf, 1);
+      free (srcf);
+      free (dstf);
+    }
+
+  if (install_locales.is_default)
+    {
+      char *srcd = grub_util_path_concat (2, src, "po");
+      copy_by_ext (srcd, dst_locale, ".mo", 0);
+      copy_locales (dst_locale);
+      free (srcd);
+    }
+  else
+    {
+      for (i = 0; i < install_locales.n_entries; i++)
+       {
+         char *srcf = grub_util_path_concat_ext (3, src,
+                                               "po",
+                                               install_locales.entries[i],
+                                               ".mo");
+         char *dstf = grub_util_path_concat_ext (2, dst_locale,
+                                               install_locales.entries[i],
+                                               ".mo");
+         if (grub_install_compress_file (srcf, dstf, 0))
+           {
+             free (srcf);
+             free (dstf);
+             continue;
+           }
+         free (srcf);
+         srcf = grub_util_path_concat_ext (4,
+                                                LOCALEDIR,
+                                                install_locales.entries[i],
+                                                "LC_MESSAGES",
+                                                PACKAGE,
+                                                ".mo");
+         if (grub_install_compress_file (srcf, dstf, 0))
+           {
+             free (srcf);
+             free (dstf);
+             continue;
+           }
+         grub_util_error (_("cannot find locale `%s'"),
+                          install_locales.entries[i]);
+       }
+    }
+
+  if (install_themes.is_default)
+    {
+      install_themes.is_default = 0;
+      install_themes.n_entries = 1;
+      install_themes.entries = xmalloc (2 * sizeof (install_themes.entries[0]));
+      install_themes.entries[0] = xstrdup ("starfield");
+      install_themes.entries[1] = NULL;
+    }
+
+  for (i = 0; i < install_themes.n_entries; i++)
+    {
+      char *srcf = grub_util_path_concat (4, pkgdatadir, "themes",
+                                       install_themes.entries[i],
+                                       "theme.txt");
+      if (grub_util_is_regular (srcf))
+       {
+         char *srcd = grub_util_path_concat (3, pkgdatadir, "themes",
+                                           install_themes.entries[i]);
+         char *dstd = grub_util_path_concat (3, dst, "themes",
+                                           install_themes.entries[i]);
+         grub_install_mkdir_p (dstd);
+         copy_all (srcd, dstd);
+         free (srcd);
+         free (dstd);
+       }
+      free (srcf);
+    }
+
+  if (install_fonts.is_default)
+    {
+      install_fonts.is_default = 0;
+      install_fonts.n_entries = 1;
+      install_fonts.entries = xmalloc (2 * sizeof (install_fonts.entries[0]));
+      install_fonts.entries[0] = xstrdup ("unicode");
+      install_fonts.entries[1] = NULL;
+    }
+
+  grub_install_mkdir_p (dst_fonts);
+
+  for (i = 0; i < install_fonts.n_entries; i++)
+    {
+      char *srcf = grub_util_path_concat_ext (2, pkgdatadir,
+                                                  install_fonts.entries[i],
+                                                  ".pf2");
+      char *dstf = grub_util_path_concat_ext (2, dst_fonts,
+                                                  install_fonts.entries[i],
+                                                  ".pf2");
+
+      grub_install_compress_file (srcf, dstf, 0);
+      free (srcf);
+      free (dstf);
+    }
+
+  free (dst_platform);
+  free (dst_locale);
+  free (dst_fonts);
+}
+
+enum grub_install_plat
+grub_install_get_target (const char *src)
+{
+  char *fn;
+  grub_util_fd_t f;
+  char buf[2048];
+  size_t r;
+  char *c, *pl, *p;
+  size_t i;
+  fn = grub_util_path_concat (2, src, "modinfo.sh");
+  f = grub_util_fd_open (fn, GRUB_UTIL_FD_O_RDONLY);
+  if (!GRUB_UTIL_FD_IS_VALID (f))
+    grub_util_error (_("%s doesn't exist. Please specify --target or --directory"), 
+                    fn);
+  r = grub_util_fd_read (f, buf, sizeof (buf) - 1);
+  grub_util_fd_close (f);
+  buf[r] = '\0';
+  c = strstr (buf, "grub_modinfo_target_cpu=");
+  if (!c || (c != buf && !grub_isspace (*(c-1))))
+    grub_util_error (_("invalid modinfo file `%s'"), fn);
+  pl = strstr (buf, "grub_modinfo_platform=");
+  if (!pl || (pl != buf && !grub_isspace (*(pl-1))))
+    grub_util_error (_("invalid modinfo file `%s'"), fn);
+  c += sizeof ("grub_modinfo_target_cpu=") - 1;
+  pl += sizeof ("grub_modinfo_platform=") - 1;
+  for (p = c; *p && !grub_isspace (*p); p++);
+  *p = '\0';
+  for (p = pl; *p && !grub_isspace (*p); p++);
+  *p = '\0';
+
+  for (i = 0; i < ARRAY_SIZE (platforms); i++)
+    if (strcmp (platforms[i].cpu, c) == 0
+       && strcmp (platforms[i].platform, pl) == 0)
+      {
+       free (fn);
+       return platforms[i].val;
+      }
+  grub_util_error (_("Unknown platform `%s-%s'"), c, pl);
+}
+
+
+void
+grub_util_unlink_recursive (const char *name)
+{
+  grub_util_fd_dir_t d;
+  grub_util_fd_dirent_t de;
+
+  d = grub_util_fd_opendir (name);
+
+  while ((de = grub_util_fd_readdir (d)))
+    {
+      char *fp;
+      if (strcmp (de->d_name, ".") == 0)
+       continue;
+      if (strcmp (de->d_name, "..") == 0)
+       continue;
+      fp = grub_util_path_concat (2, name, de->d_name);
+      if (grub_util_is_special_file (fp))
+       {
+         free (fp);
+         continue;
+       }
+      if (grub_util_is_regular (fp))
+       grub_util_unlink (fp);
+      else if (grub_util_is_directory (fp))
+       grub_util_unlink_recursive (fp);
+      free (fp);
+    }
+  grub_util_rmdir (name);
+  grub_util_fd_closedir (d);
+}
diff --git a/util/grub-install.c b/util/grub-install.c
new file mode 100644 (file)
index 0000000..100f093
--- /dev/null
@@ -0,0 +1,1539 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/types.h>
+#include <grub/emu/misc.h>
+#include <grub/util/misc.h>
+#include <grub/misc.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/file.h>
+#include <grub/fs.h>
+#include <grub/env.h>
+#include <grub/term.h>
+#include <grub/mm.h>
+#include <grub/lib/hexdump.h>
+#include <grub/crypto.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+#include <grub/zfs/zfs.h>
+#include <grub/util/install.h>
+#include <grub/emu/getroot.h>
+#include <grub/diskfilter.h>
+#include <grub/cryptodisk.h>
+#include <grub/legacy_parse.h>
+#include <grub/gpt_partition.h>
+#include <grub/emu/config.h>
+#include <grub/util/ofpath.h>
+
+#include <string.h>
+
+#include "argp.h"
+
+#include "progname.h"
+
+static char *target;
+static int removable = 0;
+static int recheck = 0;
+static int update_nvram = 1;
+static char *install_device = NULL;
+static char *debug_image = NULL;
+static char *rootdir = NULL;
+static char *bootdir = NULL;
+static int allow_floppy = 0;
+static int force_file_id = 0;
+static char *disk_module = NULL;
+static char *efidir = NULL;
+static int force = 0;
+static int have_abstractions = 0;
+static int have_cryptodisk = 0;
+static char * bootloader_id;
+static int have_load_cfg = 0;
+static FILE * load_cfg_f = NULL;
+static char *load_cfg;
+
+enum
+  {
+    OPTION_BOOT_DIRECTORY = 0x301,
+    OPTION_ROOT_DIRECTORY,
+    OPTION_TARGET,
+    OPTION_SETUP,
+    OPTION_MKRELPATH, 
+    OPTION_MKDEVICEMAP, 
+    OPTION_PROBE, 
+    OPTION_EDITENV, 
+    OPTION_ALLOW_FLOPPY, 
+    OPTION_RECHECK, 
+    OPTION_FORCE,
+    OPTION_FORCE_FILE_ID,
+    OPTION_MODULE, 
+    OPTION_NO_NVRAM, 
+    OPTION_REMOVABLE, 
+    OPTION_BOOTLOADER_ID, 
+    OPTION_EFI_DIRECTORY,
+    OPTION_FONT,
+    OPTION_DEBUG,
+    OPTION_DEBUG_IMAGE,
+    OPTION_NO_FLOPPY,
+    OPTION_DISK_MODULE
+  };
+
+static int fs_probe = 1;
+
+static error_t 
+argp_parser (int key, char *arg, struct argp_state *state)
+{
+  if (grub_install_parse (key, arg))
+    return 0;
+  switch (key)
+    {
+    case OPTION_FORCE_FILE_ID:
+      force_file_id = 1;
+      return 0;
+    case 's':
+      fs_probe = 0;
+      return 0;
+
+      /* Accept and ignore for compatibility.  */
+    case OPTION_FONT:
+    case OPTION_SETUP:
+    case OPTION_MKRELPATH:
+    case OPTION_PROBE:
+    case OPTION_EDITENV:
+    case OPTION_MKDEVICEMAP:
+    case OPTION_NO_FLOPPY:
+      return 0;
+    case OPTION_ROOT_DIRECTORY:
+      /* Accept for compatibility.  */
+      free (rootdir);
+      rootdir = xstrdup (arg);
+      return 0;
+
+    case OPTION_BOOT_DIRECTORY:
+      free (bootdir);
+      bootdir = xstrdup (arg);
+      return 0;
+
+    case OPTION_EFI_DIRECTORY:
+      free (efidir);
+      efidir = xstrdup (arg);
+      return 0;
+
+    case OPTION_DISK_MODULE:
+      free (disk_module);
+      disk_module = xstrdup (arg);
+      return 0;
+
+    case OPTION_TARGET:
+      free (target);
+      target = xstrdup (arg);
+      return 0;
+
+    case OPTION_DEBUG_IMAGE:
+      free (debug_image);
+      debug_image = xstrdup (arg);
+      return 0;
+
+    case OPTION_NO_NVRAM:
+      update_nvram = 0;
+      return 0;
+
+    case OPTION_FORCE:
+      force = 1;
+      return 0;
+
+    case OPTION_RECHECK:
+      recheck = 1;
+      return 0;
+
+    case OPTION_REMOVABLE:
+      removable = 1;
+      return 0;
+
+    case OPTION_ALLOW_FLOPPY:
+      allow_floppy = 1;
+      return 0;
+
+    case OPTION_DEBUG:
+      verbosity++;
+      return 0;
+
+    case OPTION_BOOTLOADER_ID:
+      free (bootloader_id);
+      bootloader_id = xstrdup (arg);
+      return 0;
+
+    case ARGP_KEY_ARG:
+      if (install_device)
+       grub_util_error ("%s", _("More than one install device?"));
+      install_device = xstrdup (arg);
+      return 0;
+
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+}
+
+
+static struct argp_option options[] = {
+  GRUB_INSTALL_OPTIONS,
+  {"boot-directory", OPTION_BOOT_DIRECTORY, N_("DIR"),
+   0, N_("install GRUB images under the directory DIR/%s instead of the %s directory"), 2},
+  {"root-directory", OPTION_ROOT_DIRECTORY, N_("DIR"),
+   OPTION_HIDDEN, 0, 2},
+  {"font", OPTION_FONT, N_("FILE"),
+   OPTION_HIDDEN, 0, 2},
+  {"target", OPTION_TARGET, N_("TARGET"),
+   /* TRANSLATORS: "TARGET" as in "target platform".  */
+   0, N_("install GRUB for TARGET platform [default=%s]"), 2},
+  {"grub-setup", OPTION_SETUP, "FILE", OPTION_HIDDEN, 0, 2},
+  {"grub-mkrelpath", OPTION_MKRELPATH, "FILE", OPTION_HIDDEN, 0, 2},
+  {"grub-mkdevicemap", OPTION_MKDEVICEMAP, "FILE", OPTION_HIDDEN, 0, 2},
+  {"grub-probe", OPTION_PROBE, "FILE", OPTION_HIDDEN, 0, 2},
+  {"grub-editenv", OPTION_EDITENV, "FILE", OPTION_HIDDEN, 0, 2},
+  {"allow-floppy", OPTION_ALLOW_FLOPPY, 0, 0,
+   /* TRANSLATORS: "may break" doesn't just mean that option wouldn't have any
+      effect but that it will make the resulting install unbootable from HDD. */
+   N_("make the drive also bootable as floppy (default for fdX devices)."
+      " May break on some BIOSes."), 2},
+  {"recheck", OPTION_RECHECK, 0, 0,
+   N_("delete device map if it already exists"), 2},
+  {"force", OPTION_FORCE, 0, 0,
+   N_("install even if problems are detected"), 2},
+  {"force-file-id", OPTION_FORCE_FILE_ID, 0, 0,
+   N_("use identifier file even if UUID is available"), 2},
+  {"disk-module", OPTION_MODULE, N_("MODULE"), 0,
+   N_("disk module to use (biosdisk or native). "
+      "This option is only available on BIOS target."), 2},
+  {"no-nvram", OPTION_NO_NVRAM, 0, 0,
+   N_("don't update the `boot-device' NVRAM variable. "
+      "This option is only available on IEEE1275 targets."), 2},
+
+  {"debug", OPTION_DEBUG, 0, OPTION_HIDDEN, 0, 2},
+  {"no-floppy", OPTION_NO_FLOPPY, 0, OPTION_HIDDEN, 0, 2},
+  {"debug-image", OPTION_DEBUG_IMAGE, "STR", OPTION_HIDDEN, 0, 2},
+  {"removable", OPTION_REMOVABLE, 0, 0,
+   N_("the installation device is removable. "
+      "This option is only available on EFI."), 2},
+  {"bootloader-id", OPTION_BOOTLOADER_ID, N_("ID"), 0,
+   N_("the ID of bootloader. This option is only available on EFI."), 2},
+  {"efi-directory", OPTION_EFI_DIRECTORY, N_("DIR"), 0,
+   N_("use DIR as the EFI System Partition root."), 2},
+  {"skip-fs-probe",'s',0,      0,
+   N_("do not probe for filesystems in DEVICE"), 0},
+
+  {0, 0, 0, 0, 0, 0}
+};
+
+static const char *
+get_default_platform (void)
+{
+#ifdef __powerpc__
+   return "powerpc-ieee1275";
+#elif defined (__sparc__) || defined (__sparc64__)
+   return "sparc64-ieee1275";
+#elif defined (__MIPSEL__)
+   return "mipsel-loongson";
+#elif defined (__MIPSEB__)
+   return "mips-arc";
+#elif defined (__ia64__)
+   return "ia64-efi";
+#elif defined (__arm__)
+   return "arm-uboot";
+#elif defined (__amd64__) || defined (__x86_64__) || defined (__i386__)
+   return grub_install_get_default_x86_platform ();
+#else
+   return NULL;
+#endif
+}
+
+static char *
+help_filter (int key, const char *text, void *input __attribute__ ((unused)))
+{
+  switch (key)
+    {
+    case OPTION_BOOT_DIRECTORY:
+      return xasprintf (text, GRUB_DIR_NAME, GRUB_BOOT_DIR_NAME "/" GRUB_DIR_NAME);
+    case OPTION_TARGET:
+      return xasprintf (text, get_default_platform ());
+    case ARGP_KEY_HELP_POST_DOC:
+      return xasprintf (text, program_name, GRUB_BOOT_DIR_NAME "/" GRUB_DIR_NAME);
+    default:
+      return grub_install_help_filter (key, text, input);
+    }
+}
+
+/* TRANSLATORS: INSTALL_DEVICE isn't an identifier and is the DEVICE you
+   install to.  */
+struct argp argp = {
+  options, argp_parser, N_("[OPTION] [INSTALL_DEVICE]"),
+  N_("Install GRUB on your drive.")"\v"
+  N_("INSTALL_DEVICE must be system device filename.\n"
+     "%s copies GRUB images into %s.  On some platforms, it"
+     " may also install GRUB into the boot sector."), 
+  NULL, help_filter, NULL
+};
+
+static int
+probe_raid_level (grub_disk_t disk)
+{
+  /* disk might be NULL in the case of a LVM physical volume with no LVM
+     signature.  Ignore such cases here.  */
+  if (!disk)
+    return -1;
+
+  if (disk->dev->id != GRUB_DISK_DEVICE_DISKFILTER_ID)
+    return -1;
+
+  if (disk->name[0] != 'm' || disk->name[1] != 'd')
+    return -1;
+
+  if (!((struct grub_diskfilter_lv *) disk->data)->segments)
+    return -1;
+  return ((struct grub_diskfilter_lv *) disk->data)->segments->type;
+}
+
+static void
+probe_mods (grub_disk_t disk)
+{
+  grub_partition_t part;
+  grub_disk_memberlist_t list = NULL, tmp;
+  int raid_level;
+
+  if (disk->partition == NULL)
+    grub_util_info ("no partition map found for %s", disk->name);
+
+  for (part = disk->partition; part; part = part->parent)
+    {
+      char buf[50];
+      if (strcmp (part->partmap->name, "openbsd") == 0
+         || strcmp (part->partmap->name, "netbsd") == 0)
+       {
+         grub_install_push_module ("part_bsd");
+         continue;
+       }
+      snprintf (buf, sizeof (buf), "part_%s", part->partmap->name);
+      grub_install_push_module (buf);
+    }
+
+  if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID)
+    {
+      grub_diskfilter_get_partmap (disk, grub_install_push_module);
+      have_abstractions = 1;
+    }
+
+  if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID
+      && (grub_memcmp (disk->name, "lvm/", sizeof ("lvm/") - 1) == 0 ||
+         grub_memcmp (disk->name, "lvmid/", sizeof ("lvmid/") - 1) == 0))
+    grub_install_push_module ("lvm");
+
+  if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID
+      && grub_memcmp (disk->name, "ldm/", sizeof ("ldm/") - 1) == 0)
+    grub_install_push_module ("ldm");
+
+  if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID)
+    {
+      grub_util_cryptodisk_get_abstraction (disk,
+                                           grub_install_push_module);
+      have_abstractions = 1;
+      have_cryptodisk = 1;
+    }
+
+  raid_level = probe_raid_level (disk);
+  if (raid_level >= 0)
+    {
+      grub_install_push_module ("diskfilter");
+      if (disk->dev->raidname)
+       grub_install_push_module (disk->dev->raidname (disk));
+    }
+  if (raid_level == 5)
+    grub_install_push_module ("raid5rec");
+  if (raid_level == 6)
+    grub_install_push_module ("raid6rec");
+
+  /* In case of LVM/RAID, check the member devices as well.  */
+  if (disk->dev->memberlist)
+    list = disk->dev->memberlist (disk);
+  while (list)
+    {
+      probe_mods (list->disk);
+      tmp = list->next;
+      free (list);
+      list = tmp;
+    }
+}
+
+static int
+have_bootdev (enum grub_install_plat pl)
+{
+  switch (pl)
+    {
+    case GRUB_INSTALL_PLATFORM_I386_PC:
+    case GRUB_INSTALL_PLATFORM_I386_EFI:
+    case GRUB_INSTALL_PLATFORM_X86_64_EFI:
+    case GRUB_INSTALL_PLATFORM_IA64_EFI:
+    case GRUB_INSTALL_PLATFORM_ARM_EFI:
+    case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
+    case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
+    case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
+    case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
+    case GRUB_INSTALL_PLATFORM_MIPS_ARC:
+      return 1;
+
+    case GRUB_INSTALL_PLATFORM_I386_QEMU:
+    case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
+    case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
+    case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
+    case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
+
+    case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
+    case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
+      return 0;
+
+      /* pacify warning.  */
+    case GRUB_INSTALL_PLATFORM_MAX:
+      return 0;
+    }
+  return 0;
+}
+
+static void
+probe_cryptodisk_uuid (grub_disk_t disk)
+{
+  grub_disk_memberlist_t list = NULL, tmp;
+
+  /* In case of LVM/RAID, check the member devices as well.  */
+  if (disk->dev->memberlist)
+    {
+      list = disk->dev->memberlist (disk);
+    }
+  while (list)
+    {
+      probe_cryptodisk_uuid (list->disk);
+      tmp = list->next;
+      free (list);
+      list = tmp;
+    }
+  if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID)
+    {
+      const char *uuid = grub_util_cryptodisk_get_uuid (disk);
+      if (!load_cfg_f)
+       load_cfg_f = grub_util_fopen (load_cfg, "wb");
+      have_load_cfg = 1;
+
+      fprintf (load_cfg_f, "cryptomount -u %s\n",
+             uuid);
+    }
+}
+
+static int
+is_same_disk (const char *a, const char *b)
+{
+  while (1)
+    {
+      if ((*a == ',' || *a == '\0') && (*b == ',' || *b == '\0'))
+       return 1;
+      if (*a != *b)
+       return 0;
+      if (*a == '\\')
+       {
+         if (a[1] != b[1])
+           return 0;
+         a += 2;
+         b += 2;
+         continue;
+       }
+      a++;
+      b++;
+    }
+}
+
+char *
+get_rndstr (void)
+{
+  grub_uint8_t rnd[15];
+  const size_t sz = sizeof (rnd) * GRUB_CHAR_BIT / 5;
+  char * ret = xmalloc (sz + 1);
+  size_t i;
+  if (grub_get_random (rnd, sizeof (rnd)))
+    grub_util_error ("%s", _("couldn't retrieve random data"));
+  for (i = 0; i < sz; i++)
+    {
+      grub_size_t b = i * 5;
+      grub_uint8_t r;
+      grub_size_t f1 = GRUB_CHAR_BIT - b % GRUB_CHAR_BIT;
+      grub_size_t f2;
+      if (f1 > 5)
+       f1 = 5;
+      f2 = 5 - f1;
+      r = (rnd[b / GRUB_CHAR_BIT] >> (b % GRUB_CHAR_BIT)) & ((1 << f1) - 1);
+      if (f2)
+       r |= (rnd[b / GRUB_CHAR_BIT + 1] & ((1 << f2) - 1)) << f1;
+      if (r < 10)
+       ret[i] = '0' + r;
+      else
+       ret[i] = 'a' + (r - 10);
+    }
+  ret[sz] = '\0';
+  return ret;
+}
+
+static char *
+escape (const char *in)
+{
+  char *ptr;
+  char *ret;
+  int overhead = 0;
+
+  for (ptr = (char*)in; *ptr; ptr++)
+    if (*ptr == '\'')
+      overhead += 3;
+  ret = grub_malloc (ptr - in + overhead + 1);
+  if (!ret)
+    return NULL;
+
+  grub_strchrsub (ret, in, '\'', "'\\''");
+  return ret;
+}
+
+static struct grub_util_config config;
+
+static void
+device_map_check_duplicates (const char *dev_map)
+{
+  FILE *fp;
+  char buf[1024];      /* XXX */
+  size_t alloced = 8;
+  size_t filled = 0;
+  char **d;
+  size_t i;
+
+  d = xmalloc (alloced * sizeof (d[0]));
+
+  if (dev_map[0] == '\0')
+    return;
+
+  fp = grub_util_fopen (dev_map, "r");
+  if (! fp)
+    return;
+
+  while (fgets (buf, sizeof (buf), fp))
+    {
+      char *p = buf;
+      char *e;
+
+      /* Skip leading spaces.  */
+      while (*p && grub_isspace (*p))
+       p++;
+
+      /* If the first character is `#' or NUL, skip this line.  */
+      if (*p == '\0' || *p == '#')
+       continue;
+
+      if (*p != '(')
+       continue;
+
+      p++;
+
+      e = p;
+      p = strchr (p, ')');
+      if (! p)
+       continue;
+
+      if (filled >= alloced)
+       {
+         alloced *= 2;
+         d = xrealloc (d, alloced * sizeof (d[0]));
+       }
+
+      *p = '\0';
+
+      d[filled++] = xstrdup (e);
+    }
+
+  fclose (fp);
+
+  qsort (d, filled, sizeof (d[0]), (int (*) (const void *, const void *))strcmp);
+
+  for (i = 0; i + 1 < filled; i++)
+    if (strcmp (d[i], d[i+1]) == 0)
+      {
+       grub_util_error ("the drive %s is defined multiple times in the device map %s",
+                        d[i], dev_map);
+      }
+
+  for (i = 0; i < filled; i++)
+    free (d[i]);
+
+  free (d);
+}
+
+static grub_err_t
+write_to_disk (grub_device_t dev, const char *fn)
+{
+  char *core_img;
+  size_t core_size;
+  grub_err_t err;
+
+  core_size = grub_util_get_image_size (fn);
+
+  core_img = grub_util_read_image (fn);    
+
+  err = grub_disk_write (dev->disk, 0, 0,
+                        core_size, core_img);
+  free (core_img);
+  return err;
+}
+
+static int
+is_prep_partition (grub_device_t dev)
+{
+  if (!dev->disk)
+    return 0;
+  if (!dev->disk->partition)
+    return 0;
+  if (strcmp(dev->disk->partition->partmap->name, "msdos") == 0)
+    return (dev->disk->partition->msdostype == 0x41);
+
+  if (strcmp (dev->disk->partition->partmap->name, "gpt") == 0)
+    {
+      struct grub_gpt_partentry gptdata;
+      grub_partition_t p = dev->disk->partition;
+      int ret = 0;
+      dev->disk->partition = dev->disk->partition->parent;
+
+      if (grub_disk_read (dev->disk, p->offset, p->index,
+                         sizeof (gptdata), &gptdata) == 0)
+       {
+         const grub_gpt_part_type_t template = {
+           grub_cpu_to_le32_compile_time (0x9e1a2d38),
+           grub_cpu_to_le16_compile_time (0xc612),
+           grub_cpu_to_le16_compile_time (0x4316),
+           { 0xaa, 0x26, 0x8b, 0x49, 0x52, 0x1e, 0x5a, 0x8b }
+         };
+
+         ret = grub_memcmp (&template, &gptdata.type,
+                            sizeof (template)) == 0;
+       }
+      dev->disk->partition = p;
+      return ret;
+    }
+
+  return 0;
+}
+
+static int
+is_prep_empty (grub_device_t dev)
+{
+  grub_disk_addr_t dsize, addr;
+  grub_uint32_t buffer[32768];
+
+  dsize = grub_disk_get_size (dev->disk);
+  for (addr = 0; addr < dsize;
+       addr += sizeof (buffer) / GRUB_DISK_SECTOR_SIZE)
+    {
+      grub_size_t sz = sizeof (buffer);
+      grub_uint32_t *ptr;
+
+      if (sizeof (buffer) / GRUB_DISK_SECTOR_SIZE > dsize - addr)
+       sz = (dsize - addr) * GRUB_DISK_SECTOR_SIZE;
+      grub_disk_read (dev->disk, addr, 0, sz, buffer);
+
+      if (addr == 0 && grub_memcmp (buffer, ELFMAG, SELFMAG) == 0)
+       return 1;
+
+      for (ptr = buffer; ptr < buffer + sz / sizeof (*buffer); ptr++)
+       if (*ptr)
+         return 0;
+    }
+
+  return 1;
+}
+
+int
+main (int argc, char *argv[])
+{
+  int is_efi = 0;
+  const char *efi_distributor = NULL;
+  const char *efi_file = NULL;
+  char **grub_devices;
+  grub_fs_t grub_fs;
+  grub_device_t grub_dev = NULL;
+  enum grub_install_plat platform;
+  char *grubdir, *device_map;
+  char **curdev, **curdrive;
+  char **grub_drives;
+  char *relative_grubdir;
+  char **efidir_device_names = NULL;
+  grub_device_t efidir_grub_dev = NULL;
+  char *efidir_grub_devname;
+
+  grub_util_host_init (&argc, &argv);
+
+  argp_parse (&argp, argc, argv, 0, 0, 0);
+
+  if (verbosity > 1)
+    grub_env_set ("debug", "all");
+
+  grub_util_load_config (&config);
+
+  if (!bootloader_id && config.grub_distributor)
+    {
+      char *ptr;
+      bootloader_id = xstrdup (config.grub_distributor);
+      for (ptr = bootloader_id; *ptr && *ptr != ' '; ptr++)
+       if (*ptr >= 'A' && *ptr <= 'Z')
+         *ptr = *ptr - 'A' + 'a';
+      *ptr = '\0';
+    }
+  if (!bootloader_id || bootloader_id[0] == '\0')
+    {
+      free (bootloader_id);
+      bootloader_id = xstrdup ("grub");
+    }
+
+  if (!grub_install_source_directory)
+    {
+      if (!target)
+       {
+         const char * t;
+         t = get_default_platform ();
+         if (!t)
+           grub_util_error ("%s", 
+                            _("Unable to determine your platform."
+                              " Use --target.")
+                            );
+         target = xstrdup (t); 
+       }
+      grub_install_source_directory
+       = grub_util_path_concat (2, grub_util_get_pkglibdir (), target);
+    }
+
+  platform = grub_install_get_target (grub_install_source_directory);
+
+  switch (platform)
+    {
+    case GRUB_INSTALL_PLATFORM_I386_PC:
+      if (!disk_module)
+       disk_module = xstrdup ("biosdisk");
+      break;
+    case GRUB_INSTALL_PLATFORM_I386_EFI:
+    case GRUB_INSTALL_PLATFORM_X86_64_EFI:
+    case GRUB_INSTALL_PLATFORM_ARM_EFI:
+    case GRUB_INSTALL_PLATFORM_IA64_EFI:
+    case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
+    case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
+    case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
+    case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
+    case GRUB_INSTALL_PLATFORM_MIPS_ARC:
+    case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
+      break;
+
+    case GRUB_INSTALL_PLATFORM_I386_QEMU:
+    case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
+    case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
+    case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
+    case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
+    case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
+      disk_module = xstrdup ("native");
+      break;
+
+      /* pacify warning.  */
+    case GRUB_INSTALL_PLATFORM_MAX:
+      break;
+    }
+
+  switch (platform)
+    {
+    case GRUB_INSTALL_PLATFORM_I386_PC:
+    case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
+      if (!install_device)
+       grub_util_error ("%s", _("install device isn't specified"));
+      break;
+    case GRUB_INSTALL_PLATFORM_MIPS_ARC:
+    case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
+    case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
+      break;
+    case GRUB_INSTALL_PLATFORM_I386_EFI:
+    case GRUB_INSTALL_PLATFORM_X86_64_EFI:
+    case GRUB_INSTALL_PLATFORM_ARM_EFI:
+    case GRUB_INSTALL_PLATFORM_IA64_EFI:
+    case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
+    case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
+    case GRUB_INSTALL_PLATFORM_I386_QEMU:
+    case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
+    case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
+    case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
+    case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
+    case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
+      free (install_device);
+      install_device = NULL;
+      break;
+
+      /* pacify warning.  */
+    case GRUB_INSTALL_PLATFORM_MAX:
+      break;
+    }
+
+  if (!bootdir)
+    bootdir = grub_util_path_concat (3, "/", rootdir, GRUB_BOOT_DIR_NAME);
+
+  {
+    char * t = grub_util_path_concat (2, bootdir, GRUB_DIR_NAME);
+    grub_install_mkdir_p (t);
+    grubdir = canonicalize_file_name (t);
+    if (!grubdir)
+      grub_util_error (_("failed to get canonical path of `%s'"), t);
+    free (t);
+  }
+  device_map = grub_util_path_concat (2, grubdir, "device.map");
+
+  if (recheck)
+    grub_util_unlink (device_map);
+
+  device_map_check_duplicates (device_map);
+  grub_util_biosdisk_init (device_map);
+
+  /* Initialize all modules. */
+  grub_init_all ();
+  grub_gcry_init_all ();
+  switch (platform)
+    {
+    case GRUB_INSTALL_PLATFORM_I386_EFI:
+    case GRUB_INSTALL_PLATFORM_X86_64_EFI:
+    case GRUB_INSTALL_PLATFORM_ARM_EFI:
+    case GRUB_INSTALL_PLATFORM_IA64_EFI:
+      is_efi = 1;
+      break;
+    default:
+      is_efi = 0;
+      break;
+
+      /* pacify warning.  */
+    case GRUB_INSTALL_PLATFORM_MAX:
+      break;
+    }
+
+  /* Find the EFI System Partition.  */
+
+  if (is_efi)
+    {
+      grub_fs_t fs;
+      free (install_device);
+      install_device = NULL;
+      if (!efidir)
+       {
+         char *d = grub_util_path_concat (2, bootdir, "efi");
+         char *dr = NULL;
+         if (!grub_util_is_directory (d))
+           {
+             free (d);
+             d = grub_util_path_concat (2, bootdir, "EFI");
+           }
+         /*
+           The EFI System Partition may have been given directly using
+           --root-directory.
+         */
+         if (!grub_util_is_directory (d)
+             && rootdir && grub_strcmp (rootdir, "/") != 0)
+           {
+             free (d);
+             d = xstrdup (rootdir);
+           }
+         if (grub_util_is_directory (d))
+           dr = grub_make_system_path_relative_to_its_root (d);
+         /* Is it a mount point? */
+         if (dr && dr[0] == '\0')
+           efidir = d;
+         else
+           free (d);
+         free (dr);
+       }
+      if (!efidir)
+       grub_util_error ("%s", _("cannot find EFI directory"));
+      efidir_device_names = grub_guess_root_devices (efidir);
+      if (!efidir_device_names || !efidir_device_names[0])
+       grub_util_error (_("cannot find a device for %s (is /dev mounted?)"),
+                            efidir);
+      install_device = efidir_device_names[0];
+
+      for (curdev = efidir_device_names; *curdev; curdev++)
+         grub_util_pull_device (*curdev);
+      
+      efidir_grub_devname = grub_util_get_grub_dev (efidir_device_names[0]);
+      if (!efidir_grub_devname)
+       grub_util_error (_("cannot find a GRUB drive for %s.  Check your device.map"),
+                        efidir_device_names[0]);
+
+      efidir_grub_dev = grub_device_open (efidir_grub_devname);
+      if (! efidir_grub_dev)
+       grub_util_error ("%s", grub_errmsg);
+
+      fs = grub_fs_probe (efidir_grub_dev);
+      if (! fs)
+       grub_util_error ("%s", grub_errmsg);
+
+      if (grub_strcmp (fs->name, "fat") != 0)
+       grub_util_error (_("%s doesn't look like an EFI partition.\n"), efidir);
+
+      /* The EFI specification requires that an EFI System Partition must
+        contain an "EFI" subdirectory, and that OS loaders are stored in
+        subdirectories below EFI.  Vendors are expected to pick names that do
+        not collide with other vendors.  To minimise collisions, we use the
+        name of our distributor if possible.
+      */
+      char *t;
+      efi_distributor = bootloader_id;
+      if (removable)
+       {
+         /* The specification makes stricter requirements of removable
+            devices, in order that only one image can be automatically loaded
+            from them.  The image must always reside under /EFI/BOOT, and it
+            must have a specific file name depending on the architecture.
+         */
+         efi_distributor = "BOOT";
+         switch (platform)
+           {
+           case GRUB_INSTALL_PLATFORM_I386_EFI:
+             efi_file = "BOOTIA32.EFI";
+             break;
+           case GRUB_INSTALL_PLATFORM_X86_64_EFI:
+             efi_file = "BOOTX64.EFI";
+             break;
+           case GRUB_INSTALL_PLATFORM_IA64_EFI:
+             efi_file = "BOOTIA64.EFI";
+             break;
+           case GRUB_INSTALL_PLATFORM_ARM_EFI:
+             efi_file = "BOOTARM.EFI";
+             break;
+           default:
+             grub_util_error ("%s", _("You've found a bug"));
+             break;
+           }
+       }
+      else
+       {
+         /* It is convenient for each architecture to have a different
+            efi_file, so that different versions can be installed in parallel.
+         */
+         switch (platform)
+           {
+           case GRUB_INSTALL_PLATFORM_I386_EFI:
+             efi_file = "grubia32.efi";
+             break;
+           case GRUB_INSTALL_PLATFORM_X86_64_EFI:
+             efi_file = "grubx64.efi";
+             break;
+           case GRUB_INSTALL_PLATFORM_IA64_EFI:
+             efi_file = "grubia64.efi";
+             break;
+           case GRUB_INSTALL_PLATFORM_ARM_EFI:
+             efi_file = "grubarm.efi";
+             break;
+           default:
+             efi_file = "grub.efi";
+             break;
+           }
+       }
+      t = grub_util_path_concat (3, efidir, "EFI", efi_distributor);
+      free (efidir);
+      efidir = t;
+      grub_install_mkdir_p (efidir);
+    }
+
+  grub_install_copy_files (grub_install_source_directory,
+                          grubdir, platform);
+
+  char *envfile = grub_util_path_concat (2, grubdir, "grubenv");
+  if (!grub_util_is_regular (envfile))
+    grub_util_create_envblk_file (envfile);
+
+  size_t ndev = 0;
+
+  /* Write device to a variable so we don't have to traverse /dev every time.  */
+  grub_devices = grub_guess_root_devices (grubdir);
+  if (!grub_devices || !grub_devices[0])
+    grub_util_error (_("cannot find a device for %s (is /dev mounted?)"),
+                    grubdir);
+
+  for (curdev = grub_devices; *curdev; curdev++)
+    {
+      grub_util_pull_device (*curdev);
+      ndev++;
+    }
+
+  grub_drives = xmalloc (sizeof (grub_drives[0]) * (ndev + 1)); 
+
+  for (curdev = grub_devices, curdrive = grub_drives; *curdev; curdev++,
+       curdrive++)
+    {
+      *curdrive = grub_util_get_grub_dev (*curdev);
+      if (! *curdrive)
+       grub_util_error (_("cannot find a GRUB drive for %s.  Check your device.map"),
+                        *curdev);
+    }
+  *curdrive = 0;
+
+  grub_dev = grub_device_open (grub_drives[0]);
+  if (! grub_dev)
+    grub_util_error ("%s", grub_errmsg);
+
+  grub_fs = grub_fs_probe (grub_dev);
+  if (! grub_fs)
+    grub_util_error ("%s", grub_errmsg);
+
+  grub_install_push_module (grub_fs->name);
+
+  if (grub_dev->disk)
+    probe_mods (grub_dev->disk);
+
+  for (curdrive = grub_drives + 1; *curdrive; curdrive++)
+    {
+      grub_device_t dev = grub_device_open (*curdrive);
+      if (!dev)
+       continue;
+      if (dev->disk)
+       probe_mods (dev->disk);
+      grub_device_close (dev);
+    }
+
+  if (!config.is_cryptodisk_enabled && have_cryptodisk)
+    grub_util_error (_("attempt to install to cryptodisk without cryptodisk enabled. "
+                      "Set `%s' in file `%s'."), "GRUB_ENABLE_CRYPTODISK=1",
+                    grub_util_get_config_filename ());
+
+  if (disk_module && grub_strcmp (disk_module, "ata") == 0)
+    grub_install_push_module ("pata");
+  else if (disk_module && grub_strcmp (disk_module, "native") == 0)
+    {
+      grub_install_push_module ("pata");
+      grub_install_push_module ("ahci");
+      grub_install_push_module ("ohci");
+      grub_install_push_module ("uhci");
+      grub_install_push_module ("usbms");
+    }
+  else if (disk_module && disk_module[0])
+    grub_install_push_module (disk_module);
+
+  relative_grubdir = grub_make_system_path_relative_to_its_root (grubdir);
+  if (relative_grubdir[0] == '\0')
+    {
+      free (relative_grubdir);
+      relative_grubdir = xstrdup ("/");
+    }
+
+  char *platname =  grub_install_get_platform_name (platform);
+  char *platdir;
+  {
+    char *t = grub_util_path_concat (2, grubdir,
+                                  platname);
+    platdir = canonicalize_file_name (t);
+    if (!platdir)
+      grub_util_error (_("failed to get canonical path of `%s'"),
+                      t);
+    free (t);
+  }
+  load_cfg = grub_util_path_concat (2, platdir,
+                                 "load.cfg");
+
+  grub_util_unlink (load_cfg);
+
+  if (debug_image && debug_image[0])
+    {
+      load_cfg_f = grub_util_fopen (load_cfg, "wb");
+      have_load_cfg = 1;
+      fprintf (load_cfg_f, "set debug='%s'\n",
+             debug_image);
+    }
+  char *prefix_drive = NULL;
+  char *install_drive = NULL;
+
+  if (install_device)
+    {
+      if (install_device[0] == '('
+         && install_device[grub_strlen (install_device) - 1] == ')')
+       install_drive = xstrdup (install_device);
+      else
+       {
+         grub_util_pull_device (install_device);
+         install_drive = grub_util_get_grub_dev (install_device);
+         if (!install_drive)
+           grub_util_error (_("cannot find a GRUB drive for %s.  Check your device.map"),
+                            install_device);
+       }
+    }
+
+  if (!have_abstractions)
+    {
+      if ((disk_module && grub_strcmp (disk_module, "biosdisk") != 0)
+         || grub_drives[1]
+         || (!install_drive
+             && platform != GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275)
+         || (install_drive && !is_same_disk (grub_drives[0], install_drive))
+         || !have_bootdev (platform))
+       {
+         char *uuid = NULL;
+         /*  generic method (used on coreboot and ata mod).  */
+         if (!force_file_id && grub_fs->uuid && grub_fs->uuid (grub_dev,
+                                                               &uuid))
+           {
+             grub_print_error ();
+             grub_errno = 0;
+             uuid = NULL;
+           }
+
+         if (!load_cfg_f)
+           load_cfg_f = grub_util_fopen (load_cfg, "wb");
+         have_load_cfg = 1;
+         if (uuid)
+           {
+             fprintf (load_cfg_f, "search.fs_uuid %s root ",
+                     uuid);
+             grub_install_push_module ("search_fs_uuid");
+           }
+         else
+           {
+             char *rndstr = get_rndstr ();
+             char *fl = grub_util_path_concat (3, grubdir,
+                                                    "uuid", rndstr);
+             char *fldir = grub_util_path_concat (2, grubdir,
+                                                       "uuid");
+             char *relfl;
+             FILE *flf;
+             grub_install_mkdir_p (fldir);
+             flf = grub_util_fopen (fl, "w");
+             if (!flf)
+               grub_util_error ("Can't create file: %s", strerror (errno));
+             fclose (flf);
+             relfl = grub_make_system_path_relative_to_its_root (fl);
+             fprintf (load_cfg_f, "search.file %s root ",
+                      relfl);
+             grub_install_push_module ("search_fs_file");
+           }
+         for (curdev = grub_devices, curdrive = grub_drives; *curdev; curdev++,
+                curdrive++)
+           {
+             const char *map;
+             char *g = NULL;
+             grub_device_t dev;
+             if (curdrive == grub_drives)
+               dev = grub_dev;
+             else
+               dev = grub_device_open (*curdrive);
+             if (!dev)
+               continue;
+
+             if (dev->disk->dev->id != GRUB_DISK_DEVICE_HOSTDISK_ID)
+               {
+                 grub_util_fprint_full_disk_name (load_cfg_f,
+                                                  dev->disk->name,
+                                                  dev);
+                 fprintf (load_cfg_f, " ");
+                 if (dev != grub_dev)
+                   grub_device_close (dev);
+                 continue;
+               }
+
+             map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
+
+             if (map)
+               {
+                 grub_util_fprint_full_disk_name (load_cfg_f, map, dev);
+                 fprintf (load_cfg_f, " ");
+               }
+
+
+             if (disk_module && disk_module[0]
+                 && grub_strcmp (disk_module, "biosdisk") != 0)
+                 g = grub_util_guess_baremetal_drive (*curdev);
+             else
+               switch (platform)
+                 {
+                 case GRUB_INSTALL_PLATFORM_I386_PC:
+                   g = grub_util_guess_bios_drive (*curdev);
+                   break;
+                 case GRUB_INSTALL_PLATFORM_I386_EFI:
+                 case GRUB_INSTALL_PLATFORM_X86_64_EFI:
+                 case GRUB_INSTALL_PLATFORM_ARM_EFI:
+                 case GRUB_INSTALL_PLATFORM_IA64_EFI:
+                   g = grub_util_guess_efi_drive (*curdev);
+                   break;
+                 case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
+                 case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
+                 case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
+                   {
+                     const char * ofpath = grub_util_devname_to_ofpath (*curdev);
+                     g = xasprintf ("ieee1275/%s", ofpath);
+                     break;
+                   }
+                 case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
+                 case GRUB_INSTALL_PLATFORM_I386_QEMU:
+                 case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
+                 case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
+                 case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
+                 case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
+                   g = grub_util_guess_baremetal_drive (*curdev);
+                   break;
+                 case GRUB_INSTALL_PLATFORM_MIPS_ARC:
+                 case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
+                 case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
+                   grub_util_warn ("%s", _("no hints available for your platform. Expect reduced performance"));
+                   break;
+                   /* pacify warning.  */
+                 case GRUB_INSTALL_PLATFORM_MAX:
+                   break;
+                 }
+             if (g)
+               {
+                 grub_util_fprint_full_disk_name (load_cfg_f, g, dev);
+                 fprintf (load_cfg_f, " ");
+               }
+             if (dev != grub_dev)
+               grub_device_close (dev);
+           }
+         fprintf (load_cfg_f, "\n");
+         char *escaped_relpath = escape (relative_grubdir);
+         fprintf (load_cfg_f, "set prefix=($root)'%s'\n",
+                  escaped_relpath);
+       }
+      else
+       {
+         /* We need to hardcode the partition number in the core image's prefix.  */
+         char *p;
+         for (p = grub_drives[0]; *p; )
+           {
+             if (*p == '\\' && p[1])
+               {
+                 p += 2;
+                 continue;
+               }
+             if (*p == ',' || *p == '\0')
+               break;
+             p++;
+           }
+         prefix_drive = xasprintf ("(%s)", p);
+       }
+    }
+  else
+    {
+      if (config.is_cryptodisk_enabled)
+       {
+         if (grub_dev->disk)
+           probe_cryptodisk_uuid (grub_dev->disk);
+
+         for (curdrive = grub_drives + 1; *curdrive; curdrive++)
+           {
+             grub_device_t dev = grub_device_open (*curdrive);
+             if (!dev)
+               continue;
+             if (dev->disk)
+               probe_cryptodisk_uuid (dev->disk);
+             grub_device_close (dev);
+           }
+       }
+      prefix_drive = xasprintf ("(%s)", grub_drives[0]);
+    }
+
+  char mkimage_target[200];
+  const char *core_name = NULL;
+
+  switch (platform)
+    {
+    case GRUB_INSTALL_PLATFORM_I386_EFI:
+    case GRUB_INSTALL_PLATFORM_X86_64_EFI:
+    case GRUB_INSTALL_PLATFORM_ARM_EFI:
+    case GRUB_INSTALL_PLATFORM_IA64_EFI:
+      core_name = "core.efi";
+      snprintf (mkimage_target, sizeof (mkimage_target),
+               "%s-%s",
+               grub_install_get_platform_cpu (platform),
+               grub_install_get_platform_platform (platform));
+      break;
+    case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
+    case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
+    case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
+      core_name = "core.elf";
+      snprintf (mkimage_target, sizeof (mkimage_target),
+               "%s-%s-elf",
+               grub_install_get_platform_cpu (platform),
+               grub_install_get_platform_platform (platform));
+      break;
+
+    case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
+    case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
+    case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
+    case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
+      core_name = "core.elf";
+      snprintf (mkimage_target, sizeof (mkimage_target),
+               "%s-%s",
+               grub_install_get_platform_cpu (platform),
+               grub_install_get_platform_platform (platform));
+      break;
+
+
+    case GRUB_INSTALL_PLATFORM_I386_PC:
+    case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
+    case GRUB_INSTALL_PLATFORM_MIPS_ARC:
+    case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
+    case GRUB_INSTALL_PLATFORM_I386_QEMU:
+      snprintf (mkimage_target, sizeof (mkimage_target),
+               "%s-%s",
+               grub_install_get_platform_cpu (platform),
+               grub_install_get_platform_platform (platform));
+      core_name = "core.img";
+      break;
+    case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
+      strcpy (mkimage_target, "sparc64-ieee1275-raw");
+      core_name = "core.img";
+      break;
+      /* pacify warning.  */
+    case GRUB_INSTALL_PLATFORM_MAX:
+      break;
+    }
+
+  if (!core_name)
+    grub_util_error ("%s", _("You've found a bug"));
+
+  if (load_cfg_f)
+    fclose (load_cfg_f);
+
+  char *imgfile = grub_util_path_concat (2, platdir,
+                                      core_name);
+  char *prefix = xasprintf ("%s%s", prefix_drive ? : "",
+                           relative_grubdir);
+  grub_install_make_image_wrap (/* source dir  */ grub_install_source_directory,
+                               /*prefix */ prefix,
+                               /* output */ imgfile,
+                               /* memdisk */ NULL,
+                               have_load_cfg ? load_cfg : NULL,
+                               /* image target */ mkimage_target,
+                               0, GRUB_COMPRESSION_AUTO);
+  /* Backward-compatibility kludges.  */
+  switch (platform)
+    {
+    case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
+      {
+       char *dst = grub_util_path_concat (2, bootdir, "grub.elf");
+       grub_install_copy_file (imgfile, dst, 1);
+       free (dst);
+      }
+      break;
+
+    case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
+    case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
+      {
+       char *dst = grub_util_path_concat (2, grubdir, "grub");
+       grub_install_copy_file (imgfile, dst, 1);
+       free (dst);
+      }
+      break;
+
+    case GRUB_INSTALL_PLATFORM_I386_EFI:
+    case GRUB_INSTALL_PLATFORM_X86_64_EFI:
+      {
+       char *dst = grub_util_path_concat (2, platdir, "grub.efi");
+       grub_install_make_image_wrap (/* source dir  */ grub_install_source_directory,
+                                     /* prefix */ "",
+                                      /* output */ dst,
+                                      /* memdisk */ NULL,
+                                     have_load_cfg ? load_cfg : NULL,
+                                      /* image target */ mkimage_target,
+                                     0, GRUB_COMPRESSION_AUTO);
+      }
+      break;
+    case GRUB_INSTALL_PLATFORM_ARM_EFI:
+    case GRUB_INSTALL_PLATFORM_IA64_EFI:
+    case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
+    case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
+    case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
+    case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
+    case GRUB_INSTALL_PLATFORM_I386_PC:
+    case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
+    case GRUB_INSTALL_PLATFORM_MIPS_ARC:
+    case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
+    case GRUB_INSTALL_PLATFORM_I386_QEMU:
+    case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
+      break;
+      /* pacify warning.  */
+    case GRUB_INSTALL_PLATFORM_MAX:
+      break;
+    }
+
+  /* Perform the platform-dependent install */
+
+  switch (platform)
+    {
+    case GRUB_INSTALL_PLATFORM_I386_PC:
+      {
+       char *boot_img_src = grub_util_path_concat (2, 
+                                                 grub_install_source_directory,
+                                                 "boot.img");
+       char *boot_img = grub_util_path_concat (2, platdir,
+                                             "boot.img");
+       grub_install_copy_file (boot_img_src, boot_img, 1);
+
+       grub_util_info ("grub_bios_setup %s %s %s %s --directory='%s' --device-map='%s' '%s'",
+                       allow_floppy ? "--allow-floppy " : "",
+                       verbosity ? "--verbose " : "",
+                       force ? "--force " : "",
+                       !fs_probe ? "--skip-fs-probe" : "",
+                       platdir,
+                       device_map,
+                       install_device);
+                       
+       /*  Now perform the installation.  */
+       grub_util_bios_setup (platdir, "boot.img", "core.img",
+                             install_drive, force,
+                             fs_probe, allow_floppy);
+       break;
+      }
+    case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
+      {
+       char *boot_img_src = grub_util_path_concat (2, 
+                                                 grub_install_source_directory,
+                                                 "boot.img");
+       char *boot_img = grub_util_path_concat (2, platdir,
+                                             "boot.img");
+       grub_install_copy_file (boot_img_src, boot_img, 1);
+
+       grub_util_info ("grub_sparc_setup %s %s %s %s --directory='%s' --device-map='%s' '%s'",
+                       allow_floppy ? "--allow-floppy " : "",
+                       verbosity ? "--verbose " : "",
+                       force ? "--force " : "",
+                       !fs_probe ? "--skip-fs-probe" : "",
+                       platdir,
+                       device_map,
+                       install_drive);
+                       
+       /*  Now perform the installation.  */
+       grub_util_sparc_setup (platdir, "boot.img", "core.img",
+                              install_device, force,
+                              fs_probe, allow_floppy);
+       break;
+      }
+
+    case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
+      /* If a install device is defined, copy the core.elf to PReP partition.  */
+      if (install_device && install_device[0])
+       {
+         grub_device_t ins_dev;
+         ins_dev = grub_device_open (install_drive);
+         if (!ins_dev || !is_prep_partition (ins_dev))
+           {
+             grub_util_error ("%s", _("the chosen partition is not a PReP partition"));
+           }
+         if (is_prep_empty (ins_dev))
+           {
+             if (write_to_disk (ins_dev, imgfile))
+               grub_util_error ("%s", _("failed to copy Grub to the PReP partition"));
+           }
+         else
+           {
+             char *s = xasprintf ("dd if=/dev/zero of=%s", install_device);
+             grub_util_error ("the PReP partition is not empty. If you are sure you want to use it, run dd to clear it: `%s'",
+                              s);
+           }
+         grub_device_close (ins_dev);
+      }
+      /* fallthrough.  */
+    case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
+      if (update_nvram)
+       {
+         if (platform != GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275
+             || !install_device
+             || install_device[0] == '\0')
+           {
+             const char *dev;
+             char *relpath;
+             int partno;
+             relpath = grub_make_system_path_relative_to_its_root (imgfile);
+             partno = grub_dev->disk->partition
+               ? grub_dev->disk->partition->number + 1 : 0;
+             dev = grub_util_get_os_disk (grub_devices[0]);
+             grub_install_register_ieee1275 (0, dev,
+                                             partno, relpath);
+           }
+         else
+           grub_install_register_ieee1275 (1, grub_util_get_os_disk (install_device),
+                                           0, NULL);
+       }
+      break;
+    case GRUB_INSTALL_PLATFORM_MIPS_ARC:
+      grub_install_sgi_setup (install_device, imgfile, "grub");
+      break;
+
+    case GRUB_INSTALL_PLATFORM_I386_EFI:
+      {
+       char *dst = grub_util_path_concat (2, efidir, "grub.efi");
+       /* For old macs. Suggested by Peter Jones.  */
+       grub_install_copy_file (imgfile, dst, 1);
+       free (dst);
+      }
+
+    case GRUB_INSTALL_PLATFORM_X86_64_EFI:
+    case GRUB_INSTALL_PLATFORM_ARM_EFI:
+    case GRUB_INSTALL_PLATFORM_IA64_EFI:
+      {
+       char *dst = grub_util_path_concat (2, efidir, efi_file);
+       grub_install_copy_file (imgfile, dst, 1);
+       free (dst);
+      }
+      if (!removable)
+       {
+         char * efidir_disk;
+         int efidir_part;
+         char * efifile_path;
+
+         /* Try to make this image bootable using the EFI Boot Manager, if available.  */
+         if (!efi_distributor || efi_distributor[0] == '\0')
+           grub_util_error ("%s", "EFI distributor id isn't specified.");
+         efidir_disk  = grub_util_get_os_disk (efidir_device_names[0]);
+         efidir_part = efidir_grub_dev->disk->partition ? efidir_grub_dev->disk->partition->number + 1 : 1;
+         efifile_path = xasprintf ("\\EFI\\%s\\%s",
+                                   efi_distributor,
+                                   efi_file);
+         grub_install_register_efi (efidir_disk, efidir_part,
+                                    efifile_path, efi_distributor);
+       }
+      break;
+
+    case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
+    case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
+    case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
+    case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
+    case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
+    case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
+    case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
+    case GRUB_INSTALL_PLATFORM_I386_QEMU:
+      grub_util_warn ("%s",
+                     _("WARNING: no platform-specific install was performed"));
+      break;
+      /* pacify warning.  */
+    case GRUB_INSTALL_PLATFORM_MAX:
+      break;
+    }
+
+  fprintf (stderr, "%s\n", _("Installation finished. No error reported."));
+
+  /* Free resources.  */
+  grub_gcry_fini_all ();
+  grub_fini_all ();
+
+  return 0;
+}
diff --git a/util/grub-install.in b/util/grub-install.in
deleted file mode 100644 (file)
index c022a6b..0000000
+++ /dev/null
@@ -1,829 +0,0 @@
-#! /bin/sh
-
-# Install GRUB on your drive.
-# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009  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 <http://www.gnu.org/licenses/>.
-
-# Initialize some variables.
-sbindir="@sbindir@"
-sysconfdir="@sysconfdir@"
-
-host_os=@host_os@
-target=
-
-grub_probe="${sbindir}/@grub_probe@"
-grub_editenv="${bindir}/@grub_editenv@"
-grub_mkrelpath="${bindir}/@grub_mkrelpath@"
-rootdir=
-bootdir=
-grubdir="`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'`"
-
-install_device=
-force_lba=
-recheck=no
-debug=no
-debug_image=
-
-update_nvram=yes
-
-removable=no
-efi_quiet=-q
-
-# Get GRUB_DISTRIBUTOR.
-if test -f "${sysconfdir}/default/grub" ; then
-    . "${sysconfdir}/default/grub"
-fi
-
-bootloader_id="$(echo "$GRUB_DISTRIBUTOR" | tr 'A-Z' 'a-z' | cut -d' ' -f1)"
-if test -z "$bootloader_id"; then
-    bootloader_id=grub
-fi
-
-disk_module=unspecified
-
-# Usage: usage
-# Print the usage.
-usage () {
-    # TRANSLATORS: INSTALL_DEVICE isn't an identifier and is the DEVICE you
-    # install to.
-    gettext_printf "Usage: %s [OPTION] [INSTALL_DEVICE]" "$self"
-    echo
-    gettext "Install GRUB on your drive." ; echo
-    echo
-    print_option_help "-h, --help" "$(gettext "print this message and exit")"
-    grub_print_install_files_help
-
-    dirmsg="$(gettext_printf "install GRUB images under the directory DIR/%s instead of the %s directory" "@grubdirname@" "$grubdir")"
-    print_option_help "--boot-directory=$(gettext "DIR")" "$dirmsg"
-    # TRANSLATORS: "TARGET" as in "target platform".
-    target_trans="$(gettext "TARGET")"
-    # TRANSLATORS: "current" refers to the platform user's currently running on
-    print_option_help "--target=$target_trans" "$(gettext "install GRUB for TARGET platform [default=current]")"
-    print_option_help "--grub-setup=$(gettext "FILE")" "$(gettext "use FILE as grub-setup")"
-    print_option_help "--grub-mkrelpath=$(gettext "FILE")" "$(gettext "use FILE as grub-mkrelpath")"
-    print_option_help "--grub-probe=$(gettext "FILE")" "$(gettext "use FILE as grub-probe")"
-    print_option_help "--grub-editenv=$(gettext "FILE")" "$(gettext "use FILE as grub-editenv")"
-    # TRANSLATORS: "may break" doesn't just mean that option wouldn't have any
-    # effect but that it will make the resulting install unbootable from HDD.
-    print_option_help "--allow-floppy" "$(gettext "make the drive also bootable as floppy (default for fdX devices). May break on some BIOSes.")"
-    print_option_help "--recheck" "$(gettext "delete device map if it already exists")"
-    print_option_help "--force" "$(gettext "install even if problems are detected")"
-    print_option_help "--force-file-id" "$(gettext "use identifier file even if UUID is available")"
-    print_option_help "--disk-module=$(gettext "MODULE")" "$(gettext "disk module to use (biosdisk or native). This option is only available on BIOS target.")"
-    print_option_help "--no-nvram" "$(gettext "don't update the \`boot-device' NVRAM variable. This option is only available on IEEE1275 targets.")"
-    print_option_help  "--removable" "$(gettext "the installation device is removable. This option is only available on EFI.")"
-    print_option_help  "--bootloader-id=$(gettext "ID")" "$(gettext "the ID of bootloader. This option is only available on EFI.")"
-    print_option_help "--efi-directory=$(gettext "DIR")" "$(gettext "use DIR as the EFI System Partition root.")"
-echo
-gettext "INSTALL_DEVICE must be system device filename.";echo
-echo
-
-gettext_printf "%s copies GRUB images into %s.  On some platforms, it
-may also install GRUB into the boot sector.\n" "$self" "$grubdir";echo
-echo
-gettext "Report bugs to <bug-grub@gnu.org>."; echo
-}
-
-allow_floppy=""
-force_file_id=
-efidir=
-
-# Check the arguments.
-while test $# -gt 0
-do
-    grub_process_install_options "$@"
-    case "$grub_process_install_options_consumed" in
-       1) shift; continue;;
-       2) shift; shift; continue;;
-    esac
-
-    option=$1
-    shift
-
-    case "$option" in
-    -h | --help)
-       usage
-       exit 0 ;;
-
-    --force-file-id)
-       force_file_id=y ;;
-
-# Accept and ignore for compatibility
-    --font)
-        shift;;
-    --font=*)
-       ;;
-
-# Accept for compatibility
-    --root-directory)
-       rootdir="`argument $option "$@"`"; shift;;
-    --root-directory=*)
-       rootdir="`echo "$option" | sed 's/--root-directory=//'`" ;;
-
-    --boot-directory)
-       bootdir="`argument $option "$@"`"; shift;;
-    --boot-directory=*)
-       bootdir="`echo "$option" | sed 's/--boot-directory=//'`" ;;
-
-    --efi-directory)
-       efidir="`argument $option "$@"`"; shift;;
-    --efi-directory=*)
-       efidir="`echo "$option" | sed 's/--efi-directory=//'`" ;;
-
-    --target)
-       target="`argument $option "$@"`"; shift;;
-    --target=*)
-       target="`echo "$option" | sed 's/--target=//'`" ;;
-
-    --grub-setup)
-       grub_setup="`argument "$option" "$@"`"; shift;;
-    --grub-setup=*)
-       grub_setup="`echo "$option" | sed 's/--grub-setup=//'`" ;;
-
-    --bootloader-id)
-       bootloader_id="`argument $option "$@"`"; shift;;
-    --bootloader-id=*)
-       bootloader_id="`echo "$option" | sed 's/--bootloader-id=//'`" ;;
-
-    --grub-mkrelpath)
-       grub_mkrelpath="`argument "$option" "$@"`"; shift;;
-    --grub-mkrelpath=*)
-       grub_mkrelpath="`echo "$option" | sed 's/--grub-mkrelpath=//'`" ;;
-
-       # Ignore: for compatibility
-    --grub-mkdevicemap)
-       shift;;
-    --grub-mkdevicemap=*)
-       ;;
-
-    --grub-probe)
-           grub_probe="`argument "$option" "$@"`"; shift;;
-    --grub-probe=*)
-       grub_probe="`echo "$option" | sed 's/--grub-probe=//'`" ;;
-
-    --grub-editenv)
-           grub_editenv="`argument "$option" "$@"`"; shift;;
-    --grub-editenv=*)
-       grub_editenv="`echo "$option" | sed 's/--grub-editenv=//'`" ;;
-
-    --no-floppy)
-       ;;
-    --recheck)
-       recheck=yes ;;
-    --removable)
-       removable=yes ;;
-
-    --allow-floppy)
-       allow_floppy="--allow-floppy" ;;
-
-    --disk-module)
-       disk_module="`argument "$option" "$@"`"; shift;
-       ;;
-    --disk-module=*)
-        disk_module="`echo "$option" | sed 's/--disk-module=//'`"
-       ;;
-
-    --no-nvram)
-       update_nvram=no ;;
-
-    # This is an undocumented feature...
-    --debug)
-       debug=yes ;;
-    --debug-image)
-       debug_image="`argument "$option" "$@"`"; shift;;
-    --debug-image=*)
-       debug_image="`echo "$option" | sed 's/--debug-image=//'`" ;;
-
-    -f | --force)
-        setup_force="--force" ;;
-
-    -*)
-       gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2
-       usage
-       exit 1
-       ;;
-    *)
-       if test "x$install_device" != x; then
-           gettext "More than one install device?" 1>&2
-           echo 1>&2
-           usage
-           exit 1
-       fi
-       install_device="${option}" ;;
-    esac
-done
-
-if [ x$source_directory = x ]; then
-    if [ x$target = x ]; then
-       case x"`uname -m`" in
-           x"powerpc"* | x"ppc"*)
-               target="powerpc-ieee1275";;
-           x"sparc"*)
-               target="sparc64-ieee1275";;
-           x"mips"*"el")
-               target="mipsel-loongson";;
-           x"mips"*)
-               target="mips-arc";;
-           x"ia64"*)
-               target="ia64-efi";;
-           x"x86_64"* | x"amd64"*)
-                # On Linux, we need the efivars kernel modules.
-               # If no EFI is available this module just does nothing
-               # besides a small hello and if we detect efi we'll load it
-               # anyway later. So it should be safe to
-               # try to load it here.
-               case "$host_os" in
-                   linux*)
-                       modprobe -q efivars 2>/dev/null || true ;;
-               esac
-               if [ -d /sys/firmware/efi ]; then
-                   target="x86_64-efi"
-               else
-                   target=i386-pc
-               fi
-               ;;
-           x"i"?"86"*)
-                # On Linux, we need the efivars kernel modules.
-               # If no EFI is available this module just does nothing
-               # besides a small hello and if we detect efi we'll load it
-               # anyway later. So it should be safe to
-               # try to load it here.
-               case "$host_os" in
-                   linux*)
-                       modprobe -q efivars 2>/dev/null || true ;;
-               esac
-               if [ -d /sys/firmware/efi ]; then
-                   target="i386-efi"
-               elif [ -e /proc/device-tree ]; then
-                   target=i386-pc
-                   for x in /proc/device-tree/*; do
-                       if [ -e "$x" ]; then
-                           target="i386-ieee1275"
-                       fi
-                   done
-               else
-                   target=i386-pc
-               fi
-               ;;
-           x"arm"*)
-               target="arm-uboot";;
-           *)
-               gettext "Unable to determine your platform. Use --target." ;
-               echo    ;;
-       esac
-    fi
-    source_directory="${libdir}/@PACKAGE@/$target"
-fi
-
-if ! [ -d "$source_directory" ]; then
-    gettext_printf "%s doesn't exist. Please specify --target or --directory\\n" "$source_directory"
-    exit 1
-fi
-
-. "${source_directory}"/modinfo.sh
-
-if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ] ; then
-    if [ x$disk_module = xunspecified ]; then
-       disk_module=biosdisk
-    fi
-elif [ "${grub_modinfo_platform}" = "ieee1275" ] || [ "${grub_modinfo_platform}" = "efi" ] || [ "${grub_modinfo_platform}" = "arc" ] || [ "${grub_modinfo_platform}" = "uboot" ] ; then
-    disk_module=
-else
-    disk_module=native
-fi
-
-if test "x$grub_setup" = x && [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ]; then
-    grub_setup="${sbindir}/@grub_bios_setup@"
-fi
-
-if test "x$grub_setup" = x && [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "sparc64-ieee1275" ]; then
-    grub_setup="${sbindir}/@grub_sparc64_setup@"
-fi
-
-if test "x$install_device" = x && ([ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ] \
-    || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "sparc64-ieee1275" ]); then
-    gettext "Install device isn't specified." 1>&2
-    echo 1>&2
-    usage
-    exit 1
-fi
-
-if ! ([ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ] \
-    || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "sparc64-ieee1275" ] \
-    || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "powerpc-ieee1275" ] \
-    || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "mips-arc" ]); then
-    install_device=
-fi
-
-# If the debugging feature is enabled, print commands.
-setup_verbose=
-if test x"$debug" = xyes; then
-    set -x
-    setup_verbose="--verbose"
-    efi_quiet=
-fi
-
-if [ -z "$bootdir" ]; then
-    # Default bootdir if bootdir not initialized.
-    bootdir="/@bootdirname@"
-
-    if [ -n "$rootdir" ] ; then
-        # Initialize bootdir if rootdir was initialized.
-        bootdir="${rootdir}/@bootdirname@"
-    fi
-fi
-
-grubdir="`echo "${bootdir}/@grubdirname@" | sed 's,//*,/,g'`"
-device_map="${grubdir}/device.map"
-
-
-# Check if GRUB is installed.
-if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "sparc64-ieee1275" ] ; then
-    set $grub_setup dummy
-    if test -f "$1"; then
-        :
-    else
-       # TRANSLATORS: This message is shown when required executable `%s'
-       # isn't found
-        gettext_printf "%s: Not found.\n" "$1" 1>&2
-        exit 1
-    fi
-fi
-
-set "$grub_mkimage" dummy
-if test -f "$1"; then
-    :
-else
-    # TRANSLATORS: This message is shown when required executable `%s'
-    # isn't found
-    gettext_printf "%s: Not found.\n" "$1" 1>&2
-    exit 1
-fi
-
-if [ x"$grub_modinfo_platform" = xefi ]; then
-    # Find the EFI System Partition.
-    if test -n "$efidir"; then
-       install_device="`"$grub_probe" --target=device --device-map= "${efidir}"`"
-    else
-       if test -d "${bootdir}/efi"; then
-           install_device="`"$grub_probe" --target=device --device-map= "${bootdir}/efi"`"
-            # Is it a mount point?
-           if test "x$install_device" != "x`"$grub_probe" --target=device --device-map= "${bootdir}"`"; then
-               efidir="${bootdir}/efi"
-           fi
-       elif test -d "${bootdir}/EFI"; then
-           install_device="`"$grub_probe" --target=device --device-map= "${bootdir}/EFI"`"
-            # Is it a mount point?
-           if test "x$install_device" != "x`"$grub_probe" --target=device --device-map= "${bootdir}"`"; then
-               efidir="${bootdir}/EFI"
-           fi
-       elif test -n "$rootdir" && test "x$rootdir" != "x/"; then
-        # The EFI System Partition may have been given directly using
-        # --root-directory.
-           install_device="`"$grub_probe" --target=device --device-map= "${rootdir}"`"
-        # Is it a mount point?
-           if test "x$install_device" != "x`"$grub_probe" --target=device --device-map= "${rootdir}/.."`"; then
-               efidir="${rootdir}"
-           fi
-       fi
-
-       if test -n "$efidir"; then
-           efi_fs=`"$grub_probe" --target=fs "--device-map=${device_map}" "${efidir}"`
-           if test "x$efi_fs" = xfat; then :; else
-               gettext_printf "%s doesn't look like an EFI partition.\n" "${efidir}" 1>&2
-               efidir=
-           fi
-       fi
-    fi
-
-    if test -n "$efidir"; then
-        # The EFI specification requires that an EFI System Partition must
-        # contain an "EFI" subdirectory, and that OS loaders are stored in
-        # subdirectories below EFI.  Vendors are expected to pick names that do
-        # not collide with other vendors.  To minimise collisions, we use the
-        # name of our distributor if possible.
-       efi_distributor="$bootloader_id"
-       if test $removable = yes; then
-          # The specification makes stricter requirements of removable
-          # devices, in order that only one image can be automatically loaded
-          # from them.  The image must always reside under /EFI/BOOT, and it
-          # must have a specific file name depending on the architecture.
-           efi_distributor=BOOT
-           case "$grub_modinfo_target_cpu" in
-               i386)
-                   efi_file=BOOTIA32.EFI ;;
-               x86_64)
-                   efi_file=BOOTX64.EFI ;;
-           # GRUB does not yet support these architectures, but they're defined
-           # by the specification so we include them here to ease future
-           # expansion.
-               ia64)
-                   efi_file=BOOTIA64.EFI ;;
-               arm)
-                   efi_file=BOOTARM.EFI ;;
-           esac
-       else
-           # It is convenient for each architecture to have a different
-           # efi_file, so that different versions can be installed in parallel.
-           case "$grub_modinfo_target_cpu" in
-               i386)
-                   efi_file=grubia32.efi ;;
-               x86_64)
-                   efi_file=grubx64.efi ;;
-        # GRUB does not yet support these architectures, but they're defined
-        # by the specification so we include them here to ease future
-        # expansion.
-               ia64)
-                   efi_file=grubia64.efi ;;
-               arm)
-                   efi_file=grubarm.efi ;;
-               *)
-                   efi_file=grub.efi ;;
-           esac
-       fi
-       efidir="$efidir/EFI/$efi_distributor"
-       mkdir -p "$efidir" || exit 1
-    else
-        # We don't know what's going on.  Fall back to traditional
-        # (non-specification-compliant) behaviour.
-       efidir="$grubdir"
-       efi_distributor=
-       efi_file=grub.efi
-    fi
-fi
-
-# Create the GRUB directory if it is not present.
-mkdir -p "$grubdir" || exit 1
-mkdir -p "$grubdir/${grub_modinfo_target_cpu}-$grub_modinfo_platform" || exit 1
-
-# If --recheck is specified, remove the device map, if present.
-if test $recheck = yes; then
-    rm -f "$device_map"
-fi
-
-# Device map file is optional
-if test -f "$device_map"; then
-    # Make sure that there is no duplicated entry.
-    tmp=`sed -n '/^([fh]d[0-9]*)/s/\(^(.*)\).*/\1/p' "$device_map" \
-       | sort | uniq -d | sed -n 1p`
-    if test -n "$tmp"; then
-       gettext_printf "The drive %s is defined multiple times in the device map %s\n" "$tmp" "$device_map" 1>&2
-       exit 1
-    fi
-else
-    device_map=
-fi
-
-# Copy the GRUB images to the GRUB directory.
-grub_install_files "${source_directory}" "${grubdir}" "${grub_modinfo_target_cpu}-$grub_modinfo_platform" all
-
-if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "sparc64-ieee1275" ] ; then
-    for file in "${source_directory}"/*.img "${source_directory}"/efiemu??.o; do
-       if test -f "$file"; then
-           cp -f "$file" "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform" || exit 1
-       fi
-    done
-fi
-
-if ! is_path_readable_by_grub "${grubdir}"; then
-    gettext_printf "Path \`%s' is not readable by GRUB on boot. Installation is impossible. Aborting.\n" "${grubdir}" 1>&2
-    exit 1
-fi
-
-# Write device to a variable so we don't have to traverse /dev every time.
-grub_device="`"$grub_probe" --device-map="${device_map}" --target=device "${grubdir}"`" || exit 1
-
-if ! test -f "${grubdir}"/grubenv; then
-    "$grub_editenv" "${grubdir}"/grubenv create
-fi
-
-# Create the core image. First, auto-detect the filesystem module.
-fs_module="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=fs --device `"
-if test "x$fs_module" = x ; then
-    gettext_printf "Auto-detection of a filesystem of %s failed.\n" "${grub_device}" 1>&2
-    gettext "Try with --recheck." 1>&2
-    echo 1>&2
-    gettext_printf "If the problem persists please report this together with the output of %s to <%s>" "\"$grub_probe --device-map=\"${device_map}\" --target=fs -v ${grubdir}\"" "bug-grub@gnu.org" 1>&2
-    exit 1
-fi
-
-# Then the partition map module.  In order to support partition-less media,
-# this command is allowed to fail (--target=fs already grants us that the
-# filesystem will be accessible).
-partmap_module=
-for x in `echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=partmap --device 2> /dev/null`; do
-   case "$x" in
-       netbsd | openbsd) 
-          partmap_module="$partmap_module part_bsd";;
-       "") ;;
-       *)
-          partmap_module="$partmap_module part_$x";;
-   esac
-done
-
-# Device abstraction module, if any (lvm, raid).
-devabstraction_module="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=abstraction --device`"
-
-if [ "x$disk_module" = xata ]; then
-    disk_module=pata
-fi
-
-if [ "x$disk_module" = xnative ]; then
-    disk_module="pata ahci ohci"
-    if [ "x$grub_modinfo_target_cpu" = "xi386" ] || [ "x$grub_modinfo_target_cpu" = "xx86_64" ]; then
-       disk_module="$disk_module uhci"
-    fi
-    disk_module="$disk_module usbms"
-fi
-
-# The order in this list is critical.  Be careful when modifying it.
-modules="$modules $disk_module"
-modules="$modules $fs_module $partmap_module $devabstraction_module"
-
-relative_grubdir="`"$grub_mkrelpath" "${grubdir}"`" || exit 1
-if [ "x${relative_grubdir}" = "x" ] ; then
-    relative_grubdir=/
-fi
-
-prefix_drive=
-config_opt_file=
-
-rm -f "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/load.cfg"
-
-if [ "x${debug_image}" != x ]; then
-    echo "set debug='${debug_image}'" >> "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/load.cfg"
-    config_opt_file="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/load.cfg"
-fi
-
-if [ "x${devabstraction_module}" = "x" ] ; then
-    if [ x"${install_device}" != x ]; then
-      if echo "${install_device}" | grep -qx "(.*)" ; then
-        install_drive="${install_device}"
-      else
-        install_drive="`"$grub_probe" --device-map="${device_map}" --target=drive --device "${install_device}"`" || exit 1
-      fi
-      install_drive="`echo "${install_drive}" | sed -e 's/^(\(\([^,\\\\]\|\\\\\\\\\|\\\\,\)*\)\(\(,[a-zA-Z0-9]*\)*\))$/\1/'`"
-    fi
-    grub_drive="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=drive --device`" || exit 1
-
-    # Strip partition number
-    grub_partition="`echo "${grub_drive}" | sed -e 's/^(\(\([^,\\\\]\|\\\\\\\\\|\\\\,\)*\)\(\(,[a-zA-Z0-9]*\)*\))$/\3/'`"
-    grub_drive="`echo "${grub_drive}" | sed -e 's/^(\(\([^,\\\\]\|\\\\\\\\\|\\\\,\)*\)\(\(,[a-zA-Z0-9]*\)*\))$/\1/'`"
-
-    if [ x"${install_device}" = x ] && [ x"${grub_modinfo_target_cpu}-$grub_modinfo_platform" = x"powerpc-ieee1275" ]; then
-       install_drive="$grub_drive"
-    fi
-
-    if ([ "x$disk_module" != x ] && [ "x$disk_module" != xbiosdisk ]) || [ "x${grub_drive}" != "x${install_drive}" ] || ([ "x$grub_modinfo_platform" != xefi ] && [ "x$grub_modinfo_platform" != xpc ] && [ x"${grub_modinfo_platform}" != x"ieee1275" ]); then
-        # generic method (used on coreboot and ata mod)
-       uuid=
-       if [ x"$force_file_id" != xy ]; then
-            uuid="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=fs_uuid --device`"
-       fi
-
-       if [ x"$disk_module" != x ] && [ x"$disk_module" != xbiosdisk ]; then
-            hints="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=baremetal_hints --device`"
-       elif [ x"$grub_modinfo_platform" = xpc ]; then
-            hints="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=bios_hints --device`"
-       elif [ x"$grub_modinfo_platform" = xefi ]; then
-            hints="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=efi_hints --device`"
-       elif [ x"$grub_modinfo_platform" = xieee1275 ]; then
-            hints="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=ieee1275_hints --device`"
-       elif [ x"$grub_modinfo_platform" = xloongson ] || [ x"$grub_modinfo_platform" = xqemu ] || [ x"$grub_modinfo_platform" = xcoreboot ] || [ x"$grub_modinfo_platform" = xmultiboot ] || [ x"$grub_modinfo_platform" = xqemu-mips ]; then
-            hints="`echo "${grub_device}" | xargs "$grub_probe" --device-map="${device_map}" --target=baremetal_hints --device`"
-       else
-            gettext "No hints available for your platform. Expect reduced performance." 1>&2
-           echo 1>&2
-           hints=
-        fi
-       if [ x"$uuid" != x ]; then
-            echo "search.fs_uuid ${uuid} root $hints " >> "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/load.cfg"
-           search_module=search_fs_uuid
-       else
-           mkdir -p "${grubdir}/uuid"
-           file="`mktemp "${grubdir}/uuid/XXXXXXXXXXXXXXXXXXXXXXXXX"`"
-           relfile="`${grub_mkrelpath} "$file"`"
-            echo "search.file '${relfile}' root $hints " >> "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/load.cfg"
-           search_module=search_fs_file
-       fi
-       echo 'set prefix=($root)'"$(echo "${relative_grubdir}" | sed "s,\\([ \"'\\\\]\\),\\\\\\1,g")" >> "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/load.cfg"
-       config_opt_file="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/load.cfg"
-        modules="$modules $search_module"
-    else
-        # we need to hardcode the partition number in the core image's prefix.
-       if [ x"$grub_partition" = x ]; then
-            prefix_drive="()"
-       else
-            # Comma is already there
-            prefix_drive="($grub_partition)"
-       fi
-    fi
-else
-    if [ x$GRUB_ENABLE_CRYPTODISK = xy ]; then
-       for uuid in "`echo "${grub_device}" | xargs "${grub_probe}"  --target=cryptodisk_uuid --device`"; do
-           echo "cryptomount -u $uuid" >> "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/load.cfg"
-       done
-       config_opt_file="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/load.cfg"
-    fi
-
-    prefix_drive=`"$grub_probe" --device-map="${device_map}" --target=drive --device "${grub_device}"` || exit 1
-fi
-
-case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in
-    sparc64-ieee1275) mkimage_target=sparc64-ieee1275-raw ;;
-    mipsel-loongson) mkimage_target=mipsel-loongson-elf ;;
-    mips-qemu_mips | mipsel-qemu_mips) mkimage_target="${grub_modinfo_target_cpu}-${grub_modinfo_platform}"-elf ;;
-    *) mkimage_target="${grub_modinfo_target_cpu}-${grub_modinfo_platform}" ;;
-esac
-
-case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in
-    i386-efi | x86_64-efi | ia64-efi) imgext=efi ;;
-    mipsel-loongson | i386-coreboot | i386-multiboot | i386-ieee1275 \
-       | powerpc-ieee1275 | mips-qemu_mips | mipsel-qemu_mips) imgext=elf ;;
-    *) imgext=img ;;
-esac
-
-if [ x"$config_opt_file" = x ]; then
-    "$grub_mkimage" -d "${source_directory}" -O "${mkimage_target}" --output="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" --prefix="${prefix_drive}${relative_grubdir}" $grub_decompression_module $modules || exit 1
-else
-    "$grub_mkimage" -c "${config_opt_file}" -d "${source_directory}" -O "${mkimage_target}" --output="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" --prefix="${prefix_drive}${relative_grubdir}" $grub_decompression_module $modules || exit 1
-fi
-
-# Backward-compatibility kludges
-if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "mipsel-loongson" ]; then
-    cp "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" "${bootdir}"/grub.elf
-elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-ieee1275" ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "powerpc-ieee1275" ]; then
-    cp "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" "${grubdir}/grub"
-elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-efi" ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "x86_64-efi" ]; then
-
-    if [ x"$config_opt_file" = x ]; then
-       "$grub_mkimage" -d "${source_directory}" -O "${mkimage_target}" --output="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/grub.efi" --prefix="" $grub_decompression_module $modules || exit 1
-    else
-       "$grub_mkimage" -c "${config_opt_file}" -d "${source_directory}" -O "${mkimage_target}" --output="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/grub.efi" --prefix="" $grub_decompression_module $modules || exit 1
-    fi
-fi
-
-
-# Perform the grub_modinfo_platform-dependent install
-if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "sparc64-ieee1275" ] ; then
-    # Now perform the installation.
-    "$grub_setup" ${allow_floppy} ${setup_verbose} ${setup_force} --directory="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform" \
-       --device-map="${device_map}" "${install_device}" || exit 1
-elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-ieee1275" ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "powerpc-ieee1275" ]; then
-
-    # If a install device is defined, copy the core.elf to PReP partition.
-    if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "powerpc-ieee1275" ] && [ -n "${install_device}" ]; then
-
-        if [ "$("${grub_probe}" -m "${device_map}" -d "${install_device}" -t msdos_parttype)" != "41" ] \
-            && [ "$("${grub_probe}" -m "${device_map}" -d "${install_device}" -t gpt_parttype)" != "9e1a2d38-c612-4316-aa26-8b49521e5a8b" ]; then
-            gettext "The chosen partition is not a PReP partition." 1>&2
-            echo 1>&2
-            exit 1
-        fi
-
-        if [ "$(file -s -b -L "${install_device}" | awk '{ print $1 }')" = ELF ] || [ x$("${grub_probe}" -m "${device_map}" -d "${install_device}" -t zero_check) = xtrue ]; then
-               dd if="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" of="${install_device}" status=noxfer || {
-               gettext "Failed to copy Grub to the PReP partition." 1>&2
-                   echo 1>&2
-                   exit 1
-               }
-        else
-               gettext "The PReP partition is not empty. If you are sure you want to use it, run dd to clear it:" 1>&2
-               echo 1>&2
-               echo "  dd if=/dev/zero of=${install_device}"
-               exit 1
-        fi
-    fi
-
-    if [ x"$update_nvram" = xyes ]; then
-       ofpathname="`which ofpathname`"
-       nvsetenv="`which nvsetenv`"
-       set "$ofpathname" dummy
-       if test -f "$1"; then
-           :
-       else
-            # TRANSLATORS: This message is shown when required executable `%s'
-            # isn't found
-           gettext_printf "%s: Not found.\n" "$1" 1>&2
-           exit 1
-       fi
-       set "$nvsetenv" dummy
-       if test -f "$1"; then
-           :
-       else
-            # TRANSLATORS: This message is shown when required executable `%s'
-            # isn't found
-           gettext_printf "%s: Not found.\n" "$1" 1>&2
-           exit 1
-       fi
-       if  [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" != "powerpc-ieee1275" ] \
-           || [ -z "${install_device}" ]; then
-         # Get the Open Firmware device tree path translation.
-           dev="`echo $grub_device | sed -e 's/\/dev\///' -e 's/[0-9]\+//'`"
-           partno="`echo $grub_device | sed -e 's/.*[^0-9]\([0-9]\+\)$/\1/'`"
-           ofpath="`$ofpathname $dev`" || {
-           # TRANSLATORS: "device tree path" is the name of the device
-            # for IEEE1275
-               gettext_printf "Couldn't find IEEE1275 device tree path for %s.\nYou will have to set \`boot-device' variable manually.\n" "$dev" 1>&2
-               exit 1
-           }
-
-            # Point boot-device at the new grub install
-           boot_device="$ofpath:$partno,"`"$grub_mkrelpath" "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" | sed 's,/,\\\\,g'`
-
-       else
-
-           dev="`echo "${install_device}" | sed -e 's/\/dev\///' -e 's/[0-9]\+//'`"
-           boot_device="`$ofpathname "$dev"`" || {
-           # TRANSLATORS: "device tree path" is the name of the device
-            # for IEEE1275
-               gettext_printf "Couldn't find IEEE1275 device tree path for %s.\nYou will have to set \`boot-device' variable manually.\n" "$dev" 1>&2
-               exit 1
-           }
-       fi
-
-       "$nvsetenv" boot-device "$boot_device" || {
-           # TRANSLATORS: The %s will be replaced by an external program name.
-           gettext_printf "\`%s' failed.\n" "$nvsetenv" 1>&2
-           gettext "You will have to set \`boot-device' variable manually.  At the IEEE1275 prompt, type:" 1>&2
-           echo 1>&2
-           echo "  setenv boot-device $boot_device" 1>&2
-           exit 1
-       }
-    fi
-elif [ x"${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = xmips-arc ]; then
-    dvhtool -d "${install_device}" --unix-to-vh "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" grub
-    gettext "You will have to set \`SystemPartition' and \`OSLoader' manually." 1>&2
-    echo 1>&2
-elif [ x"$grub_modinfo_platform" = xefi ]; then
-    cp "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" "${efidir}/${efi_file}"
-    # For old macs. Suggested by Peter Jones.
-    if [ x$grub_modinfo_target_cpu = xi386 ]; then
-       cp "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" "${efidir}/boot.efi"
-    fi
-
-    # Try to make this image bootable using the EFI Boot Manager, if available.
-    if test "$removable" = no; then
-
-       efibootmgr="`which efibootmgr`" || {
-            # TRANSLATORS: This message is shown when required executable `%s'
-            # isn't found
-           gettext_printf "%s: Not found.\n" "efibootmgr" 1>&2
-           exit 1
-       }
-
-       test -n "$efi_distributor" || {
-           gettext "EFI distributor id isn't specified." 1>&2
-           echo 1>&2
-           exit 1
-       }
-
-        # On Linux, we need the efivars kernel modules.
-       case "$host_os" in
-           linux*)
-               modprobe -q efivars 2>/dev/null || true ;;
-       esac
-
-        # Delete old entries from the same distributor.
-       for bootnum in `efibootmgr | grep '^Boot[0-9]' | \
-           fgrep -i " $efi_distributor" | cut -b5-8`; do
-           efibootmgr $efi_quiet -b "$bootnum" -B
-       done
-
-        # Add a new entry for the image we just created.  efibootmgr needs to be
-        # given the disk device and partition number separately, so we have to
-        # fiddle about with grub-probe to get hold of this reasonably reliably.
-        # Use fresh device map text to avoid any problems with stale data, since
-        # all we need here is a one-to-one mapping.
-       efidir_drive="$("$grub_probe" --target=drive --device-map= "$efidir")"
-       efidir_disk="$("$grub_probe" --target=disk --device-map= "$efidir")"
-       if test -z "$efidir_drive" || test -z "$efidir_disk"; then
-           gettext_printf "Can't find GRUB drive for %s; unable to create EFI Boot Manager entry.\n" "$efidir" >&2
-       else
-           efidir_part="$(echo "$efidir_drive" | sed 's/^([^,]*,[^0-9]*//; s/[^0-9].*//')"
-           efibootmgr $efi_quiet -c -d "$efidir_disk" -p "$efidir_part" -w \
-               -L "$bootloader_id" -l "\\EFI\\$efi_distributor\\$efi_file"
-       fi
-    fi
-else
-    gettext "WARNING: no platform-specific install was performed" 1>&2
-    echo 1>&2
-fi
-
-gettext "Installation finished. No error reported." 1>&2
-echo 1>&2
-
-# Bye.
-exit 0
diff --git a/util/grub-install_header b/util/grub-install_header
deleted file mode 100644 (file)
index 2759ae8..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-#! /bin/sh
-set -e
-
-# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012  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 <http://www.gnu.org/licenses/>.
-
-prefix="@prefix@"
-exec_prefix="@exec_prefix@"
-datarootdir="@datarootdir@"
-bindir="@bindir@"
-
-libdir="@libdir@"
-PACKAGE_NAME=@PACKAGE_NAME@
-PACKAGE_TARNAME=@PACKAGE_TARNAME@
-PACKAGE_VERSION=@PACKAGE_VERSION@
-datadir="@datadir@"
-if [ "x$pkgdatadir" = x ]; then
-    pkgdatadir="${datadir}/@PACKAGE@"
-fi
-localedir="@datadir@/locale"
-
-self=`basename $0`
-
-export TEXTDOMAIN=@PACKAGE@
-export TEXTDOMAINDIR="@localedir@"
-
-. "${pkgdatadir}/grub-mkconfig_lib"
-
-modules=
-
-pkglib_DATA="moddep.lst command.lst fs.lst partmap.lst parttool.lst \
-handler.lst video.lst crypto.lst terminal.lst"
-
-grub_mkimage="${bindir}/@grub_mkimage@"
-
-grub_compress_file () {
-    if [ -f "$1" ] ; then
-       if [ "$compressor" != "" ] ; then
-           "$compressor" $compressor_opts "$1" > "$2"
-       else
-           cp -f "$1" "$2"
-       fi
-    else
-       gettext_printf "Skipping file \`%s': not a plain file\n" "$1" 1>&2
-    fi
-}
-
-grub_install_files () {
-    grub_install_files_source_directory="$1"
-    grub_install_files_target_directory="$2"
-    grub_install_files_platform="$3"
-    
-    mkdir -p "${grub_install_files_target_directory}"/"${grub_install_files_platform}"
-    
-    for file in "${grub_install_files_target_directory}"/*.mod \
-"${grub_install_files_target_directory}"/*.lst \
-"${grub_install_files_target_directory}"/*.img \
-"${grub_install_files_target_directory}"/efiemu??.o \
-"${grub_install_files_target_directory}"/"${grub_install_files_platform}"/*.mod \
-"${grub_install_files_target_directory}"/"${grub_install_files_platform}"/*.lst \
-"${grub_install_files_target_directory}"/"${grub_install_files_platform}"/*.img \
-"${grub_install_files_target_directory}"/"${grub_install_files_platform}"/efiemu??.o;
-    do
-       if test -f "$file" && [ "`basename $file`" != menu.lst ]; then
-           rm -f "$file" || exit 1
-       fi
-    done
-
-    if [ x"$install_modules" = xall ]; then
-       for file in "${grub_install_files_source_directory}/"*.mod; do
-           grub_compress_file "$file" "${grub_install_files_target_directory}"/"${grub_install_files_platform}/$(basename "$file")"
-       done
-    else
-       modules1=
-       modules2="$install_modules"
-       while [ x"$modules2" != x ]; do
-           modules3=
-           for x in $modules2; do
-               modules3="$modules3 $(grep "^$x:" "${grub_install_files_source_directory}/moddep.lst" | sed 's,^[^:]*:,,')"
-           done
-           modules1="$modules1 $modules2"
-           modules2="$modules3"
-       done
-       for file in $(echo "$modules1" | sed 's, ,\n,g' |sort -u); do
-           grub_compress_file "${grub_install_files_source_directory}/$file.mod" "${grub_install_files_target_directory}"/"${grub_install_files_platform}/$file.mod"
-       done
-    fi
-    
-    for file in ${pkglib_DATA} efiemu32.o efiemu64.o; do
-       if test -f "${grub_install_files_source_directory}/${file}"; then
-            grub_compress_file "${grub_install_files_source_directory}/${file}" "${grub_install_files_target_directory}"/"${grub_install_files_platform}/${file}"
-       fi
-    done
-    
-    # Copy gettext files
-    mkdir -p "${grub_install_files_target_directory}"/locale
-
-    for file in "${grub_install_files_target_directory}"/locale/*.mo; do
-       if test -f "$file"; then
-           rm -f "$file" || exit 1
-       fi
-    done
-
-    if [ x"$install_locales" = xall ]; then
-       for file in "${grub_install_files_source_directory}"/po/*.mo; do
-           if test -f "$file"; then
-               grub_compress_file "$file" "${grub_install_files_target_directory}"/locale/"$(basename "$file")"
-           fi
-       done
-       for dir in "${localedir}"/*; do
-           if test -f "$dir/LC_MESSAGES/@PACKAGE@.mo" && ! test -f "${grub_install_files_target_directory}"/locale/"${dir##*/}.mo"; then
-               grub_compress_file "$dir/LC_MESSAGES/@PACKAGE@.mo" "${grub_install_files_target_directory}"/locale/"${dir##*/}.mo"
-           fi
-       done
-    else
-       for locale in $install_locales; do
-           if test -f "${grub_install_files_source_directory}"/po/$locale.mo; then
-               grub_compress_file "${grub_install_files_source_directory}"/po/locale.mo "${grub_install_files_target_directory}"/locale/$locale.mo
-           elif test -f "${localedir}/$locale/LC_MESSAGES/@PACKAGE@.mo"; then
-               grub_compress_file "${localedir}/$locale/LC_MESSAGES/@PACKAGE@.mo" "${grub_install_files_target_directory}"/locale/$locale.mo
-           fi
-       done
-    fi
-    for theme in ${install_themes} ; do
-       if test -f "${pkgdatadir}"/themes/"${theme}"/theme.txt; then
-           mkdir -p "${grub_install_files_target_directory}"/themes/"${theme}"
-           for file in "${pkgdatadir}"/themes/"${theme}"/*; do
-               grub_compress_file "$file" "${grub_install_files_target_directory}"/themes/"${theme}"/"$(basename "$file")"
-           done
-       fi
-    done
-
-    for font in ${install_fonts} ; do
-       if test -f "${pkgdatadir}"/"$font".pf2; then
-           mkdir -p "${grub_install_files_target_directory}"/fonts
-           grub_compress_file "${pkgdatadir}"/"$font".pf2 "${grub_install_files_target_directory}"/fonts/"$font".pf2
-       fi
-    done
-}
-
-grub_print_install_files_help () {
-    print_option_help "--modules=$(gettext "MODULES")" "$(gettext "pre-load specified modules MODULES")"
-    print_option_help "--install-modules=$(gettext "MODULES")" "$(gettext "install only MODULES and their dependencies [default=all]")"
-    print_option_help "--themes=THEMES" "$(gettext_printf "install THEMES [default=%s]" "starfield")"
-    print_option_help "--fonts=FONTS" "$(gettext_printf "install FONTS [default=%s]" "unicode")"
-    print_option_help "--locales=LOCALES" "$(gettext_printf "install only LOCALES [default=all]")"
-    print_option_help "--compress[=no,xz,gz,lzo]" "$(gettext "compress GRUB files [optional]")"
-    # TRANSLATORS: platform here isn't identifier. It can be translated.
-    dir_msg="$(gettext_printf "use images and modules under DIR [default=%s/<platform>]" "${libdir}/@PACKAGE@")"
-    print_option_help "-d, --directory=$(gettext "DIR")" "$dir_msg"
-    print_option_help  "--grub-mkimage=$(gettext "FILE")" "$(gettext "use FILE as grub-mkimage")"
-    print_option_help "-v, --version" "$(gettext "print the version information and exit")"
-}
-
-install_modules=all
-install_themes=starfield
-install_fonts=unicode
-install_locales=all
-compress=no
-grub_decompression_module=""
-compressor=""
-compressor_opts=""
-source_directory=""
-
-argument () {
-  opt=$1
-  shift
-
-  if test $# -eq 0; then
-      gettext_printf "%s: option requires an argument -- \`%s'\n" "$0" "$opt" 1>&2
-      exit 1
-  fi
-  echo $1
-}
-
-grub_parse_compress () {
-    compress="$1"
-    case x"$compress" in
-       xno) ;;
-       xgz)
-           compressor=`which gzip || true`
-           grub_decompression_module="gzio"
-           compressor_opts="--best --stdout";;
-       xxz)
-           compressor=`which xz || true`
-           grub_decompression_module="xzio gcry_crc"
-           compressor_opts="--lzma2=dict=128KiB --check=none --stdout";;
-       xlzo)
-           compressor=`which lzop || true`
-           grub_decompression_module="lzopio adler32 gcry_crc"
-           compressor_opts="-9 -c";;
-       *)
-           gettext_printf "Unrecognized compression \`%s'\n" "$compress" 1>&2
-           usage
-           exit 1
-    esac
-}
-
-grub_process_install_options () {
-    option=$1
-    shift
-
-    grub_process_install_options_consumed=0
-
-    case "$option" in
-       --install-modules)
-           install_modules=`argument $option "$@"`; grub_process_install_options_consumed=2; return ;;
-       --install-modules=*)
-            install_modules=`echo "$option" | sed 's/--install-modules=//'`; grub_process_install_options_consumed=1; return ;;
-       --themes)
-           install_themes=`argument $option "$@"`; grub_process_install_options_consumed=2; return ;;
-       --themes=*)
-            install_themes=`echo "$option" | sed 's/--themes=//'`; grub_process_install_options_consumed=1; return ;;
-       --fonts)
-           install_fonts=`argument $option "$@"`; grub_process_install_options_consumed=2; return ;;
-       --fonts=*)
-            install_fonts=`echo "$option" | sed 's/--fonts=//'`; grub_process_install_options_consumed=1; return ;;
-       --locales)
-           install_locales=`argument $option "$@"`; grub_process_install_options_consumed=2; return ;;
-       --locales=*)
-            install_locales=`echo "$option" | sed 's/--locales=//'`; grub_process_install_options_consumed=1; return ;;
-       --compress)
-           grub_parse_compress `argument $option "$@"`; grub_process_install_options_consumed=2; return ;;
-        --compress=*)
-            grub_parse_compress `echo "${option}" | sed 's/--compress=//'`; grub_process_install_options_consumed=1; return ;;
-       --directory | -d)
-           source_directory=`argument $option "$@"`; grub_process_install_options_consumed=2 ;;
-       --directory=*)
-           source_directory=`echo "$option" | sed 's/--directory=//'` grub_process_install_options_consumed=1;;
-
-       # For backwards compatibility
-       --override-directory)
-           source_directory=`argument $option "$@"`; grub_process_install_options_consumed=2 ;;
-       --override-directory=*)
-           source_directory=`echo "$option" | sed 's/--override-directory=//'` grub_process_install_options_consumed=1;;
-
-       --grub-mkimage)
-           grub_mkimage=`argument $option "$@"`; grub_process_install_options_consumed=2 ;;
-        --grub-mkimage=*)
-           grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'`;grub_process_install_options_consumed=1 ;;
-        --modules)
-           modules=`argument $option "$@"`; grub_process_install_options_consumed=2;;
-        --modules=*)
-           modules=`echo "$option" | sed 's/--modules=//'` grub_process_install_options_consumed=1;;
-        -v | --version)
-           echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}"
-           exit 0 ;;
-    esac
-}
-
-export grub_decompression_module
index 6e1e424db7163ab074cf3efdb03a1fa589087c2c..33cce36ad3ff71deaf0f5f6e8d13e4541972454b 100644 (file)
@@ -45,6 +45,7 @@
 #include <grub/ia64/reloc.h>
 #include <grub/osdep/hostfile.h>
 #include <grub/util/install.h>
+#include <grub/emu/config.h>
 
 #define _GNU_SOURCE    1
 #include <argp.h>
@@ -83,7 +84,7 @@ help_filter (int key, const char *text, void *input __attribute__ ((unused)))
   switch (key)
     {
     case 'd':
-      return xasprintf (text, GRUB_PKGLIBDIR);
+      return xasprintf (text, grub_util_get_pkglibdir ());
     case 'p':
       return xasprintf (text, DEFAULT_DIRECTORY);
     case 'O':
@@ -268,10 +269,12 @@ main (int argc, char *argv[])
   if (!arguments.dir)
     {
       const char *dn = grub_util_get_target_dirname (arguments.image_target);
-      arguments.dir = xmalloc (sizeof (GRUB_PKGLIBDIR) + grub_strlen (dn) + 1);
-      memcpy (arguments.dir, GRUB_PKGLIBDIR, sizeof (GRUB_PKGLIBDIR) - 1);
-      *(arguments.dir + sizeof (GRUB_PKGLIBDIR) - 1) = '/';
-      strcpy (arguments.dir + sizeof (GRUB_PKGLIBDIR), dn);
+      const char *pkglibdir = grub_util_get_pkglibdir ();
+      char *ptr;
+      arguments.dir = xmalloc (grub_strlen (pkglibdir) + grub_strlen (dn) + 2);
+      ptr = grub_stpcpy (arguments.dir, pkglibdir);
+      *ptr++ = '/';
+      strcpy (ptr, dn);
     }
 
   grub_install_generate_image (arguments.dir,
diff --git a/util/grub-mknetdir.c b/util/grub-mknetdir.c
new file mode 100644 (file)
index 0000000..20130d3
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+  * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2013  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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <config.h>
+
+#include <grub/util/install.h>
+#include <grub/emu/config.h>
+#include <grub/util/misc.h>
+
+#include <argp.h>
+#include <string.h>
+#include <errno.h>
+
+static char *rootdir = NULL, *subdir = NULL;
+static char *debug_image = NULL;
+
+enum
+  {
+    OPTION_NET_DIRECTORY = 0x301,
+    OPTION_SUBDIR,
+    OPTION_DEBUG,
+    OPTION_DEBUG_IMAGE
+  };
+
+static struct argp_option options[] = {
+  GRUB_INSTALL_OPTIONS,
+  {"net-directory", OPTION_NET_DIRECTORY, N_("DIR"),
+   0, N_("root directory of TFTP server"), 2},
+  {"subdir", OPTION_SUBDIR, N_("DIR"),
+   0, N_("relative subdirectory on network server"), 2},
+  {"debug", OPTION_DEBUG, 0, OPTION_HIDDEN, 0, 2},
+  {"debug-image", OPTION_DEBUG_IMAGE, "DEBUG", OPTION_HIDDEN, 0, 2},
+  {0, 0, 0, 0, 0, 0}
+};
+
+static error_t 
+argp_parser (int key, char *arg, struct argp_state *state)
+{
+  if (grub_install_parse (key, arg))
+    return 0;
+  switch (key)
+    {
+    case OPTION_NET_DIRECTORY:
+      free (rootdir);
+      rootdir = xstrdup (arg);
+      return 0;
+    case OPTION_SUBDIR:
+      free (subdir);
+      subdir = xstrdup (arg);
+      return 0;
+      /* This is an undocumented feature...  */
+    case OPTION_DEBUG:
+      verbosity++;
+      return 0;
+    case OPTION_DEBUG_IMAGE:
+      free (debug_image);
+      debug_image = xstrdup (arg);
+      return 0;
+
+    case ARGP_KEY_ARG:
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+}
+
+
+struct argp argp = {
+  options, argp_parser, N_("[OPTION]"),
+  "\v"N_("copies GRUB images into net_directory/subdir/target_cpu-platform."), 
+  NULL, grub_install_help_filter, NULL
+};
+
+static char *base;
+
+static const struct
+{
+  const char *mkimage_target;
+  const char *netmodule;
+  const char *ext;
+} targets[GRUB_INSTALL_PLATFORM_MAX] =
+  {
+    [GRUB_INSTALL_PLATFORM_I386_PC] = { "i386-pc-pxe", "pxe", ".0" },
+    [GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275] = { "sparc64-ieee1275-aout", "ofnet", ".img" },
+    [GRUB_INSTALL_PLATFORM_I386_IEEE1275] = { "i386-ieee1275", "ofnet", ".elf" },
+    [GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275] = { "powerpc-ieee1275", "ofnet", ".elf" },
+    [GRUB_INSTALL_PLATFORM_I386_EFI] = { "i386-efi", "efinet", ".efi" },
+    [GRUB_INSTALL_PLATFORM_X86_64_EFI] = { "x86_64-efi", "efinet", ".efi" },
+    [GRUB_INSTALL_PLATFORM_IA64_EFI] = { "ia64-efi", "efinet", ".efi" },
+    [GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm-efi", "efinet", ".efi" }
+  };
+
+static void
+process_input_dir (const char *input_dir, enum grub_install_plat platform)
+{
+  char *platsub = grub_install_get_platform_name (platform);
+  char *grubdir = grub_util_path_concat (3, rootdir, subdir, platsub);
+  char *load_cfg = grub_util_path_concat (2, grubdir, "load.cfg");
+  char *prefix;
+  char *output;
+  char *grub_cfg;
+  FILE *cfg;
+
+  grub_install_copy_files (input_dir, base, platform);
+  grub_util_unlink (load_cfg);
+
+  if (debug_image)
+    {
+      FILE *f = grub_util_fopen (load_cfg, "wb");
+      if (!f)
+       grub_util_error (_("cannot open `%s': %s"), load_cfg,
+                        strerror (errno));
+      fprintf (f, "set debug='%s'\n", debug_image);
+      fclose (f);
+    }
+  else
+    {
+      free (load_cfg);
+      load_cfg = 0;
+    }
+
+  prefix = xasprintf ("/%s", subdir);
+  if (!targets[platform].mkimage_target)
+    grub_util_error ("unsupported platform %s\n", platsub);
+
+  grub_cfg = grub_util_path_concat (2, grubdir, "grub.cfg");
+  cfg = grub_util_fopen (grub_cfg, "wb");
+  if (!cfg)
+    grub_util_error (_("cannot open `%s': %s"), grub_cfg,
+                    strerror (errno));
+  fprintf (cfg, "source %s/grub.cfg", subdir);
+  fclose (cfg);
+
+  grub_install_push_module (targets[platform].netmodule);
+
+  output = grub_util_path_concat_ext (2, grubdir, "core", targets[platform].ext);
+  grub_install_make_image_wrap (input_dir, prefix, output,
+                               0, load_cfg,
+                               targets[platform].mkimage_target, 0,
+                               GRUB_COMPRESSION_AUTO);
+  grub_install_pop_module ();
+
+  /* TRANSLATORS: First %s is replaced by platform name. Second one by filename.  */
+  printf (_("Netboot directory for %s created. Configure your DHCP server to point to %s\n"),
+         platsub, output);
+
+  free (platsub);
+  free (output);
+  free (prefix);
+  free (grub_cfg);
+  free (grubdir);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+  const char *pkgdatadir = grub_util_get_pkgdatadir ();
+
+  grub_util_host_init (&argc, &argv);
+  rootdir = xstrdup ("/srv/tftp");
+
+  subdir = grub_util_path_concat (2, GRUB_BOOT_DIR_NAME, GRUB_DIR_NAME);
+
+  argp_parse (&argp, argc, argv, 0, 0, 0);
+
+  base = grub_util_path_concat (2, rootdir, subdir);
+  /* Create the GRUB directory if it is not present.  */
+
+  grub_install_mkdir_p (base);
+
+  grub_install_push_module ("tftp");
+
+  if (!grub_install_source_directory)
+    {
+      enum grub_install_plat plat;
+
+      for (plat = 0; plat < GRUB_INSTALL_PLATFORM_MAX; plat++)
+       if (targets[plat].mkimage_target)
+         {
+           char *platdir = grub_util_path_concat (2, pkgdatadir,
+                                                  grub_install_get_platform_name (plat));
+
+           if (!grub_util_is_directory (platdir))
+             {
+               free (platdir);
+               continue;
+             }
+           process_input_dir (platdir, plat);
+         }
+    }
+  else
+    {
+      enum grub_install_plat plat;
+      plat = grub_install_get_target (grub_install_source_directory);
+      process_input_dir (grub_install_source_directory, plat);
+    }
+  return 0;
+}
diff --git a/util/grub-mknetdir.in b/util/grub-mknetdir.in
deleted file mode 100644 (file)
index b7b59da..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-# Install GRUB on your drive.
-# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,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 <http://www.gnu.org/licenses/>.
-
-# Initialize some variables.
-host_os=@host_os@
-
-rootdir=/srv/tftp
-modules=
-
-no_floppy=
-recheck=no
-debug=no
-debug_image=
-subdir="`echo '/@bootdirname@/@grubdirname@' | sed "s,//*,/,g"`"
-pc_dir="${libdir}/@PACKAGE@/i386-pc"
-ppc_dir="${libdir}/@PACKAGE@/powerpc-ieee1275"
-sparc_dir="${libdir}/@PACKAGE@/sparc64-ieee1275"
-i386_ieee1275_dir="${libdir}/@PACKAGE@/i386-ieee1275"
-efi32_dir="${libdir}/@PACKAGE@/i386-efi"
-efi64_dir="${libdir}/@PACKAGE@/x86_64-efi"
-itanium_dir="${libdir}/@PACKAGE@/ia64-efi"
-
-# Usage: usage
-# Print the usage.
-usage () {
-    gettext_printf "Usage: %s [OPTION]\n" "$self"
-    echo
-    print_option_help "-h, --help" "$(gettext "print this message and exit")"
-    grub_print_install_files_help
-    print_option_help "--net-directory=$(gettext "DIR")" "$(gettext "root directory of TFTP server")"
-    print_option_help "--subdir=$(gettext "DIR")" "$(gettext "relative subdirectory on network server")"
-    echo
-    gettext_printf "%s copies GRUB images into net_directory/subdir/target_cpu-platform\n" "$self" 
-    echo
-    gettext "Report bugs to <bug-grub@gnu.org>."; echo
-}
-
-# Check the arguments.
-while test $# -gt 0
-do
-    grub_process_install_options "$@"
-    case "$grub_process_install_options_consumed" in
-       1) shift; continue;;
-       2) shift; shift; continue;;
-    esac
-
-    option=$1
-    shift
-
-    case "$option" in
-    -h | --help)
-       usage
-       exit 0 ;;
-
-    --net-directory)
-       rootdir=`argument $option "$@"`; shift;;
-    --net-directory=*)
-       rootdir=`echo "$option" | sed 's/--net-directory=//'` ;;
-
-    --subdir)
-       subdir=`argument $option "$@"`; shift;;
-    --subdir=*)
-       subdir=`echo "$option" | sed 's/--subdir=//'` ;;
-
-    # This is an undocumented feature...
-    --debug)
-       debug=yes ;;
-    --debug-image)
-       debug_image=`argument $option "$@"`; shift;;
-    --debug-image=*)
-       debug_image=`echo "$option" | sed 's/--debug-image=//'` ;;
-
-    -*)
-       gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2
-       usage
-       exit 1
-       ;;
-    *)
-       gettext_printf "Unknown extra argument \`%s'." "$option" 1>&2
-       echo 1>&2
-       usage
-       exit 1
-       ;;
-    esac
-done
-
-set $grub_mkimage dummy
-if test -f "$1"; then
-    :
-else
-    gettext_printf "%s: Not found.\n" "$1" 1>&2
-    exit 1
-fi
-
-# Create the GRUB directory if it is not present.
-mkdir -p "${rootdir}/${subdir}" || exit 1
-
-process_input_dir ()
-{ 
-    input_dir="$1"
-    platform="$2"
-    grubdir="${rootdir}/${subdir}/${platform}"
-    config_opt=
-
-    grub_install_files "${input_dir}" "${rootdir}/${subdir}" "${platform}"
-
-    rm -f "${grubdir}"/load.cfg
-
-    if [ "x${debug_image}" != x ]; then
-       echo "set debug='${debug_image}'" >> ${grubdir}/load.cfg
-       config_opt="-c ${grubdir}/load.cfg "
-    fi
-
-    prefix="/${subdir}";
-    case "${platform}" in
-        i386-pc) mkimage_target=i386-pc-pxe;
-                 netmodules="pxe";
-                 ext=0 ;;
-        sparc64-ieee1275) mkimage_target=sparc64-ieee1275-aout;
-                 netmodules="ofnet";
-                 ext=img ;;
-        *-ieee1275) mkimage_target="${platform}";
-                 netmodules="ofnet";
-                 ext=elf ;;
-        *-efi) mkimage_target="${platform}";
-                 netmodules="efinet";
-                 ext=efi ;;
-        *) gettext_printf "Unsupported platform %s\n" ${platform};
-           exit 1;;
-    esac
-
-    cat << EOF > ${grubdir}/grub.cfg
-source ${subdir}/grub.cfg
-EOF
-
-    "$grub_mkimage" ${config_opt} -d "${input_dir}" -O ${mkimage_target} "--output=${grubdir}/core.$ext" "--prefix=$prefix" $modules $grub_decompression_module $netmodules tftp || exit 1
-    # TRANSLATORS: First %s is replaced by platform name. Second one by filename.
-    gettext_printf "Netboot directory for %s created. Configure your DHCP server to point to %s\n" "${platform}" "${subdir}/${platform}/core.$ext"
-}
-
-if [ "${source_directory}" = "" ] ; then
-    if test -e "${pc_dir}" ; then
-        process_input_dir "${pc_dir}" i386-pc
-    fi
-    if test -e "${ppc_dir}" ; then
-        process_input_dir "${ppc_dir}" powerpc-ieee1275
-    fi
-    if test -e "${sparc_dir}" ; then
-        process_input_dir ${sparc_dir} sparc64-ieee1275
-    fi
-    if test -e "${i386_ieee1275_dir}" ; then
-        process_input_dir "${i386_ieee1275_dir}" i386-ieee1275
-    fi
-    if test -e "${efi32_dir}" ; then
-        process_input_dir "${efi32_dir}" i386-efi
-    fi
-    if test -e "${efi64_dir}" ; then
-        process_input_dir "${efi64_dir}" x86_64-efi
-    fi
-    if test -e "${itanium_dir}" ; then
-        process_input_dir "${itanium_dir}" ia64-efi
-    fi
-else
-    . "${source_directory}"/modinfo.sh
-    process_input_dir "${source_directory}" ${grub_modinfo_target_cpu}-${grub_modinfo_platform}
-fi
-
-
-# Bye.
-exit 0
diff --git a/util/grub-mkrescue.c b/util/grub-mkrescue.c
new file mode 100644 (file)
index 0000000..0b8c39b
--- /dev/null
@@ -0,0 +1,827 @@
+/*
+ *  Make GRUB rescue image
+ *
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <grub/util/install.h>
+#include <grub/util/misc.h>
+#include <grub/emu/exec.h>
+#include <grub/emu/config.h>
+#include <argp.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <string.h>
+#include <time.h>
+
+static char *source_dirs[GRUB_INSTALL_PLATFORM_MAX];
+static char *rom_directory;
+static char *label_font;
+static char *label_color;
+static char *label_bgcolor;
+static char *product_name;
+static char *product_version;
+static int xorriso_tail_argc;
+static int xorriso_tail_arg_alloc;
+static char **xorriso_tail_argv;
+static char *output_image;
+static char *xorriso;
+static char *boot_grub;
+static int xorriso_argc;
+static int xorriso_arg_alloc;
+static char **xorriso_argv;
+static char *iso_uuid;
+static char *iso9660_dir;
+
+static void
+xorriso_push (const char *val)
+{
+  if (xorriso_arg_alloc <= xorriso_argc + 1)
+    {
+      xorriso_arg_alloc = 2 * (4 + xorriso_argc);
+      xorriso_argv = xrealloc (xorriso_argv,
+                              sizeof (xorriso_argv[0])
+                              * xorriso_arg_alloc);
+    }
+  xorriso_argv[xorriso_argc++] = xstrdup (val);
+}
+
+static void
+xorriso_link (const char *from, const char *to)
+{
+  char *tof = grub_util_path_concat (2, iso9660_dir, to);
+  char *val = xasprintf ("%s=%s", from, tof);
+  xorriso_push (val);
+  free (val);
+  free (tof);
+}
+
+enum
+  {
+    OPTION_OUTPUT = 'o',
+    OPTION_ROM_DIRECTORY = 0x301,
+    OPTION_XORRISO,
+    OPTION_GLUE_EFI,
+    OPTION_RENDER_LABEL,
+    OPTION_LABEL_FONT,
+    OPTION_LABEL_COLOR,
+    OPTION_LABEL_BGCOLOR,
+    OPTION_PRODUCT_NAME,
+    OPTION_PRODUCT_VERSION,
+    OPTION_SPARC_BOOT,
+    OPTION_ARCS_BOOT
+  };
+
+static struct argp_option options[] = {
+  GRUB_INSTALL_OPTIONS,
+  {"output", 'o', N_("FILE"),
+   0, N_("save output in FILE [required]"), 2},
+  {"rom-directory", OPTION_ROM_DIRECTORY, N_("DIR"),
+   0, N_("save ROM images in DIR [optional]"), 2},
+  {"xorriso", OPTION_XORRISO, N_("FILE"),
+   /* TRANSLATORS: xorriso is a program for creating ISOs and burning CDs.  */
+   0, N_("use FILE as xorriso [optional]"), 2},
+  {"grub-glue-efi", OPTION_GLUE_EFI, N_("FILE"), OPTION_HIDDEN, 0, 2},
+  {"grub-render-label", OPTION_RENDER_LABEL, N_("FILE"), OPTION_HIDDEN, 0, 2},
+  {"label-font", OPTION_LABEL_FONT, N_("FILE"), 0, N_("use FILE as font for label"), 2},
+  {"label-color", OPTION_LABEL_COLOR, N_("COLOR"), 0, N_("use COLOR for label"), 2},
+  {"label-bgcolor", OPTION_LABEL_BGCOLOR, N_("COLOR"), 0, N_("use COLOR for label background"), 2},
+  {"product-name", OPTION_PRODUCT_NAME, N_("STRING"), 0, N_("use STRING as product name"), 2},
+  {"product-version", OPTION_PRODUCT_VERSION, N_("STRING"), 0, N_("use STRING as product version"), 2},
+  {"sparc-boot", OPTION_SPARC_BOOT, 0, 0, N_("enable sparc boot. Disables HFS+, APM, ARCS and boot as disk image for i386-pc"), 2},
+  {"arcs-boot", OPTION_ARCS_BOOT, 0, 0, N_("enable ARCS (big-endian mips machines, mostly SGI) boot. Disables HFS+, APM, sparc64 and boot as disk image for i386-pc"), 2},
+  {0, 0, 0, 0, 0, 0}
+};
+
+static char *
+help_filter (int key, const char *text, void *input __attribute__ ((unused)))
+{
+  switch (key)
+    {
+    case ARGP_KEY_HELP_POST_DOC:
+      return xasprintf (text, "xorriso -as mkisofs -help");
+    default:
+      return grub_install_help_filter (key, text, input);
+    }
+}
+
+enum {
+  SYS_AREA_AUTO,
+  SYS_AREA_COMMON,
+  SYS_AREA_SPARC,
+  SYS_AREA_ARCS
+} system_area = SYS_AREA_AUTO;
+
+static error_t 
+argp_parser (int key, char *arg, struct argp_state *state)
+{
+  if (grub_install_parse (key, arg))
+    return 0;
+  switch (key)
+    {
+    case OPTION_OUTPUT:
+      free (output_image);
+      output_image = xstrdup (arg);
+      return 0;
+    case OPTION_ROM_DIRECTORY:
+      free (rom_directory);
+      rom_directory = xstrdup (arg);
+      return 0;
+
+      /*
+       FIXME:
+    # Intentionally undocumented
+    --grub-mkimage-extra)
+       mkimage_extra_arg="$mkimage_extra_arg `argument $option "$@"`"; shift ;;
+    --grub-mkimage-extra=*)
+       mkimage_extra_arg="$mkimage_extra_arg `echo "$option" | sed 's/--grub-mkimage-extra=//'`" ;;
+      */
+    case OPTION_SPARC_BOOT:
+      system_area = SYS_AREA_SPARC;
+      return 0;
+    case OPTION_ARCS_BOOT:
+      system_area = SYS_AREA_ARCS;
+      return 0;
+    case OPTION_PRODUCT_NAME:
+      free (product_name);
+      product_name = xstrdup (arg);
+      return 0;
+    case OPTION_PRODUCT_VERSION:
+      free (product_version);
+      product_version = xstrdup (arg);
+      return 0;
+      /* Accept and ignore for compatibility.  */
+    case OPTION_GLUE_EFI:
+    case OPTION_RENDER_LABEL:
+      return 0;
+    case OPTION_LABEL_FONT:
+      free (label_font);
+      label_font = xstrdup (arg);
+      return 0;
+
+    case OPTION_LABEL_COLOR:
+      free (label_color);
+      label_color = xstrdup (arg);
+      return 0;
+
+    case OPTION_LABEL_BGCOLOR:
+      free (label_bgcolor);
+      label_bgcolor = xstrdup (arg);
+      return 0;
+
+    case OPTION_XORRISO:
+      free (xorriso);
+      xorriso = xstrdup (arg);
+      return 0;
+
+    case ARGP_KEY_ARG:
+      if (xorriso_tail_arg_alloc <= xorriso_tail_argc)
+       {
+         xorriso_tail_arg_alloc = 2 * (4 + xorriso_tail_argc);
+         xorriso_tail_argv = xrealloc (xorriso_tail_argv,
+                                  sizeof (xorriso_tail_argv[0])
+                                  * xorriso_tail_arg_alloc);
+       }
+      xorriso_tail_argv[xorriso_tail_argc++] = xstrdup (arg);
+      return 0;
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+}
+
+struct argp argp = {
+  options, argp_parser, N_("[OPTION] SOURCE..."),
+  /* TRANSLATORS: it generates one single image which is bootable through any method. */
+  N_("Make GRUB CD-ROM, disk, pendrive and floppy bootable image.")"\v"
+  N_("Generates a bootable rescue image with specified source files, source directories, or mkisofs options listed by the output of `%s'.\n\n"
+     "Option -- switches to native xorriso command mode.\n\n"
+     "Mail xorriso support requests to <bug-xorriso@gnu.org>."), 
+  NULL, help_filter, NULL
+};
+
+static void
+write_part (FILE *f, const char *srcdir)
+{
+  FILE *in;
+  char *inname = grub_util_path_concat (2, srcdir, "partmap.lst");
+  char buf[260];
+  in = grub_util_fopen (inname, "rb");
+  if (!in)
+    return;
+  while (fgets (buf, 256, in))
+    {
+      char *ptr;
+      for (ptr = buf + strlen (buf) - 1;
+          ptr >= buf && (*ptr == '\n' || *ptr == '\r');
+          ptr--);
+      ptr[1] = '\0';
+      fprintf (f, "insmod %s\n", buf);
+    }
+  fclose (in);
+}
+
+static void
+make_image_abs (enum grub_install_plat plat,
+               const char *mkimage_target,
+               const char *output,
+               grub_compression_t compress)
+{
+  char *load_cfg;
+  FILE *load_cfg_f;
+
+  if (!source_dirs[plat])
+    return;
+
+  grub_util_info (N_("enabling %s support ..."),
+                 mkimage_target);
+
+  load_cfg = grub_util_make_temporary_file ();
+
+  load_cfg_f = grub_util_fopen (load_cfg, "wb");
+  fprintf (load_cfg_f, "search --fs-uuid --set=root %s\n", iso_uuid);
+  fprintf (load_cfg_f, "set prefix=(${root})/boot/grub\n");
+
+  write_part (load_cfg_f, source_dirs[plat]);
+  fclose (load_cfg_f);
+
+  grub_install_push_module ("search");
+  grub_install_push_module ("iso9660");
+  grub_install_make_image_wrap (source_dirs[plat], "/boot/grub", output,
+                               0, load_cfg,
+                               mkimage_target, 0,
+                               compress);
+  grub_install_pop_module ();
+  grub_install_pop_module ();
+  grub_util_unlink (load_cfg);
+}
+
+static void
+make_image (enum grub_install_plat plat,
+           const char *mkimage_target,
+           const char *output_sub,
+           grub_compression_t compress)
+{
+  char *out = grub_util_path_concat (2, boot_grub, output_sub);
+  make_image_abs (plat, mkimage_target,
+                 out, GRUB_COMPRESSION_AUTO);
+  free (out);
+}
+
+static void
+make_image_fwdisk_abs (enum grub_install_plat plat,
+                      const char *mkimage_target,
+                      const char *output)
+{
+  if (!source_dirs[plat])
+    return;
+
+  grub_install_push_module ("iso9660");
+  grub_install_make_image_wrap (source_dirs[plat], "()/boot/grub", output,
+                               0, 0, mkimage_target, 0,
+                               GRUB_COMPRESSION_AUTO);
+  grub_install_pop_module ();
+}
+
+static int
+check_xorriso (const char *val)
+{
+  const char *argv[5];
+  int fd;
+  pid_t pid;
+  FILE *mdadm;
+  char *buf = NULL;
+  size_t len = 0;
+  int ret = 0;
+
+  argv[0] = xorriso;
+  argv[1] = "-as";
+  argv[2] = "mkisofs";
+  argv[3] = "-help";
+  argv[4] = NULL;
+
+  pid = grub_util_exec_pipe_stderr (argv, &fd);
+
+  if (!pid)
+    return 0;
+
+  /* Parent.  Read mdadm's output.  */
+  mdadm = fdopen (fd, "r");
+  if (! mdadm)
+    return 0;
+
+  while (getline (&buf, &len, mdadm) > 0)
+    {
+      if (grub_strstr (buf, val))
+       ret = 1;
+    }
+
+  close (fd);
+  waitpid (pid, NULL, 0);
+  free (buf);
+  return ret;
+}
+
+static void
+make_image_fwdisk (enum grub_install_plat plat,
+                  const char *mkimage_target,
+                  const char *output_sub)
+{
+  char *out = grub_util_path_concat (2, boot_grub, output_sub);
+  make_image_fwdisk_abs (plat, mkimage_target, out);
+  free (out);
+}
+
+int
+main (int argc, char *argv[])
+{
+  char *romdir;
+  char *sysarea_img = NULL;
+  const char *pkgdatadir;
+
+  grub_util_host_init (&argc, &argv);
+
+  pkgdatadir = grub_util_get_pkgdatadir ();
+
+  product_name = xstrdup (PACKAGE_NAME);
+  product_version = xstrdup (PACKAGE_VERSION);
+  xorriso = xstrdup ("xorriso");
+  label_font = grub_util_path_concat (2, pkgdatadir, "unicode.pf2");
+
+  argp_parse (&argp, argc, argv, 0, 0, 0);
+
+  if (!output_image)
+    grub_util_error ("%s", _("output file must be specified"));
+
+  xorriso_push (xorriso);
+  xorriso_push ("-as");
+  xorriso_push ("mkisofs");
+  xorriso_push ("-graft-points");
+  
+  iso9660_dir = grub_util_make_temporary_dir ();
+  grub_util_info ("temporaray iso9660 dir is `%s'", 
+                 iso9660_dir);
+  boot_grub = grub_util_path_concat (3, iso9660_dir, "boot", "grub");
+  grub_install_mkdir_p (boot_grub);
+  romdir = grub_util_path_concat (2, boot_grub, "roms");
+  grub_util_mkdir (romdir);
+
+  if (!grub_install_source_directory)
+    {
+      enum grub_install_plat plat;
+
+      for (plat = 0; plat < GRUB_INSTALL_PLATFORM_MAX; plat++)
+       {
+         char *platdir = grub_util_path_concat (2, pkgdatadir,
+                                                grub_install_get_platform_name (plat));
+
+         if (!grub_util_is_directory (platdir))
+           {
+             free (platdir);
+             continue;
+           }
+         source_dirs[plat] = platdir;
+         grub_install_copy_files (platdir,
+                                  boot_grub, plat);
+       }
+    }
+  else
+    {
+      enum grub_install_plat plat;
+      plat = grub_install_get_target (grub_install_source_directory);
+      grub_install_copy_files (grub_install_source_directory,
+                              boot_grub, plat);
+      source_dirs[plat] = xstrdup (grub_install_source_directory);
+    }
+  if (system_area == SYS_AREA_AUTO || grub_install_source_directory)
+    {
+      if (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC]
+         || source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275]
+         || source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]
+         || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI])
+       system_area = SYS_AREA_COMMON;
+      else if (source_dirs[GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275])
+       system_area = SYS_AREA_SPARC;
+      else if (source_dirs[GRUB_INSTALL_PLATFORM_MIPS_ARC])
+       system_area = SYS_AREA_ARCS;
+    }
+
+  /* obtain date-based UUID.  */
+  {
+    time_t tim;
+    struct tm *tmm;
+    tim = time (NULL);
+    tmm = gmtime (&tim);
+    iso_uuid = xmalloc (55);
+    grub_snprintf (iso_uuid, 50,
+                  "%04d-%02d-%02d-%02d-%02d-%02d-00",
+                  tmm->tm_year + 1900,
+                  tmm->tm_mon + 1,
+                  tmm->tm_mday,
+                  tmm->tm_hour,
+                  tmm->tm_min,
+                  tmm->tm_sec);
+  }
+  {
+    char *uuid_out = xmalloc (strlen (iso_uuid) + 1 + 40);
+    char *optr;
+    const char *iptr;
+    optr = grub_stpcpy (uuid_out, "--modification-date=");
+    for (iptr = iso_uuid; *iptr; iptr++)
+      if (*iptr != '-')
+       *optr++ = *iptr;
+    *optr = '\0';
+    xorriso_push (uuid_out);
+    free (uuid_out);
+  }
+
+  /* build BIOS core.img.  */
+  if (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC])
+    {
+      char *load_cfg;
+      FILE *load_cfg_f;
+      char *output = grub_util_path_concat (3, boot_grub, "i386-pc", "eltorito.img");
+      load_cfg = grub_util_make_temporary_file ();
+
+      grub_util_info (N_("enabling %s support ..."), "BIOS");
+      load_cfg_f = grub_util_fopen (load_cfg, "wb");
+      write_part (load_cfg_f, source_dirs[GRUB_INSTALL_PLATFORM_I386_PC]);
+      fclose (load_cfg_f);
+
+      grub_install_push_module ("biosdisk");
+      grub_install_push_module ("iso9660");
+      grub_install_make_image_wrap (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC],
+                                   "/boot/grub", output,
+                                   0, load_cfg,
+                                   "i386-pc-eltorito", 0,
+                                   GRUB_COMPRESSION_AUTO);
+
+      xorriso_push ("-b");
+      xorriso_push ("boot/grub/i386-pc/eltorito.img");
+      xorriso_push ("-no-emul-boot");
+      xorriso_push ("-boot-load-size");
+      xorriso_push ("4");
+      xorriso_push ("-boot-info-table");
+      if (system_area == SYS_AREA_COMMON)
+       {
+         if (check_xorriso ("grub2-boot-info"))
+           {
+             char *boot_hybrid = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_I386_PC],
+                                                        "boot_hybrid.img");
+             xorriso_push ("--grub2-boot-info");
+             xorriso_push ("--grub2-mbr");
+             xorriso_push (boot_hybrid);
+           }
+         else
+           {
+             FILE *sa, *bi;
+             size_t sz;
+             char buf[512];
+             char *bin = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_I386_PC],
+                                                "boot.img");
+             grub_util_warn ("%s", _("Your xorriso doesn't support `--grub2-boot-info'. Some features are disabled. Please use xorriso 1.2.9 or later."));
+             sysarea_img = grub_util_make_temporary_file ();
+             sa = grub_util_fopen (sysarea_img, "wb");
+             if (!sa)
+               grub_util_error (_("cannot open `%s': %s"), sysarea_img,
+                                strerror (errno));
+             bi = grub_util_fopen (sysarea_img, "wb");
+             if (!bi)
+               grub_util_error (_("cannot open `%s': %s"), bin,
+                                strerror (errno));
+             fread (buf, 1, 512, bi);
+             fclose (bi);
+             fwrite (buf, 1, 512, sa);
+             
+             grub_install_make_image_wrap (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC],
+                                           "/boot/grub", output,
+                                           0, load_cfg,
+                                           "i386-pc", 0,
+                                           GRUB_COMPRESSION_AUTO);
+             sz = ftello (sa);
+             fflush (sa);
+             fsync (fileno (sa));
+             fclose (sa);
+             
+             if (sz > 32768)
+               {
+                 grub_util_warn ("%s", _("Your xorriso doesn't support `--grub2-boot-info'. Your core image is too big. Boot as disk is disabled. Please use xorriso 1.2.9 or later."));
+               }
+             else
+               {
+                 xorriso_push ("-G");
+                 xorriso_push (sysarea_img);
+               }
+           }
+       }
+      grub_install_pop_module ();
+      grub_install_pop_module ();
+    }
+
+  /** build multiboot core.img */
+  grub_install_push_module ("pata");
+  grub_install_push_module ("ahci");
+  grub_install_push_module ("at_keyboard");
+  make_image (GRUB_INSTALL_PLATFORM_I386_MULTIBOOT, "i386-multiboot", "i386-multiboot/core.elf", GRUB_COMPRESSION_AUTO);
+  grub_install_pop_module ();
+  grub_install_pop_module ();
+  grub_install_pop_module ();
+
+  make_image_fwdisk (GRUB_INSTALL_PLATFORM_I386_IEEE1275, "i386-ieee1275", "ofwx86.elf");
+
+  char *core_services = NULL;
+
+  if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]
+      || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]
+      || source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275])
+    {
+      char *mach_ker, *sv, *label, *label_text;
+      FILE *f;
+      core_services = grub_util_path_concat (4, iso9660_dir, "System", "Library", "CoreServices");
+      grub_install_mkdir_p (core_services);
+
+      mach_ker = grub_util_path_concat (2, iso9660_dir, "mach_kernel");
+      f = grub_util_fopen (mach_ker, "wb");
+      fclose (f);
+      free (mach_ker);
+
+      sv = grub_util_path_concat (2, core_services, "SystemVersion.plist");
+      f = grub_util_fopen (sv, "wb");
+      fprintf (f, "<plist version=\"1.0\">\n"
+              "<dict>\n"
+              "        <key>ProductBuildVersion</key>\n"
+              "        <string></string>\n"
+              "        <key>ProductName</key>\n"
+              "        <string>%s</string>\n"
+              "        <key>ProductVersion</key>\n"
+              "        <string>%s</string>\n"
+              "</dict>\n"
+              "</plist>\n", product_name, product_version);
+      fclose (f);
+      free (sv);
+      label = grub_util_path_concat (2, core_services, ".disk_label");
+      char *label_string = xasprintf ("%s %s", product_name, product_version);
+      grub_util_render_label (label_font, label_bgcolor ? : "white",
+                             label_color ? : "black", label_string, label);
+      free (label);
+      label_text = grub_util_path_concat (2, core_services, ".disk_label.contentDetails");
+      f = grub_util_fopen (label_text, "wb");
+      fprintf (f, "%s", label_string);
+      fclose (f);
+      free (label_string);
+      free (label_text);
+      if (system_area == SYS_AREA_COMMON)
+       {
+         xorriso_push ("-hfsplus");
+         xorriso_push ("-apm-block-size");
+         xorriso_push ("2048");
+         xorriso_push ("-hfsplus-file-creator-type");
+         xorriso_push ("chrp");
+         xorriso_push ("tbxj");
+         xorriso_push ("/System/Library/CoreServices/.disk_label");
+
+         if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]
+             || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI])
+           {
+             xorriso_push ("-hfs-bless-by");
+             xorriso_push ("i");
+             xorriso_push ("/System/Library/CoreServices/boot.efi");
+           }
+       }
+    }
+
+  if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]
+      || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]
+      || source_dirs[GRUB_INSTALL_PLATFORM_IA64_EFI]
+      || source_dirs[GRUB_INSTALL_PLATFORM_ARM_EFI])
+    {
+      char *efidir = grub_util_make_temporary_dir ();
+      char *efidir_efi = grub_util_path_concat (2, efidir, "efi");
+      char *efidir_efi_boot = grub_util_path_concat (3, efidir, "efi", "boot");
+      char *imgname, *img32, *img64, *img_mac = NULL;
+      char *efiimgfat;
+      grub_install_mkdir_p (efidir_efi_boot);
+
+      imgname = grub_util_path_concat (2, efidir_efi_boot, "bootia64.efi");
+      make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_IA64_EFI, "ia64-efi", imgname);
+      free (imgname);
+
+      img64 = grub_util_path_concat (2, efidir_efi_boot, "bootx64.efi");
+      make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_X86_64_EFI, "x86_64-efi", img64);
+
+      img32 = grub_util_path_concat (2, efidir_efi_boot, "bootia32.efi");
+      make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_I386_EFI, "i386-efi", img32);
+
+      imgname = grub_util_path_concat (2, efidir_efi_boot, "bootarm.efi");
+      make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_ARM_EFI, "arm-efi", imgname);
+      free (imgname);
+
+      if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI])
+       {
+         imgname = grub_util_path_concat (2, efidir_efi_boot, "boot.efi");
+         /* For old macs. Suggested by Peter Jones.  */
+         grub_install_copy_file (img32, imgname, 1);
+       }
+
+      if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]
+         || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI])
+       img_mac = grub_util_path_concat (2, core_services, "boot.efi");
+
+      if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]
+         && source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI])
+       grub_util_glue_efi (img32, img64, img_mac);
+      else if (source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI])
+       grub_install_copy_file (img64, img_mac, 1);
+      else if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI])
+       grub_install_copy_file (img32, img_mac, 1);
+
+      free (img_mac);
+      free (img32);
+      free (img64);
+      free (efidir_efi_boot);
+
+      efiimgfat = grub_util_path_concat (2, iso9660_dir, "efi.img");
+      grub_util_exec ((const char * []) { "mformat", "-C", "-f", "2880", "-L", "16", "-i",
+           efiimgfat, "::", NULL });
+      grub_util_exec ((const char * []) { "mcopy", "-s", "-i", efiimgfat, efidir_efi, "::/", NULL });
+      xorriso_push ("--efi-boot");
+      xorriso_push ("efi.img");
+      xorriso_push ("-efi-boot-part");
+      xorriso_push ("--efi-boot-image");
+
+      grub_util_unlink_recursive (efidir);
+      free (efiimgfat);
+      free (efidir_efi);
+      free (efidir);
+    }
+
+  make_image_fwdisk (GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275, "powerpc-ieee1275", "powerpc-ieee1275/core.elf");
+
+  if (source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275])
+    {
+      char *grub_chrp = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275],
+                                              "grub.chrp");
+      char *bisrc = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275],
+                                          "grub.chrp");
+      char *bootx = grub_util_path_concat (2, core_services, "BootX");
+      char *ppc_chrp = grub_util_path_concat (3, iso9660_dir, "ppc", "chrp");
+      char *bitgt = grub_util_path_concat (3, iso9660_dir, "ppc", "bootinfo.txt");
+      grub_install_copy_file (grub_chrp, bootx, 1);
+      grub_install_mkdir_p (ppc_chrp);
+      grub_install_copy_file (bisrc, bitgt, 1);
+      xorriso_link ("/System/Library/CoreServices/grub.elf", "/boot/grub/powerpc-ieee1275/core.elf");
+      xorriso_link ("/boot/grub/powerpc.elf", "/boot/grub/powerpc-ieee1275/core.elf");
+      /* FIXME: add PreP */
+      if (system_area == SYS_AREA_COMMON)
+       {
+         xorriso_push ("-hfsplus-file-creator-type");
+         xorriso_push ("chrp");
+         xorriso_push ("tbxi");
+         xorriso_push ("/System/Library/CoreServices/BootX");
+         xorriso_push ("-hfs-bless-by");
+         xorriso_push ("p");
+         xorriso_push ("/System/Library/CoreServices");
+       }
+      xorriso_push ("-sysid");
+      xorriso_push ("PPC");
+    }
+
+  make_image_fwdisk (GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275,
+                    "sparc64-ieee1275-cdcore", "sparc64-ieee1275/core.img");
+
+  if (source_dirs[GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275]
+      && system_area == SYS_AREA_SPARC)
+    {
+      char *cdboot;
+      FILE *in, *out;
+      char buf[512];
+      sysarea_img = grub_util_make_temporary_file ();
+      cdboot = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275],
+                                     "cdboot.img");
+      in = grub_util_fopen (cdboot, "rb");
+      out = grub_util_fopen (sysarea_img, "wb");
+      memset (buf, 0, 512);
+      fwrite (buf, 1, 512, out);
+      fread (buf, 1, 512, in);
+      fwrite (buf, 1, 512, out);
+      fclose (in);
+      fclose (out);
+      xorriso_push ("-G");
+      xorriso_push (sysarea_img);
+      xorriso_push ("-B");
+      xorriso_push (",");
+      xorriso_push ("--grub2-sparc-core");
+      xorriso_push ("/boot/grub/sparc64-ieee1275/core.img");
+    }
+
+  make_image_fwdisk (GRUB_INSTALL_PLATFORM_MIPS_ARC, "mips-arc", "mips-arc/core.img");
+
+  if (source_dirs[GRUB_INSTALL_PLATFORM_MIPS_ARC])
+    {
+      xorriso_link ("/boot/grub/mips-arc/grub", "/boot/grub/mips-arc/core.img");
+      xorriso_link ("/boot/grub/mips-arc/sashARCS", "/boot/grub/mips-arc/core.img");
+      xorriso_link ("/boot/grub/mips-arc/sash", "/boot/grub/mips-arc/core.img");
+    }
+  if (source_dirs[GRUB_INSTALL_PLATFORM_MIPS_ARC] && system_area == SYS_AREA_ARCS)
+    {
+      xorriso_push ("-mips-boot");
+      xorriso_push ("/boot/grub/mips-arc/sashARCS");
+      xorriso_push ("-mips-boot");
+      xorriso_push ("/boot/grub/mips-arc/sash");
+      xorriso_push ("-mips-boot");
+      xorriso_push ("/boot/grub/mips-arc/grub");
+    }
+
+  make_image_fwdisk (GRUB_INSTALL_PLATFORM_MIPSEL_ARC, "mipsel-arc", "arc.exe");
+
+  grub_install_push_module ("pata");
+  make_image (GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS, "mipsel-qemu_mips-elf", "roms/mipsel-qemu_mips.elf", GRUB_COMPRESSION_AUTO);
+
+  make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-loongson-elf", "loongson.elf", GRUB_COMPRESSION_XZ);
+
+  make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-yeeloong-flash", "mipsel-yeeloong.bin", GRUB_COMPRESSION_XZ);
+  make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-fulong2f-flash", "mipsel-fuloong2f.bin", GRUB_COMPRESSION_XZ);
+
+  make_image (GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, "mips-qemu_mips-elf", "roms/mips-qemu_mips.elf", GRUB_COMPRESSION_AUTO);
+
+  grub_install_push_module ("at_keyboard");
+
+  make_image (GRUB_INSTALL_PLATFORM_I386_QEMU, "i386-qemu", "roms/qemu.img", GRUB_COMPRESSION_AUTO);
+
+  grub_install_push_module ("ahci");
+
+  make_image (GRUB_INSTALL_PLATFORM_I386_COREBOOT, "i386-coreboot", "roms/coreboot.elf", GRUB_COMPRESSION_AUTO);
+  grub_install_pop_module ();
+  grub_install_pop_module ();
+  grub_install_pop_module ();
+
+  if (rom_directory)
+    {
+      const struct
+      {
+       enum grub_install_plat plat;
+       const char *from, *to;
+      } roms[] =
+         {
+           {GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS, "roms/mipsel-qemu_mips.elf", "mipsel-qemu_mips.elf"},
+           {GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "loongson.elf", "mipsel-loongson.elf"},
+           {GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "roms/mipsel-yeeloong.bin", "mipsel-yeeloong.bin"},
+           {GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "roms/mipsel-fulong.bin", "mipsel-fulong.bin"},
+           {GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, "roms/mips-qemu_mips.elf", "mips-qemu_mips.elf"},
+           {GRUB_INSTALL_PLATFORM_I386_QEMU, "roms/qemu.img", "qemu.img"},
+           {GRUB_INSTALL_PLATFORM_I386_COREBOOT, "roms/coreboot.elf", "coreboot.elf"},
+         };
+      grub_size_t i;
+      for (i = 0; i < ARRAY_SIZE (roms); i++)
+       {
+         char *from = grub_util_path_concat (2, boot_grub, roms[i].from);
+         char *to = grub_util_path_concat (2, rom_directory, roms[i].to);
+         grub_install_copy_file (from, to, 0);
+       }
+    }
+
+  xorriso_push ("--protective-msdos-label");
+  xorriso_push ("-o");
+  xorriso_push (output_image);
+  xorriso_push ("-r");
+  xorriso_push (iso9660_dir);
+  xorriso_push ("--sort-weight");
+  xorriso_push ("0");
+  xorriso_push ("/");
+  xorriso_push ("--sort-weight");
+  xorriso_push ("1");
+  xorriso_push ("/boot");
+  int i;
+  for (i = 0; i < xorriso_tail_argc; i++)
+    xorriso_push (xorriso_tail_argv[i]);
+
+  xorriso_argv[xorriso_argc] = NULL;
+
+  grub_util_exec ((const char *const *)xorriso_argv);
+
+  grub_util_unlink_recursive (iso9660_dir);
+
+  if (sysarea_img)
+    grub_util_unlink (sysarea_img);
+
+  free (core_services);
+  free (romdir);
+  return 0;
+}
diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in
deleted file mode 100644 (file)
index 444ef85..0000000
+++ /dev/null
@@ -1,493 +0,0 @@
-#!/bin/sh
-
-# Make GRUB rescue image
-# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,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 <http://www.gnu.org/licenses/>.
-
-# Initialize some variables.
-
-multiboot_dir="${libdir}/@PACKAGE@/i386-multiboot"
-coreboot_dir="${libdir}/@PACKAGE@/i386-coreboot"
-qemu_dir="${libdir}/@PACKAGE@/i386-qemu"
-mipsel_qemu_dir="${libdir}/@PACKAGE@/mipsel-qemu_mips"
-loongson_dir="${libdir}/@PACKAGE@/mipsel-loongson"
-mips_qemu_dir="${libdir}/@PACKAGE@/mips-qemu_mips"
-pc_dir="${libdir}/@PACKAGE@/i386-pc"
-i386_ieee1275_dir="${libdir}/@PACKAGE@/i386-ieee1275"
-efi32_dir="${libdir}/@PACKAGE@/i386-efi"
-efi64_dir="${libdir}/@PACKAGE@/x86_64-efi"
-ia64_dir="${libdir}/@PACKAGE@/ia64-efi"
-sparc64_dir="${libdir}/@PACKAGE@/sparc64-ieee1275"
-arcs_dir="${libdir}/@PACKAGE@/mips-arc"
-arc_dir="${libdir}/@PACKAGE@/mipsel-arc"
-ppc_dir="${libdir}/@PACKAGE@/powerpc-ieee1275"
-rom_directory=
-grub_render_label="${bindir}/@grub_render_label@"
-grub_glue_efi="${bindir}/@grub_glue_efi@"
-label_font="${pkgdatadir}/unicode.pf2"
-label_color="black"
-label_bgcolor="white"
-product_name="${PACKAGE_NAME}"
-product_version="${PACKAGE_VERSION}"
-
-xorriso=xorriso
-
-# Usage: usage
-# Print the usage.
-usage () {
-    gettext_printf "Usage: %s [OPTION] SOURCE...\n" "$self"
-    # TRANSLATORS: it generates one single image which is bootable through any method.
-    gettext "Make GRUB CD-ROM, disk, pendrive and floppy bootable image."; echo
-    echo
-    filetrans="$(gettext FILE)"
-    print_option_help "-h, --help" "$(gettext "print this message and exit")"
-    print_option_help "-o, --output=$filetrans" "$(gettext "save output in FILE [required]")"
-    grub_print_install_files_help
-    print_option_help "--rom-directory=$(gettext "DIR")" "$(gettext "save ROM images in DIR [optional]")"
-    # TRANSLATORS: xorriso is a program for creating ISOs and burning CDs
-    print_option_help "--xorriso=$filetrans" "$(gettext "use FILE as xorriso [optional]")"
-    print_option_help "--grub-glue-efi=$filetrans" "$(gettext "use FILE as grub-glue-efi")"
-    print_option_help "--grub-render-label=$filetrans" "$(gettext "use FILE as grub-render-label")"
-    print_option_help "--label-font=$filetrans" "$(gettext "use FILE as font for label")"
-    print_option_help "--label-color=$(gettext "COLOR")" "$(gettext "use COLOR for label")"
-    print_option_help "--label-bgcolor=$(gettext "COLOR")" "$(gettext "use COLOR for label background")"
-    print_option_help "--product-name=$(gettext "STRING")" "$(gettext "use STRING as product name")"
-    print_option_help "--product-version=$(gettext "STRING")" "$(gettext "use STRING as product version")"
-    print_option_help "--sparc-boot" "$(gettext "enable sparc boot. Disables HFS+, APM, ARCS and boot as disk image for i386-pc")"
-    print_option_help "--arcs-boot" "$(gettext "enable ARCS (big-endian mips machines, mostly SGI) boot. Disables HFS+, APM, sparc64 and boot as disk image for i386-pc")"
-    echo
-    gettext_printf "%s generates a bootable rescue image with specified source files, source directories, or mkisofs options listed by the output of \`%s'\n" "xorriso -as mkisofs -help" "$self" | grub_fmt
-    echo
-    gettext "Option -- switches to native xorriso command mode."; echo
-    echo
-    gettext "Report bugs to <bug-grub@gnu.org>."; echo
-    gettext "Mail xorriso support requests to <bug-xorriso@gnu.org>."; echo
-}
-
-system_area=auto
-mkimage_extra_arg=
-
-# Check the arguments.
-while test $# -gt 0
-do
-    grub_process_install_options "$@"
-    case "$grub_process_install_options_consumed" in
-       1) shift; continue;;
-       2) shift; shift; continue;;
-    esac
-
-    option=$1
-    shift
-
-    case "$option" in
-    -h | --help)
-       usage
-       exit 0 ;;
-
-    -o | --output)
-       output_image=`argument $option "$@"`; shift ;;
-    --output=*)
-       output_image=`echo "$option" | sed 's/--output=//'` ;;
-
-    --rom-directory)
-        rom_directory=`argument $option "$@"`; shift ;;
-    --rom-directory=*)
-       rom_directory=`echo "$option" | sed 's/--rom-directory=//'` ;;
-
-    # Intentionally undocumented
-    --grub-mkimage-extra)
-       mkimage_extra_arg="$mkimage_extra_arg `argument $option "$@"`"; shift ;;
-    --grub-mkimage-extra=*)
-       mkimage_extra_arg="$mkimage_extra_arg `echo "$option" | sed 's/--grub-mkimage-extra=//'`" ;;
-
-    --sparc-boot)
-        system_area=sparc64 ;;
-
-    --arcs-boot)
-        system_area=arcs ;;
-
-    --product-name)
-        product_name=`argument $option "$@"`; shift ;;
-    --product-name=*)
-       product_name=`echo "$option" | sed 's/--product-name=//'` ;;
-
-    --product-version)
-        product_version=`argument $option "$@"`; shift ;;
-    --product-version=*)
-       product_version=`echo "$option" | sed 's/--product-version=//'` ;;
-
-    --grub-glue-efi)
-       grub_glue_efi=`argument $option "$@"`; shift ;;
-    --grub-glue-efi=*)
-       grub_glue_efi=`echo "$option" | sed 's/--grub-glue-efi=//'` ;;
-
-    --grub-render-label)
-       grub_render_label=`argument $option "$@"`; shift ;;
-    --grub-render-label=*)
-       grub_render_label=`echo "$option" | sed 's/--grub-render-label=//'` ;;
-
-    --label-font)
-       label_font=`argument $option "$@"`; shift ;;
-    --label-font=*)
-       label_font=`echo "$option" | sed 's/--label-font=//'` ;;
-
-    --label-color)
-       label_color=`argument $option "$@"`; shift ;;
-    --label-color=*)
-       label_color=`echo "$option" | sed 's/--label-color=//'` ;;
-
-    --label-bgcolor)
-       label_bgcolor=`argument $option "$@"`; shift ;;
-    --label-bgcolor=*)
-       label_bgcolor=`echo "$option" | sed 's/--label-bgcolor=//'` ;;
-
-    --xorriso)
-       xorriso=`argument $option "$@"`; shift ;;
-    --xorriso=*)
-        xorriso=`echo "${option}" | sed 's/--xorriso=//'` ;;
-
-    *)
-       source="${source} ${option} $@"; break ;;
-    esac
-done
-
-if [ "x${output_image}" = x ] ; then
-  gettext "output file must be specified" >&2
-  echo >&2
-  usage
-  exit 1
-fi
-
-set $grub_mkimage dummy
-if test -f "$1"; then
-    :
-else
-    gettext_printf "%s: Not found.\n" "$1" 1>&2
-    exit 1
-fi
-
-iso9660_dir=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1
-mkdir -p ${iso9660_dir}/boot/grub
-mkdir -p ${iso9660_dir}/boot/grub/roms
-
-process_input_dir ()
-{
-    grub_install_files "$1" "${iso9660_dir}/boot/grub" "$2"
-}
-
-make_image ()
-{
-    source_directory="$1"
-    platform=$2
-    if ! test -e "${source_directory}"; then
-       return;
-    fi
-
-    gettext_printf "Enabling %s support ...\n" "$2"
-
-    load_cfg="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`"
-
-    (cat << EOF
-search --fs-uuid --set=root ${iso_uuid}
-set prefix=(\${root})/boot/grub
-EOF
-    for i in $(cat "${source_directory}/partmap.lst") ${modules} ; do
-        echo "insmod $i"
-    done ; ) > "${load_cfg}"
-
-    "$grub_mkimage" -O ${platform} -d "${source_directory}" -c "${load_cfg}" -o "$3" \
-        $grub_decompression_module search iso9660 $4
-    rm -rf "${load_cfg}"
-}
-
-make_image_fwdisk ()
-{
-    source_directory="$1"
-    platform=$2
-    if ! test -e "${source_directory}"; then
-       return;
-    fi
-
-    gettext_printf "Enabling %s support ...\n" "$2"
-
-    "$grub_mkimage" -O ${platform} -d "${source_directory}" -p '()/boot/grub' -o "$3" \
-        $grub_decompression_module iso9660 $4
-}
-
-if [ "${source_directory}" = "" ] ; then
-    if [ "$system_area" = auto ]; then
-       if test -e "${pc_dir}" || test -e "${ppc_dir}" \
-           || test -e "${efi32_dir}" || test -e "${efi64_dir}"; then 
-           system_area=common;
-       elif test -e "${sparc64_dir}" ; then
-           system_area=sparc64;
-       elif test -e "${arcs_dir}" ; then
-           system_area=arcs;
-       fi
-    fi
-    if test -e "${multiboot_dir}" ; then
-        process_input_dir "${multiboot_dir}" i386-multiboot
-    fi
-    if test -e "${coreboot_dir}" ; then
-        process_input_dir "${coreboot_dir}" i386-coreboot
-    fi
-    if test -e "${qemu_dir}" ; then
-        process_input_dir "${qemu_dir}" i386-qemu
-    fi
-    if test -e "${pc_dir}" ; then
-        process_input_dir "${pc_dir}" i386-pc
-    fi
-    if test -e "${i386_ieee1275_dir}" ; then
-       process_input_dir "${i386_ieee1275_dir}" i386-ieee1275
-    fi
-    if test -e "${efi32_dir}" ; then
-        process_input_dir "${efi32_dir}" i386-efi
-    fi
-    if test -e "${efi64_dir}" ; then
-        process_input_dir "${efi64_dir}" x86_64-efi
-    fi
-    if test -e "${ia64_dir}" ; then
-        process_input_dir "${ia64_dir}" ia64-efi
-    fi
-    if test -e "${mips_qemu_dir}" ; then
-        process_input_dir "${mips_qemu_dir}" mips-qemu_mips
-    fi
-    if test -e "${mipsel_qemu_dir}" ; then
-        process_input_dir "${mipsel_qemu_dir}" mipsel-qemu_mips
-    fi
-    if test -e "${loongson_dir}" ; then
-        process_input_dir "${loongson_dir}" mipsel-loongson
-    fi
-    if test -e "${ppc_dir}" ; then
-        process_input_dir "${ppc_dir}" powerpc-ieee1275
-    fi
-    if test -e "${sparc64_dir}" ; then
-        process_input_dir "${sparc64_dir}" sparc64-ieee1275
-    fi
-    if test -e "${arcs_dir}" ; then
-        process_input_dir "${arcs_dir}" mips-arc
-    fi
-    if test -e "${arc_dir}" ; then
-        process_input_dir "${arc_dir}" mipsel-arc
-    fi
-else
-    . "${source_directory}"/modinfo.sh
-    process_input_dir "${source_directory}" ${grub_modinfo_target_cpu}-${grub_modinfo_platform}
-    multiboot_dir=
-    pc_dir=
-    efi32_dir=
-    efi64_dir=
-    ia64_dir=
-    coreboot_dir=
-    qemu_dir=
-    mipsel_qemu_dir=
-    mips_qemu_dir=
-    loongson_dir=
-    ppc_dir=
-    i386_ieee1275_dir=
-    sparc64_dir=
-    arcs_dir=
-    arc_dir=
-    case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in
-        i386-multiboot) multiboot_dir="${source_directory}" ;;
-        i386-coreboot) coreboot_dir="${source_directory}" ;;
-        i386-qemu) qemu_dir="${source_directory}" ;;
-        i386-pc) pc_dir="${source_directory}"; system_area=common;;
-       i386-efi) efi32_dir="${source_directory}"; system_area=common ;;
-       x86_64-efi) efi64_dir="${source_directory}"; system_area=common ;;
-       ia64-efi) ia64_dir="${source_directory}" ;;
-       mipsel-qemu_mips) mipsel_qemu_dir="${source_directory}" ;;
-       mipsel-loongson) loongson_dir="${source_directory}" ;;
-       mips-qemu_mips) mips_qemu_dir="${source_directory}" ;;
-       powerpc-ieee1275) ppc_dir="${source_directory}"; system_area=common ;;
-       sparc64-ieee1275) sparc64_dir="${source_directory}"; system_area=sparc64 ;;
-       mips-arc) arcs_dir="${source_directory}"; system_area=arcs ;;
-       mipsel-arc) arc_dir="${source_directory}" ;;
-       i386-ieee1275) i386_ieee1275_dir="${source_directory}" ;;
-    esac
-fi
-
-# obtain date-based UUID
-iso_uuid=$(date -u +%Y-%m-%d-%H-%M-%S-00)
-grub_mkisofs_arguments="${grub_mkisofs_arguments} --modification-date=$(echo ${iso_uuid} | sed -e s/-//g)"
-
-# build BIOS core.img
-if test -e "${pc_dir}" ; then
-    gettext_printf "Enabling %s support ...\n" "BIOS"
-    load_cfg="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`"
-    core_img="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1
-
-    (for i in $(cat "${pc_dir}/partmap.lst") ${modules} ; do
-        echo "insmod $i"
-    done ;) > "${load_cfg}"
-
-    "$grub_mkimage" -O i386-pc -d "${pc_dir}/" -o "${core_img}" -c "$load_cfg" --prefix=/boot/grub \
-        $grub_decompression_module iso9660 biosdisk
-    cat "${pc_dir}/cdboot.img" "${core_img}" > "${iso9660_dir}/boot/grub/i386-pc/eltorito.img"
-
-    grub_mkisofs_arguments="${grub_mkisofs_arguments} -b boot/grub/i386-pc/eltorito.img -no-emul-boot -boot-load-size 4 -boot-info-table"
-    if [ "$system_area" = common ]; then
-       if "${xorriso}" -as mkisofs -help 2>&1 | fgrep "grub2-boot-info" >/dev/null; then
-           grub_mkisofs_arguments="${grub_mkisofs_arguments} --grub2-boot-info --grub2-mbr ${pc_dir}/boot_hybrid.img"
-       else
-           gettext "Your xorriso doesn't support \`--grub2-boot-info'. Some features are disabled. Please use xorriso 1.2.9 or later."
-           echo
-           sysarea_img="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1
-           cat "${pc_dir}/boot.img" "${core_img}" > "${sysarea_img}"
-           if [ "$(wc -c "${sysarea_img}" | awk '{ print $1; }')" -gt 32768 ]; then
-               gettext "Your xorriso doesn't support \`--grub2-boot-info'. Your core image is too big. Boot as disk is disabled. Please use xorriso 1.2.9 or later."
-               echo
-           else
-               grub_mkisofs_arguments="${grub_mkisofs_arguments} -G ${sysarea_img}"
-           fi
-       fi
-    fi
-
-    rm -f "${core_img}"
-fi
-
-# build multiboot core.img
-make_image "${multiboot_dir}" i386-multiboot "${iso9660_dir}/boot/grub/i386-multiboot/core.elf" "pata ahci at_keyboard"
-
-make_image_fwdisk "${i386_ieee1275_dir}" i386-ieee1275 "${iso9660_dir}/boot/grub/ofwx86.elf" ""
-
-if test -e "${efi64_dir}" || test -e "${efi32_dir}" || test -e "${ia64_dir}"; then
-    efi_dir=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1
-    mkdir -p "${efi_dir}/efi/boot"
-
-    # build bootia64.efi
-    make_image_fwdisk "${ia64_dir}" ia64-efi "${efi_dir}"/efi/boot/bootia64.efi ""
-    # build bootx64.efi
-    make_image_fwdisk "${efi64_dir}" x86_64-efi "${efi_dir}"/efi/boot/bootx64.efi ""
-    # build bootia32.efi
-    make_image_fwdisk "${efi32_dir}" i386-efi "${efi_dir}"/efi/boot/bootia32.efi ""
-    if [ -e "${efi_dir}"/efi/boot/bootia32.efi ]; then
-        # For old macs. Suggested by Peter Jones.
-       cp "${efi_dir}"/efi/boot/bootia32.efi "${efi_dir}"/efi/boot/boot.efi
-    fi
-
-    if [ -e "${efi_dir}"/efi/boot/bootx64.efi ] || [ -e "${efi_dir}"/efi/boot/bootia32.efi ]; then
-       mkdir -p "${iso9660_dir}"/System/Library/CoreServices
-    fi
-
-    if [ -e "${efi_dir}"/efi/boot/bootx64.efi ] && [ -e "${efi_dir}"/efi/boot/bootia32.efi ]; then
-       "$grub_glue_efi" -6 "${efi_dir}"/efi/boot/bootx64.efi -3 "${efi_dir}"/efi/boot/bootia32.efi -o "${iso9660_dir}"/System/Library/CoreServices/boot.efi
-    elif [ -e "${efi_dir}"/efi/boot/bootx64.efi ]; then
-       cp "${efi_dir}"/efi/boot/bootx64.efi "${iso9660_dir}"/System/Library/CoreServices/boot.efi
-    elif [ -e "${efi_dir}"/efi/boot/bootia32.efi ]; then
-       cp "${efi_dir}"/efi/boot/bootia32.efi "${iso9660_dir}"/System/Library/CoreServices/boot.efi
-    fi
-
-    mformat -C -f 2880 -L 16 -i "${iso9660_dir}"/efi.img ::
-    mcopy -s -i "${iso9660_dir}"/efi.img ${efi_dir}/efi ::/
-    rm -rf ${efi_dir}
-    grub_mkisofs_arguments="${grub_mkisofs_arguments} --efi-boot efi.img -efi-boot-part --efi-boot-image"
-fi
-
-make_image_fwdisk "${ppc_dir}" powerpc-ieee1275 "${iso9660_dir}/boot/grub/powerpc-ieee1275/core.elf" ""
-if [ -e "${iso9660_dir}"/System/Library/CoreServices/boot.efi ] || [ -e "${iso9660_dir}/boot/grub/powerpc-ieee1275/core.elf" ]; then
-    mkdir -p "${iso9660_dir}"/System/Library/CoreServices
-    touch "${iso9660_dir}/mach_kernel"
-    cat > "${iso9660_dir}/System/Library/CoreServices/SystemVersion.plist" <<EOF
-<plist version="1.0">
-<dict>
-        <key>ProductBuildVersion</key>
-        <string></string>
-        <key>ProductName</key>
-        <string>${product_name}</string>
-        <key>ProductVersion</key>
-        <string>${product_version}</string>
-</dict>
-</plist>
-EOF
-    "$grub_render_label" -f "$label_font" -b "$label_bgcolor" -c "$label_color" -t "${product_name} ${product_version}" -o "${iso9660_dir}/System/Library/CoreServices/.disk_label"
-    echo "${product_name} ${product_version}" > "${iso9660_dir}/System/Library/CoreServices/.disk_label.contentDetails"
-    if [ "$system_area" = common ]; then
-       grub_mkisofs_arguments="${grub_mkisofs_arguments} -hfsplus -apm-block-size 2048 -hfsplus-file-creator-type chrp tbxj /System/Library/CoreServices/.disk_label"
-    fi
-fi
-
-if [ -e "${iso9660_dir}/boot/grub/powerpc-ieee1275/core.elf" ] ; then
-    cp "${ppc_dir}/grub.chrp" "${iso9660_dir}"/System/Library/CoreServices/BootX
-    mkdir -p "${iso9660_dir}"/ppc/chrp
-    cp "${ppc_dir}/bootinfo.txt" "${iso9660_dir}"/ppc/bootinfo.txt
-    grub_mkisofs_arguments="${grub_mkisofs_arguments} /System/Library/CoreServices/grub.elf=${iso9660_dir}/boot/grub/powerpc-ieee1275/core.elf /boot/grub/powerpc.elf=${iso9660_dir}/boot/grub/powerpc-ieee1275/core.elf"
-    # FIXME: add PreP
-    if [ "$system_area" = common ]; then
-       grub_mkisofs_arguments="${grub_mkisofs_arguments} -hfsplus-file-creator-type chrp tbxi /System/Library/CoreServices/BootX -hfs-bless-by p /System/Library/CoreServices"
-    fi
-    grub_mkisofs_arguments="${grub_mkisofs_arguments} -sysid PPC"
-fi
-
-if [ -e "${iso9660_dir}"/System/Library/CoreServices/boot.efi ] && [ "$system_area" = common ]; then
-    grub_mkisofs_arguments="${grub_mkisofs_arguments} -hfs-bless-by i /System/Library/CoreServices/boot.efi"
-fi
-
-make_image_fwdisk "${sparc64_dir}" sparc64-ieee1275-cdcore "${iso9660_dir}/boot/grub/sparc64-ieee1275/core.img" ""
-if [ -e "${iso9660_dir}"/boot/grub/sparc64-ieee1275/core.img ] && [ "$system_area" = sparc64 ]; then
-   sysarea_img="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1
-   dd if=/dev/zero count=1 bs=512 | cat - "${sparc64_dir}"/cdboot.img > "$sysarea_img"
-   grub_mkisofs_arguments="${grub_mkisofs_arguments} -G $sysarea_img -B , --grub2-sparc-core /boot/grub/sparc64-ieee1275/core.img"
-fi
-
-make_image_fwdisk "${arcs_dir}" mips-arc "${iso9660_dir}/boot/grub/mips-arc/core.img" ""
-if [ -e "${iso9660_dir}/boot/grub/mips-arc/core.img" ]; then
-   grub_mkisofs_arguments="${grub_mkisofs_arguments} /boot/grub/mips-arc/grub=${iso9660_dir}/boot/grub/mips-arc/core.img /boot/grub/mips-arc/sashARCS=${iso9660_dir}/boot/grub/mips-arc/core.img  /boot/grub/mips-arc/sash=${iso9660_dir}/boot/grub/mips-arc/core.img"
-fi
-if [ -e "${iso9660_dir}/boot/grub/mips-arc/core.img" ] && [ "$system_area" = arcs ]; then
-   grub_mkisofs_arguments="${grub_mkisofs_arguments} -mips-boot /boot/grub/mips-arc/sashARCS -mips-boot /boot/grub/mips-arc/sash -mips-boot /boot/grub/mips-arc/grub"
-fi
-
-make_image_fwdisk "${arc_dir}" mipsel-arc "${iso9660_dir}/boot/grub/arc.exe" ""
-
-make_image "${mipsel_qemu_dir}" mipsel-qemu_mips-elf "${iso9660_dir}/boot/grub/roms/mipsel-qemu_mips.elf" "pata"
-if [ -e "${iso9660_dir}/boot/grub/roms/mipsel-qemu_mips.elf" ] && [ -d "${rom_directory}" ]; then
-    cp "${iso9660_dir}/boot/grub/roms/mipsel-qemu_mips.elf" "${rom_directory}/mipsel-qemu_mips.elf"
-fi
-
-make_image "${loongson_dir}" mipsel-loongson-elf "${iso9660_dir}/boot/grub/loongson.elf" "pata -C xz"
-if [ -e "${iso9660_dir}/boot/grub/loongson.elf" ] && [ -d "${rom_directory}" ]; then
-    cp "${iso9660_dir}/boot/grub/loongson.elf" "${rom_directory}/mipsel-loongson.elf"
-fi
-make_image "${loongson_dir}" mipsel-yeeloong-flash "${iso9660_dir}/boot/grub/roms/mipsel-yeeloong.bin" "pata -C xz"
-if [ -e "${iso9660_dir}/boot/grub/roms/mipsel-yeeloong.bin" ] && [ -d "${rom_directory}" ]; then
-    cp "${iso9660_dir}/boot/grub/roms/mipsel-yeeloong.bin" "${rom_directory}/mipsel-yeeloong.bin"
-fi
-
-make_image "${loongson_dir}" mipsel-fuloong2f-flash "${iso9660_dir}/boot/grub/roms/mipsel-fuloong2f.bin" "pata -C xz"
-if [ -e "${iso9660_dir}/boot/grub/roms/mipsel-fulong.bin" ] && [ -d "${rom_directory}" ]; then
-    cp "${iso9660_dir}/boot/grub/roms/mipsel-fulong.bin" "${rom_directory}/mipsel-fulong.bin"
-fi
-
-make_image "${mips_qemu_dir}" mips-qemu_mips-elf "${iso9660_dir}/boot/grub/roms/mips-qemu_mips.elf" "pata"
-if [ -e "${iso9660_dir}/boot/grub/roms/mips-qemu_mips.elf" ] && [ -d "${rom_directory}" ]; then
-    cp "${iso9660_dir}/boot/grub/roms/mips-qemu_mips.elf" "${rom_directory}/mips-qemu_mips.elf"
-fi
-make_image "${qemu_dir}" i386-qemu "${iso9660_dir}/boot/grub/roms/qemu.img" "pata at_keyboard"
-if [ -e "${iso9660_dir}/boot/grub/roms/qemu.img" ] && [ -d "${rom_directory}" ]; then
-    cp "${iso9660_dir}/boot/grub/roms/qemu.img" "${rom_directory}/qemu.img"
-fi
-make_image "${coreboot_dir}" i386-coreboot "${iso9660_dir}/boot/grub/roms/coreboot.elf" "pata ahci at_keyboard"
-if [ -e "${iso9660_dir}/boot/grub/roms/coreboot.elf" ] && [ -d "${rom_directory}" ]; then
-    cp "${iso9660_dir}/boot/grub/roms/coreboot.elf" "${rom_directory}/coreboot.elf"
-fi
-
-# build iso image
-"${xorriso}" -as mkisofs -graft-points ${grub_mkisofs_arguments} --protective-msdos-label -o "${output_image}" -r "${iso9660_dir}" --sort-weight 0 / --sort-weight 1 /boot ${source}
-rm -rf "${iso9660_dir}"
-
-rm -f "${sysarea_img}"
-
-exit 0
diff --git a/util/grub-mkstandalone.c b/util/grub-mkstandalone.c
new file mode 100644 (file)
index 0000000..774af2f
--- /dev/null
@@ -0,0 +1,372 @@
+
+/*
+  * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013  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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <config.h>
+
+#include <grub/util/install.h>
+#include <grub/util/misc.h>
+#include <grub/emu/config.h>
+
+#include <argp.h>
+#include <string.h>
+
+static grub_compression_t compression;
+static char *output_image;
+static char **files;
+static int nfiles;
+const struct grub_install_image_target_desc *format;
+static FILE *memdisk;
+
+enum
+  {
+    OPTION_OUTPUT = 'o',
+    OPTION_FORMAT = 'C',
+    OPTION_COMPRESION = 'C'
+  };
+
+static struct argp_option options[] = {
+  GRUB_INSTALL_OPTIONS,
+  {"output", 'o', N_("FILE"),
+   0, N_("save output in FILE [required]"), 2},
+  {"format", 'O', N_("FILE"), 0, 0, 2},
+  {"compression", 'C', N_("xz|none|auto"),
+   0, N_("choose the compression to use for core image"), 2},
+  {0, 0, 0, 0, 0, 0}
+};
+
+static char *
+help_filter (int key, const char *text, void *input __attribute__ ((unused)))
+{
+  switch (key)
+    {
+    case 'O':
+      {
+       char *formats = grub_install_get_image_targets_string (), *ret;
+       ret = xasprintf ("%s\n%s %s", _("generate an image in FORMAT"),
+                        _("available formats:"), formats);
+       free (formats);
+       return ret;
+      }
+    default:
+      return grub_install_help_filter (key, text, input);
+    }
+}
+
+static error_t
+argp_parser (int key, char *arg, struct argp_state *state)
+{
+  if (grub_install_parse (key, arg))
+    return 0;
+
+  switch (key)
+    {
+
+    case 'o':
+      if (output_image)
+       free (output_image);
+
+      output_image = xstrdup (arg);
+      break;
+
+    case 'O':
+      {
+       format = grub_install_get_image_target (arg);
+       if (!format)
+         {
+           printf (_("unknown target format %s\n"), arg);
+           argp_usage (state);
+           exit (1);
+         }
+       break;
+      }
+
+    case 'C':
+      if (grub_strcmp (arg, "xz") == 0)
+       {
+#ifdef HAVE_LIBLZMA
+         compression = GRUB_COMPRESSION_XZ;
+#else
+         grub_util_error ("%s",
+                          _("grub-mkimage is compiled without XZ support"));
+#endif
+       }
+      else if (grub_strcmp (arg, "none") == 0)
+       compression = GRUB_COMPRESSION_NONE;
+      else if (grub_strcmp (arg, "auto") == 0)
+       compression = GRUB_COMPRESSION_AUTO;
+      else
+       grub_util_error (_("Unknown compression format %s"), arg);
+      break;
+    case ARGP_KEY_ARG:
+      files[nfiles++] = xstrdup (arg);
+      break;
+
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
+
+struct argp argp = {
+  options, argp_parser, N_("[OPTION] SOURCE..."),
+  N_("Generate a standalone image (containing all modules) in the selected format")"\v"N_("Graft point syntax (E.g. /boot/grub/grub.cfg=./grub.cfg) is accepted"), 
+  NULL, help_filter, NULL
+};
+
+/* tar support */
+#define MAGIC  "ustar"
+struct head
+{
+  char name[100];
+  char mode[8];
+  char uid[8];
+  char gid[8];
+  char size[12];
+  char mtime[12];
+  char chksum[8];
+  char typeflag;
+  char linkname[100];
+  char magic[6];
+  char version[2];
+  char uname[32];
+  char gname[32];
+  char devmajor[8];
+  char devminor[8];
+  char prefix[155];
+  char pad[12];
+} __attribute__ ((packed));
+
+static void
+write_zeros (unsigned rsz)
+{
+  char buf[512];
+
+  memset (buf, 0, 512);
+  fwrite (buf, 1, rsz, memdisk);
+}
+
+static void
+write_pad (unsigned sz)
+{
+  write_zeros ((~sz + 1) & 511);
+}
+
+static void
+set_tar_value (char *field, grub_uint32_t val,
+              unsigned len)
+{
+  unsigned i;
+  for (i = 0; i < len - 1; i++)
+    field[len - 2 - i] = '0' + ((val >> (3 * i)) & 7);
+}
+
+static void
+compute_checksum (struct head *hd)
+{
+  unsigned int chk = 0;
+  unsigned char *ptr;
+  memset (hd->chksum, ' ', 8);
+  for (ptr = (unsigned char *) hd; ptr < (unsigned char *) (hd + 1); ptr++)
+    chk += *ptr;
+  set_tar_value (hd->chksum, chk, 8);
+}
+
+static void
+add_tar_file (const char *from,
+             const char *to)
+{
+  char *tcn;
+  const char *iptr;
+  char *optr;
+  struct head hd;
+  grub_util_fd_t in;
+  ssize_t r;
+  grub_uint32_t mtime = 0;
+  grub_uint32_t size;
+
+  COMPILE_TIME_ASSERT (sizeof (hd) == 512);
+
+  if (grub_util_is_special_file (from))
+    return;
+
+  mtime = grub_util_get_mtime (from);
+
+  optr = tcn = xmalloc (strlen (to) + 1);
+  for (iptr = to; *iptr == '/'; iptr++);
+  for (; *iptr; iptr++)
+    if (!(iptr[0] == '/' && iptr[1] == '/'))
+      *optr++ = *iptr;
+  *optr = '\0';
+
+  if (grub_util_is_directory (from))
+    {
+      grub_util_fd_dir_t d;
+      grub_util_fd_dirent_t de;
+
+      d = grub_util_fd_opendir (from);
+
+      while ((de = grub_util_fd_readdir (d)))
+       {
+         char *fp, *tfp;
+         if (strcmp (de->d_name, ".") == 0)
+           continue;
+         if (strcmp (de->d_name, "..") == 0)
+           continue;
+         fp = grub_util_path_concat (2, from, de->d_name);
+         tfp = xasprintf ("%s/%s", to, de->d_name);
+         add_tar_file (fp, tfp);
+         free (fp);
+       }
+      grub_util_fd_closedir (d);
+      free (tcn);
+      return;
+    }
+
+  if (optr - tcn > 99)
+    {
+      memset (&hd, 0, sizeof (hd));
+      memcpy (hd.name, tcn, 99);
+      memcpy (hd.mode, "0000600", 7);
+      memcpy (hd.uid, "0001750", 7);
+      memcpy (hd.gid, "0001750", 7);
+
+      set_tar_value (hd.size, optr - tcn, 12);
+      set_tar_value (hd.mtime, mtime, 12);
+      hd.typeflag = 'L';
+      memcpy (hd.magic, "ustar  ", 7);
+      memcpy (hd.uname, "grub", 4);
+      memcpy (hd.gname, "grub", 4);
+
+      compute_checksum (&hd);
+
+      fwrite (&hd, 1, sizeof (hd), memdisk);
+      fwrite (tcn, 1, optr - tcn, memdisk);
+
+      write_pad (optr - tcn);
+    }
+
+  in = grub_util_fd_open (from, GRUB_UTIL_FD_O_RDONLY);
+  if (!GRUB_UTIL_FD_IS_VALID (in))
+    grub_util_error (_("cannot open `%s': %s"), from, grub_util_fd_strerror ());
+
+  if (!grub_install_copy_buffer)
+    grub_install_copy_buffer = xmalloc (GRUB_INSTALL_COPY_BUFFER_SIZE);
+
+  size = grub_util_get_fd_size (in, from, NULL);
+
+  memset (&hd, 0, sizeof (hd));
+  memcpy (hd.name, tcn, optr - tcn < 99 ? optr - tcn : 99);
+  memcpy (hd.mode, "0000600", 7);
+  memcpy (hd.uid, "0001750", 7);
+  memcpy (hd.gid, "0001750", 7);
+
+  set_tar_value (hd.size, size, 12);
+  set_tar_value (hd.mtime, mtime, 12);
+  hd.typeflag = '0';
+  memcpy (hd.magic, "ustar  ", 7);
+  memcpy (hd.uname, "grub", 4);
+  memcpy (hd.gname, "grub", 4);
+
+  compute_checksum (&hd);
+
+  fwrite (&hd, 1, sizeof (hd), memdisk);
+  while (1)
+    {
+      r = grub_util_fd_read (in, grub_install_copy_buffer, GRUB_INSTALL_COPY_BUFFER_SIZE);
+      if (r <= 0)
+       break;
+      fwrite (grub_install_copy_buffer, 1, r, memdisk);
+    }
+  grub_util_fd_close (in);
+
+  write_pad (size);
+}
+
+int
+main (int argc, char *argv[])
+{
+  const char *pkglibdir;
+  int i;
+
+  grub_util_host_init (&argc, &argv);
+
+  files = xmalloc ((argc + 1) * sizeof (files[0]));
+
+  argp_parse (&argp, argc, argv, 0, 0, 0);
+
+  pkglibdir = grub_util_get_pkglibdir ();
+
+  if (!output_image)
+    grub_util_error ("%s", _("output file must be specified"));
+
+  if (!format)
+    grub_util_error ("%s", _("Target format not specified (use the -O option)."));
+
+  if (!grub_install_source_directory)
+    grub_install_source_directory = grub_util_path_concat (2, pkglibdir, grub_util_get_target_dirname (format));
+
+  enum grub_install_plat plat = grub_install_get_target (grub_install_source_directory);
+
+  char *memdisk_dir = grub_util_make_temporary_dir ();
+  char *boot_grub = grub_util_path_concat (3, memdisk_dir, "boot", "grub");
+  grub_install_copy_files (grub_install_source_directory,
+                          boot_grub, plat);
+
+  char *memdisk_img = grub_util_make_temporary_file ();
+
+  memdisk = grub_util_fopen (memdisk_img, "wb");
+
+  add_tar_file (memdisk_dir, "");
+  for (i = 0; i < nfiles; i++)
+    {
+      char *eq = grub_strchr (files[i], '=');
+      char *from, *to;
+      if (!eq)
+       {
+         from = files[i];
+         to = files[i];
+       }
+      else
+       {
+         *eq = '\0';
+         to = files[i];
+         from = eq + 1;
+       }
+      while (*to == '/')
+       to++;
+      add_tar_file (from, to);
+    }
+  write_zeros (512);
+
+  fclose (memdisk);
+
+  grub_util_unlink_recursive (memdisk_dir);
+
+  grub_install_push_module ("memdisk");
+  grub_install_push_module ("tar");
+
+  grub_install_make_image_wrap (grub_install_source_directory,
+                               "(memdisk)/boot/grub", output_image,
+                               memdisk_img, NULL,
+                               grub_util_get_target_name (format), 0,
+                               compression);
+
+  grub_util_unlink (memdisk_img);
+  return 0;
+}
diff --git a/util/grub-mkstandalone.in b/util/grub-mkstandalone.in
deleted file mode 100644 (file)
index b692c48..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-#!/bin/sh
-
-# Make GRUB rescue image
-# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012  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 <http://www.gnu.org/licenses/>.
-
-# Initialize some variables.
-
-compression=auto
-format=
-source=
-
-# Usage: usage
-# Print the usage.
-usage () {
-    formats="i386-coreboot i386-multiboot i386-pc i386-pc-pxe i386-efi i386-ieee1275 i386-qemu x86_64-efi mipsel-yeeloong-flash mipsel-fuloong2f-flash mipsel-loongson-elf powerpc-ieee1275 sparc64-ieee1275-raw sparc64-ieee1275-aout ia64-efi mips-arc mipsel-qemu_mips-elf mips-qemu_mips-flash  mipsel-qemu_mips-flash  mips-qemu_mips-elf"
-    gettext_printf "Usage: %s [OPTION] SOURCE...\n" "$self"
-    gettext "Generate a standalone image (containing all modules) in the selected format"
-    echo
-    print_option_help "-h, --help" "$(gettext "print this message and exit")"
-    print_option_help "-o, --output=$(gettext FILE)" "$(gettext "save output in FILE [required]")"
-    print_option_help "-O, --format=$(gettext "FORMAT")" "$(gettext "generate an image in FORMAT")"; echo
-    print_option_help "" "$(gettext "available formats:") $formats"
-    echo
-    print_option_help "-C, --compression=(xz|none|auto)" "$(gettext "choose the compression to use for core image")"
-    grub_print_install_files_help
-    echo
-    gettext "Report bugs to <bug-grub@gnu.org>."; echo
-}
-
-# Check the arguments.
-while test $# -gt 0
-do
-    grub_process_install_options "$@"
-    case "$grub_process_install_options_consumed" in
-       1) shift; continue;;
-       2) shift; shift; continue;;
-    esac
-
-    option=$1
-    shift
-
-    case "$option" in
-    -h | --help)
-       usage
-       exit 0 ;;
-
-    -o | --output)
-       output_image=`argument $option "$@"`; shift ;;
-    --output=*)
-       output_image=`echo "$option" | sed 's/--output=//'` ;;
-
-    --compression | -C)
-       compression=`argument $option "$@"`; shift ;;
-    --compression=*)
-       compression=`echo "${option}" | sed 's/--compression=//'` ;;
-
-    --format | -O)
-       format=`argument $option "$@"`; shift ;;
-    --format=*)
-       format=`echo "${option}" | sed 's/--format=//'` ;;
-
-    *)
-       source="${source} ${option} $@"; break ;;
-    esac
-done
-
-if [ "x${output_image}" = x ] ; then
-  gettext "output file must be specified" >&2
-  echo >&2
-  usage
-  exit 1
-fi
-
-if [ "x${format}" = x ] ; then
-  gettext "Target format not specified (use the -O option)." >&2
-  echo >&2
-  exit 1
-fi
-
-if [ "x$source_directory" = x ] ; then
-    cpu="`echo $format | awk -F - '{ print $1; }'`"
-    platform="`echo $format | awk -F - '{ print $2; }'`"
-    case "$platform" in
-       yeeloong | fuloong | fuloong2f | fuloong2e)
-           platform=loongson ;;
-    esac
-    case "$cpu-$platform" in
-       mips-loongson)
-           cpu=mipsel ;;
-    esac
-    source_directory="${libdir}/@PACKAGE@/$cpu-$platform"
-fi
-
-. "${source_directory}"/modinfo.sh
-
-set $grub_mkimage dummy
-if test -f "$1"; then
-    :
-else
-    echo "$1: Not found." 1>&2
-    exit 1
-fi
-
-memdisk_dir="`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1
-grub_install_files "${source_directory}" "${memdisk_dir}"/boot/grub "${grub_modinfo_target_cpu}-${grub_modinfo_platform}"
-for file in $source; do
-    cp -f "$file" "${memdisk_dir}"/"$file";
-done
-
-memdisk_img=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1
-
-(cd "${memdisk_dir}"; tar -cf - * $source) > "${memdisk_img}"
-rm -rf "${memdisk_dir}"
-"$grub_mkimage" -O "${format}" -C "$compression" -d "${source_directory}" -m "${memdisk_img}" -o "$output_image" --prefix='(memdisk)/boot/grub' memdisk tar $grub_decompression_module $modules
-rm -rf "${memdisk_img}"
-
-exit 0
index d29d562aa63ffcad646c74dd4d4d3051341c1240..db68d61f60325a3562c9c1d5df4c8345b266e2cb 100644 (file)
@@ -155,135 +155,6 @@ probe_raid_level (grub_disk_t disk)
   return ((struct grub_diskfilter_lv *) disk->data)->segments->type;
 }
 
-/* Since OF path names can have "," characters in them, and GRUB
-   internally uses "," to indicate partitions (unlike OF which uses
-   ":" for this purpose) we escape such commas.  */
-static char *
-escape_of_path (const char *orig_path)
-{
-  char *new_path, *d, c;
-  const char *p;
-
-  if (!strchr (orig_path, ','))
-    return (char *) xstrdup (orig_path);
-
-  new_path = xmalloc (strlen (orig_path) * 2 + 1);
-
-  p = orig_path;
-  d = new_path;
-  while ((c = *p++) != '\0')
-    {
-      if (c == ',')
-       *d++ = '\\';
-      *d++ = c;
-    }
-  *d = 0;
-
-  return new_path;
-}
-
-static char *
-guess_bios_drive (const char *orig_path)
-{
-  char *canon;
-  char *ptr;
-  canon = canonicalize_file_name (orig_path);
-  if (!canon)
-    return NULL;
-  ptr = strrchr (orig_path, '/');
-  if (ptr)
-    ptr++;
-  else
-    ptr = canon;
-  if ((ptr[0] == 's' || ptr[0] == 'h') && ptr[1] == 'd')
-    {
-      int num = ptr[2] - 'a';
-      free (canon);
-      return xasprintf ("hd%d", num);
-    }
-  if (ptr[0] == 'f' && ptr[1] == 'd')
-    {
-      int num = atoi (ptr + 2);
-      free (canon);
-      return xasprintf ("fd%d", num);
-    }
-  free (canon);
-  return NULL;
-}
-
-static char *
-guess_efi_drive (const char *orig_path)
-{
-  char *canon;
-  char *ptr;
-  canon = canonicalize_file_name (orig_path);
-  if (!canon)
-    return NULL;
-  ptr = strrchr (orig_path, '/');
-  if (ptr)
-    ptr++;
-  else
-    ptr = canon;
-  if ((ptr[0] == 's' || ptr[0] == 'h') && ptr[1] == 'd')
-    {
-      int num = ptr[2] - 'a';
-      free (canon);
-      return xasprintf ("hd%d", num);
-    }
-  if (ptr[0] == 'f' && ptr[1] == 'd')
-    {
-      int num = atoi (ptr + 2);
-      free (canon);
-      return xasprintf ("fd%d", num);
-    }
-  free (canon);
-  return NULL;
-}
-
-static char *
-guess_baremetal_drive (const char *orig_path)
-{
-  char *canon;
-  char *ptr;
-  canon = canonicalize_file_name (orig_path);
-  if (!canon)
-    return NULL;
-  ptr = strrchr (orig_path, '/');
-  if (ptr)
-    ptr++;
-  else
-    ptr = canon;
-  if (ptr[0] == 'h' && ptr[1] == 'd')
-    {
-      int num = ptr[2] - 'a';
-      free (canon);
-      return xasprintf ("ata%d", num);
-    }
-  if (ptr[0] == 's' && ptr[1] == 'd')
-    {
-      int num = ptr[2] - 'a';
-      free (canon);
-      return xasprintf ("ahci%d", num);
-    }
-  free (canon);
-  return NULL;
-}
-
-static void
-print_full_name (const char *drive, grub_device_t dev)
-{
-  char *dname = escape_of_path (drive);
-  if (dev->disk->partition)
-    {
-      char *pname = grub_partition_get_name (dev->disk->partition);
-      printf ("%s,%s", dname, pname);
-      free (pname);
-    }
-  else
-    printf ("%s", dname);
-  free (dname);
-} 
-
 static void
 probe_abstraction (grub_disk_t disk)
 {
@@ -513,34 +384,34 @@ probe (const char *path, char **device_names, char delim)
              p = grub_stpcpy (tmp, "ieee1275/");
              strcpy (p, ofpath);
              printf ("--hint-ieee1275='");
-             print_full_name (tmp, dev);
+             grub_util_fprint_full_disk_name (stdout, tmp, dev);
              printf ("' ");
              free (tmp);
            }
 
-         biosname = guess_bios_drive (*curdev);
+         biosname = grub_util_guess_bios_drive (*curdev);
          if (biosname)
            {
              printf ("--hint-bios=");
-             print_full_name (biosname, dev);
+             grub_util_fprint_full_disk_name (stdout, biosname, dev);
              printf (" ");
            }
          free (biosname);
 
-         efi = guess_efi_drive (*curdev);
+         efi = grub_util_guess_efi_drive (*curdev);
          if (efi)
            {
              printf ("--hint-efi=");
-             print_full_name (efi, dev);
+             grub_util_fprint_full_disk_name (stdout, efi, dev);
              printf (" ");
            }
          free (efi);
 
-         bare = guess_baremetal_drive (*curdev);
+         bare = grub_util_guess_baremetal_drive (*curdev);
          if (bare)
            {
              printf ("--hint-baremetal=");
-             print_full_name (bare, dev);
+             grub_util_fprint_full_disk_name (stdout, bare, dev);
              printf (" ");
            }
          free (bare);
@@ -551,7 +422,7 @@ probe (const char *path, char **device_names, char delim)
          if (map)
            {
              printf ("--hint='");
-             print_full_name (map, dev);
+             grub_util_fprint_full_disk_name (stdout, map, dev);
              printf ("' ");
            }
          if (curdrive[1])
@@ -568,7 +439,7 @@ probe (const char *path, char **device_names, char delim)
           || print == PRINT_EFI_HINT || print == PRINT_ARC_HINT)
          && dev->disk->dev->id != GRUB_DISK_DEVICE_HOSTDISK_ID)
        {
-         print_full_name (dev->disk->name, dev);
+         grub_util_fprint_full_disk_name (stdout, dev->disk->name, dev);
          putchar (delim);
          continue;
        }
@@ -580,16 +451,16 @@ probe (const char *path, char **device_names, char delim)
          map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
          if (map)
            {
-             print_full_name (map, dev);
+             grub_util_fprint_full_disk_name (stdout, map, dev);
              putchar (delim);
              grub_device_close (dev);
              /* Compatibility hint is one device only.  */
              break;
            }
-         biosname = guess_bios_drive (*curdev);
+         biosname = grub_util_guess_bios_drive (*curdev);
          if (biosname)
            {
-             print_full_name (biosname, dev);
+             grub_util_fprint_full_disk_name (stdout, biosname, dev);
              putchar (delim);
            }
          free (biosname);
@@ -603,10 +474,10 @@ probe (const char *path, char **device_names, char delim)
       if (print == PRINT_BIOS_HINT)
        {
          char *biosname;
-         biosname = guess_bios_drive (*curdev);
+         biosname = grub_util_guess_bios_drive (*curdev);
          if (biosname)
            {
-             print_full_name (biosname, dev);
+             grub_util_fprint_full_disk_name (stdout, biosname, dev);
              putchar (delim);
            }
          free (biosname);
@@ -622,7 +493,7 @@ probe (const char *path, char **device_names, char delim)
          map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
          if (map)
            {
-             print_full_name (map, dev);
+             grub_util_fprint_full_disk_name (stdout, map, dev);
              putchar (delim);
            }
 
@@ -632,7 +503,7 @@ probe (const char *path, char **device_names, char delim)
              char *p;
              p = grub_stpcpy (tmp, "ieee1275/");
              strcpy (p, ofpath);
-             print_full_name (tmp, dev);
+             grub_util_fprint_full_disk_name (stdout, tmp, dev);
              free (tmp);
              putchar (delim);
            }
@@ -644,17 +515,17 @@ probe (const char *path, char **device_names, char delim)
        {
          char *biosname;
          const char *map;
-         biosname = guess_efi_drive (*curdev);
+         biosname = grub_util_guess_efi_drive (*curdev);
 
          map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
          if (map)
            {
-             print_full_name (map, dev);
+             grub_util_fprint_full_disk_name (stdout, map, dev);
              putchar (delim);
            }
          if (biosname)
            {
-             print_full_name (biosname, dev);
+             grub_util_fprint_full_disk_name (stdout, biosname, dev);
              putchar (delim);
            }
 
@@ -668,17 +539,17 @@ probe (const char *path, char **device_names, char delim)
          char *biosname;
          const char *map;
 
-         biosname = guess_baremetal_drive (*curdev);
+         biosname = grub_util_guess_baremetal_drive (*curdev);
 
          map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
          if (map)
            {
-             print_full_name (map, dev);
+             grub_util_fprint_full_disk_name (stdout, map, dev);
              putchar (delim);
            }
          if (biosname)
            {
-             print_full_name (biosname, dev);
+             grub_util_fprint_full_disk_name (stdout, biosname, dev);
              putchar (delim);
            }
 
@@ -694,7 +565,7 @@ probe (const char *path, char **device_names, char delim)
          map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
          if (map)
            {
-             print_full_name (map, dev);
+             grub_util_fprint_full_disk_name (stdout, map, dev);
              putchar (delim);
            }
 
index 8b6a678fafaff9994c7465a9dba45fda6f4021de..0de340bbe36dd341778a24dfc861356f806817c0 100644 (file)
@@ -40,7 +40,7 @@
 #include <grub/time.h>
 #include <grub/i18n.h>
 #include <grub/script_sh.h>
-#include <grub/osdep/hostfile.h>
+#include <grub/emu/hostfile.h>
 
 #define ENABLE_RELOCATABLE 0
 #ifdef GRUB_BUILD
@@ -256,15 +256,3 @@ void
 grub_register_exported_symbols (void)
 {
 }
-
-#ifdef GRUB_UTIL
-void
-grub_util_init_nls (void)
-{
-#if (defined(ENABLE_NLS) && ENABLE_NLS)
-  setlocale (LC_ALL, "");
-  bindtextdomain (PACKAGE, LOCALEDIR);
-  textdomain (PACKAGE);
-#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */
-}
-#endif
index a5a683b98583c986e140827f86c2f0ccd796af19..4a510228c4d13d9f6ff0465d32f7f5ed09d0d357 100644 (file)
@@ -66,7 +66,7 @@ struct grub_install_image_target_desc
     IMAGE_I386_IEEE1275,
     IMAGE_LOONGSON_ELF, IMAGE_QEMU, IMAGE_PPC, IMAGE_YEELOONG_FLASH,
     IMAGE_FULOONG2F_FLASH, IMAGE_I386_PC_PXE, IMAGE_MIPS_ARC,
-    IMAGE_QEMU_MIPS_FLASH, IMAGE_UBOOT, IMAGE_XEN
+    IMAGE_QEMU_MIPS_FLASH, IMAGE_UBOOT, IMAGE_XEN, IMAGE_I386_PC_ELTORITO
   } id;
   enum
     {
@@ -174,6 +174,22 @@ static const struct grub_install_image_target_desc image_targets[] =
       .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR,
       .default_compression = GRUB_COMPRESSION_LZMA
     },
+    {
+      .dirname = "i386-pc",
+      .names = { "i386-pc-eltorito", NULL },
+      .voidp_sizeof = 4,
+      .bigendian = 0,
+      .id = IMAGE_I386_PC_ELTORITO, 
+      .flags = PLATFORM_FLAGS_DECOMPRESSORS,
+      .total_module_size = TARGET_NO_FIELD,
+      .decompressor_compressed_size = GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE,
+      .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE,
+      .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+      .section_align = 1,
+      .vaddr_offset = 0,
+      .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR,
+      .default_compression = GRUB_COMPRESSION_LZMA
+    },
     {
       .dirname = "i386-efi",
       .names = { "i386-efi", NULL },
@@ -826,6 +842,12 @@ grub_util_get_target_dirname (const struct grub_install_image_target_desc *t)
   return t->dirname;
 }
 
+const char *
+grub_util_get_target_name (const struct grub_install_image_target_desc *t)
+{
+  return t->names[0];
+}
+
 char *
 grub_install_get_image_targets_string (void)
 {
@@ -874,7 +896,8 @@ grub_install_generate_image (const char *dir, const char *prefix,
     comp = image_target->default_compression;
 
   if (image_target->id == IMAGE_I386_PC
-      || image_target->id == IMAGE_I386_PC_PXE)
+      || image_target->id == IMAGE_I386_PC_PXE
+      || image_target->id == IMAGE_I386_PC_ELTORITO)
     comp = GRUB_COMPRESSION_LZMA;
 
   path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods);
@@ -1105,7 +1128,8 @@ grub_install_generate_image (const char *dir, const char *prefix,
       decompress_img = grub_util_read_image (decompress_path);
 
       if ((image_target->id == IMAGE_I386_PC
-          || image_target->id == IMAGE_I386_PC_PXE)
+          || image_target->id == IMAGE_I386_PC_PXE
+          || image_target->id == IMAGE_I386_PC_ELTORITO)
          && decompress_size > GRUB_KERNEL_I386_PC_LINK_ADDR - 0x8200)
        grub_util_error ("%s", _("Decompressor is too big"));
 
@@ -1149,6 +1173,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
     {
     case IMAGE_I386_PC:
     case IMAGE_I386_PC_PXE:
+    case IMAGE_I386_PC_ELTORITO:
        if (GRUB_KERNEL_I386_PC_LINK_ADDR + core_size > 0x78000
            || (core_size > (0xffff << GRUB_DISK_SECTOR_BITS))
            || (kernel_size + bss_size + GRUB_KERNEL_I386_PC_LINK_ADDR > 0x68000))
@@ -1185,6 +1210,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
     {
     case IMAGE_I386_PC:
     case IMAGE_I386_PC_PXE:
+    case IMAGE_I386_PC_ELTORITO:
       {
        unsigned num;
        char *boot_path, *boot_img;
@@ -1219,6 +1245,21 @@ grub_install_generate_image (const char *dir, const char *prefix,
                }
          }
 
+       if (image_target->id == IMAGE_I386_PC_ELTORITO)
+         {
+           char *eltorito_path, *eltorito_img;
+           size_t eltorito_size;
+           
+           eltorito_path = grub_util_get_path (dir, "cdboot.img");
+           eltorito_size = grub_util_get_image_size (eltorito_path);
+           eltorito_img = grub_util_read_image (eltorito_path);
+           
+           grub_util_write_image (eltorito_img, eltorito_size, out,
+                                  outname);
+           free (eltorito_img);
+           free (eltorito_path);
+         }
+
        boot_path = grub_util_get_path (dir, "diskboot.img");
        boot_size = grub_util_get_image_size (boot_path);
        if (boot_size != GRUB_DISK_SECTOR_SIZE)
@@ -1764,6 +1805,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
   grub_util_write_image (core_img, core_size, out, outname);
   free (core_img);
   free (kernel_path);
+  free (rel_section);
 
   while (path_list)
     {
diff --git a/util/probe.c b/util/probe.c
new file mode 100644 (file)
index 0000000..c389f5d
--- /dev/null
@@ -0,0 +1,172 @@
+/* grub-probe.c - probe device information for a given path */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009,2010,2013  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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/types.h>
+#include <grub/emu/misc.h>
+#include <grub/util/misc.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/file.h>
+#include <grub/fs.h>
+#include <grub/partition.h>
+#include <grub/msdos_partition.h>
+#include <grub/gpt_partition.h>
+#include <grub/emu/hostdisk.h>
+#include <grub/emu/getroot.h>
+#include <grub/term.h>
+#include <grub/env.h>
+#include <grub/diskfilter.h>
+#include <grub/i18n.h>
+#include <grub/emu/misc.h>
+#include <grub/util/ofpath.h>
+#include <grub/crypto.h>
+#include <grub/cryptodisk.h>
+
+#include <string.h>
+
+/* Since OF path names can have "," characters in them, and GRUB
+   internally uses "," to indicate partitions (unlike OF which uses
+   ":" for this purpose) we escape such commas.  */
+static char *
+escape_of_path (const char *orig_path)
+{
+  char *new_path, *d, c;
+  const char *p;
+
+  if (!strchr (orig_path, ','))
+    return (char *) xstrdup (orig_path);
+
+  new_path = xmalloc (strlen (orig_path) * 2 + 1);
+
+  p = orig_path;
+  d = new_path;
+  while ((c = *p++) != '\0')
+    {
+      if (c == ',')
+       *d++ = '\\';
+      *d++ = c;
+    }
+  *d = 0;
+
+  return new_path;
+}
+
+char *
+grub_util_guess_bios_drive (const char *orig_path)
+{
+  char *canon;
+  char *ptr;
+  canon = canonicalize_file_name (orig_path);
+  if (!canon)
+    return NULL;
+  ptr = strrchr (orig_path, '/');
+  if (ptr)
+    ptr++;
+  else
+    ptr = canon;
+  if ((ptr[0] == 's' || ptr[0] == 'h') && ptr[1] == 'd')
+    {
+      int num = ptr[2] - 'a';
+      free (canon);
+      return xasprintf ("hd%d", num);
+    }
+  if (ptr[0] == 'f' && ptr[1] == 'd')
+    {
+      int num = atoi (ptr + 2);
+      free (canon);
+      return xasprintf ("fd%d", num);
+    }
+  free (canon);
+  return NULL;
+}
+
+char *
+grub_util_guess_efi_drive (const char *orig_path)
+{
+  char *canon;
+  char *ptr;
+  canon = canonicalize_file_name (orig_path);
+  if (!canon)
+    return NULL;
+  ptr = strrchr (orig_path, '/');
+  if (ptr)
+    ptr++;
+  else
+    ptr = canon;
+  if ((ptr[0] == 's' || ptr[0] == 'h') && ptr[1] == 'd')
+    {
+      int num = ptr[2] - 'a';
+      free (canon);
+      return xasprintf ("hd%d", num);
+    }
+  if (ptr[0] == 'f' && ptr[1] == 'd')
+    {
+      int num = atoi (ptr + 2);
+      free (canon);
+      return xasprintf ("fd%d", num);
+    }
+  free (canon);
+  return NULL;
+}
+
+char *
+grub_util_guess_baremetal_drive (const char *orig_path)
+{
+  char *canon;
+  char *ptr;
+  canon = canonicalize_file_name (orig_path);
+  if (!canon)
+    return NULL;
+  ptr = strrchr (orig_path, '/');
+  if (ptr)
+    ptr++;
+  else
+    ptr = canon;
+  if (ptr[0] == 'h' && ptr[1] == 'd')
+    {
+      int num = ptr[2] - 'a';
+      free (canon);
+      return xasprintf ("ata%d", num);
+    }
+  if (ptr[0] == 's' && ptr[1] == 'd')
+    {
+      int num = ptr[2] - 'a';
+      free (canon);
+      return xasprintf ("ahci%d", num);
+    }
+  free (canon);
+  return NULL;
+}
+
+void
+grub_util_fprint_full_disk_name (FILE *f,
+                                const char *drive, grub_device_t dev)
+{
+  char *dname = escape_of_path (drive);
+  if (dev->disk->partition)
+    {
+      char *pname = grub_partition_get_name (dev->disk->partition);
+      fprintf (f, "%s,%s", dname, pname);
+      free (pname);
+    }
+  else
+    fprintf (f, "%s", dname);
+  free (dname);
+}