grub-install: Fix memory leak
[grub.git] / util / grub-install.c
1 /*
2  *  GRUB  --  GRand Unified Bootloader
3  *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
4  *
5  *  GRUB is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  GRUB is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #include <config.h>
20 #include <grub/types.h>
21 #include <grub/emu/misc.h>
22 #include <grub/util/misc.h>
23 #include <grub/misc.h>
24 #include <grub/device.h>
25 #include <grub/disk.h>
26 #include <grub/file.h>
27 #include <grub/fs.h>
28 #include <grub/env.h>
29 #include <grub/term.h>
30 #include <grub/mm.h>
31 #include <grub/lib/hexdump.h>
32 #include <grub/crypto.h>
33 #include <grub/command.h>
34 #include <grub/i18n.h>
35 #include <grub/zfs/zfs.h>
36 #include <grub/util/install.h>
37 #include <grub/emu/getroot.h>
38 #include <grub/diskfilter.h>
39 #include <grub/cryptodisk.h>
40 #include <grub/legacy_parse.h>
41 #include <grub/gpt_partition.h>
42 #include <grub/emu/config.h>
43 #include <grub/util/ofpath.h>
44 #include <grub/hfsplus.h>
45
46 #include <string.h>
47
48 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
49 #pragma GCC diagnostic ignored "-Wmissing-declarations"
50 #include <argp.h>
51 #pragma GCC diagnostic error "-Wmissing-prototypes"
52 #pragma GCC diagnostic error "-Wmissing-declarations"
53
54 #include "progname.h"
55
56 static char *target;
57 static int removable = 0;
58 static int recheck = 0;
59 static int update_nvram = 1;
60 static char *install_device = NULL;
61 static char *debug_image = NULL;
62 static char *rootdir = NULL;
63 static char *bootdir = NULL;
64 static int allow_floppy = 0;
65 static int force_file_id = 0;
66 static char *disk_module = NULL;
67 static char *efidir = NULL;
68 static char *macppcdir = NULL;
69 static int force = 0;
70 static int have_abstractions = 0;
71 static int have_cryptodisk = 0;
72 static char * bootloader_id;
73 static int have_load_cfg = 0;
74 static FILE * load_cfg_f = NULL;
75 static char *load_cfg;
76 static int install_bootsector = 1;
77 static char *label_font;
78 static char *label_color;
79 static char *label_bgcolor;
80 static char *product_version;
81 static int add_rs_codes = 1;
82
83 enum
84   {
85     OPTION_BOOT_DIRECTORY = 0x301,
86     OPTION_ROOT_DIRECTORY,
87     OPTION_TARGET,
88     OPTION_SETUP,
89     OPTION_MKRELPATH, 
90     OPTION_MKDEVICEMAP, 
91     OPTION_PROBE, 
92     OPTION_EDITENV, 
93     OPTION_ALLOW_FLOPPY, 
94     OPTION_RECHECK, 
95     OPTION_FORCE,
96     OPTION_FORCE_FILE_ID,
97     OPTION_NO_NVRAM, 
98     OPTION_REMOVABLE, 
99     OPTION_BOOTLOADER_ID, 
100     OPTION_EFI_DIRECTORY,
101     OPTION_FONT,
102     OPTION_DEBUG,
103     OPTION_DEBUG_IMAGE,
104     OPTION_NO_FLOPPY,
105     OPTION_DISK_MODULE,
106     OPTION_NO_BOOTSECTOR,
107     OPTION_NO_RS_CODES,
108     OPTION_MACPPC_DIRECTORY,
109     OPTION_LABEL_FONT,
110     OPTION_LABEL_COLOR,
111     OPTION_LABEL_BGCOLOR,
112     OPTION_PRODUCT_VERSION
113   };
114
115 static int fs_probe = 1;
116
117 static error_t 
118 argp_parser (int key, char *arg, struct argp_state *state)
119 {
120   if (grub_install_parse (key, arg))
121     return 0;
122   switch (key)
123     {
124     case OPTION_FORCE_FILE_ID:
125       force_file_id = 1;
126       return 0;
127     case 's':
128       fs_probe = 0;
129       return 0;
130
131     case OPTION_SETUP:
132       if (!grub_strstr (arg, "setup"))
133         install_bootsector = 0;
134       return 0;
135
136     case OPTION_PRODUCT_VERSION:
137       free (product_version);
138       product_version = xstrdup (arg);
139       return 0;
140     case OPTION_LABEL_FONT:
141       free (label_font);
142       label_font = xstrdup (arg);
143       return 0;
144
145     case OPTION_LABEL_COLOR:
146       free (label_color);
147       label_color = xstrdup (arg);
148       return 0;
149
150     case OPTION_LABEL_BGCOLOR:
151       free (label_bgcolor);
152       label_bgcolor = xstrdup (arg);
153       return 0;
154
155       /* Accept and ignore for compatibility.  */
156     case OPTION_FONT:
157     case OPTION_MKRELPATH:
158     case OPTION_PROBE:
159     case OPTION_EDITENV:
160     case OPTION_MKDEVICEMAP:
161     case OPTION_NO_FLOPPY:
162       return 0;
163     case OPTION_ROOT_DIRECTORY:
164       /* Accept for compatibility.  */
165       free (rootdir);
166       rootdir = xstrdup (arg);
167       return 0;
168
169     case OPTION_BOOT_DIRECTORY:
170       free (bootdir);
171       bootdir = xstrdup (arg);
172       return 0;
173
174     case OPTION_MACPPC_DIRECTORY:
175       free (macppcdir);
176       macppcdir = xstrdup (arg);
177       return 0;
178
179     case OPTION_EFI_DIRECTORY:
180       free (efidir);
181       efidir = xstrdup (arg);
182       return 0;
183
184     case OPTION_DISK_MODULE:
185       free (disk_module);
186       disk_module = xstrdup (arg);
187       return 0;
188
189     case OPTION_TARGET:
190       free (target);
191       target = xstrdup (arg);
192       return 0;
193
194     case OPTION_DEBUG_IMAGE:
195       free (debug_image);
196       debug_image = xstrdup (arg);
197       return 0;
198
199     case OPTION_NO_NVRAM:
200       update_nvram = 0;
201       return 0;
202
203     case OPTION_FORCE:
204       force = 1;
205       return 0;
206
207     case OPTION_RECHECK:
208       recheck = 1;
209       return 0;
210
211     case OPTION_REMOVABLE:
212       removable = 1;
213       return 0;
214
215     case OPTION_ALLOW_FLOPPY:
216       allow_floppy = 1;
217       return 0;
218
219     case OPTION_NO_BOOTSECTOR:
220       install_bootsector = 0;
221       return 0;
222
223     case OPTION_NO_RS_CODES:
224       add_rs_codes = 0;
225       return 0;
226
227     case OPTION_DEBUG:
228       verbosity++;
229       return 0;
230
231     case OPTION_BOOTLOADER_ID:
232       free (bootloader_id);
233       bootloader_id = xstrdup (arg);
234       return 0;
235
236     case ARGP_KEY_ARG:
237       if (install_device)
238         grub_util_error ("%s", _("More than one install device?"));
239       install_device = xstrdup (arg);
240       return 0;
241
242     default:
243       return ARGP_ERR_UNKNOWN;
244     }
245 }
246
247
248 static struct argp_option options[] = {
249   GRUB_INSTALL_OPTIONS,
250   {"boot-directory", OPTION_BOOT_DIRECTORY, N_("DIR"),
251    0, N_("install GRUB images under the directory DIR/%s instead of the %s directory"), 2},
252   {"root-directory", OPTION_ROOT_DIRECTORY, N_("DIR"),
253    OPTION_HIDDEN, 0, 2},
254   {"font", OPTION_FONT, N_("FILE"),
255    OPTION_HIDDEN, 0, 2},
256   {"target", OPTION_TARGET, N_("TARGET"),
257    /* TRANSLATORS: "TARGET" as in "target platform".  */
258    0, N_("install GRUB for TARGET platform [default=%s]; available targets: %s"), 2},
259   {"grub-setup", OPTION_SETUP, "FILE", OPTION_HIDDEN, 0, 2},
260   {"grub-mkrelpath", OPTION_MKRELPATH, "FILE", OPTION_HIDDEN, 0, 2},
261   {"grub-mkdevicemap", OPTION_MKDEVICEMAP, "FILE", OPTION_HIDDEN, 0, 2},
262   {"grub-probe", OPTION_PROBE, "FILE", OPTION_HIDDEN, 0, 2},
263   {"grub-editenv", OPTION_EDITENV, "FILE", OPTION_HIDDEN, 0, 2},
264   {"allow-floppy", OPTION_ALLOW_FLOPPY, 0, 0,
265    /* TRANSLATORS: "may break" doesn't just mean that option wouldn't have any
266       effect but that it will make the resulting install unbootable from HDD. */
267    N_("make the drive also bootable as floppy (default for fdX devices)."
268       " May break on some BIOSes."), 2},
269   {"recheck", OPTION_RECHECK, 0, 0,
270    N_("delete device map if it already exists"), 2},
271   {"force", OPTION_FORCE, 0, 0,
272    N_("install even if problems are detected"), 2},
273   {"force-file-id", OPTION_FORCE_FILE_ID, 0, 0,
274    N_("use identifier file even if UUID is available"), 2},
275   {"disk-module", OPTION_DISK_MODULE, N_("MODULE"), 0,
276    N_("disk module to use (biosdisk or native). "
277       "This option is only available on BIOS target."), 2},
278   {"no-nvram", OPTION_NO_NVRAM, 0, 0,
279    N_("don't update the `boot-device'/`Boot*' NVRAM variables. "
280       "This option is only available on EFI and IEEE1275 targets."), 2},
281   {"skip-fs-probe",'s',0,      0,
282    N_("do not probe for filesystems in DEVICE"), 0},
283   {"no-bootsector", OPTION_NO_BOOTSECTOR, 0, 0,
284    N_("do not install bootsector"), 0},
285   {"no-rs-codes", OPTION_NO_RS_CODES, 0, 0,
286    N_("Do not apply any reed-solomon codes when embedding core.img. "
287       "This option is only available on x86 BIOS targets."), 0},
288
289   {"debug", OPTION_DEBUG, 0, OPTION_HIDDEN, 0, 2},
290   {"no-floppy", OPTION_NO_FLOPPY, 0, OPTION_HIDDEN, 0, 2},
291   {"debug-image", OPTION_DEBUG_IMAGE, N_("STRING"), OPTION_HIDDEN, 0, 2},
292   {"removable", OPTION_REMOVABLE, 0, 0,
293    N_("the installation device is removable. "
294       "This option is only available on EFI."), 2},
295   {"bootloader-id", OPTION_BOOTLOADER_ID, N_("ID"), 0,
296    N_("the ID of bootloader. This option is only available on EFI and Macs."), 2},
297   {"efi-directory", OPTION_EFI_DIRECTORY, N_("DIR"), 0,
298    N_("use DIR as the EFI System Partition root."), 2},
299   {"macppc-directory", OPTION_MACPPC_DIRECTORY, N_("DIR"), 0,
300    N_("use DIR for PPC MAC install."), 2},
301   {"label-font", OPTION_LABEL_FONT, N_("FILE"), 0, N_("use FILE as font for label"), 2},
302   {"label-color", OPTION_LABEL_COLOR, N_("COLOR"), 0, N_("use COLOR for label"), 2},
303   {"label-bgcolor", OPTION_LABEL_BGCOLOR, N_("COLOR"), 0, N_("use COLOR for label background"), 2},
304   {"product-version", OPTION_PRODUCT_VERSION, N_("STRING"), 0, N_("use STRING as product version"), 2},
305   {0, 0, 0, 0, 0, 0}
306 };
307
308 static const char *
309 get_default_platform (void)
310 {
311 #ifdef __powerpc__
312    return "powerpc-ieee1275";
313 #elif defined (__sparc__) || defined (__sparc64__)
314    return "sparc64-ieee1275";
315 #elif defined (__MIPSEL__)
316    return "mipsel-loongson";
317 #elif defined (__MIPSEB__)
318    return "mips-arc";
319 #elif defined (__ia64__)
320    return "ia64-efi";
321 #elif defined (__arm__)
322    return "arm-uboot";
323 #elif defined (__aarch64__)
324    return "arm64-efi";
325 #elif defined (__amd64__) || defined (__x86_64__) || defined (__i386__)
326    return grub_install_get_default_x86_platform ();
327 #else
328    return NULL;
329 #endif
330 }
331
332 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
333
334 static char *
335 help_filter (int key, const char *text, void *input __attribute__ ((unused)))
336 {
337   switch (key)
338     {
339     case OPTION_BOOT_DIRECTORY:
340       return xasprintf (text, GRUB_DIR_NAME, GRUB_BOOT_DIR_NAME "/" GRUB_DIR_NAME);
341     case OPTION_TARGET:
342       {
343         char *plats = grub_install_get_platforms_string ();
344         char *ret;
345         ret = xasprintf (text, get_default_platform (), plats);
346         free (plats);
347         return ret;
348       }
349     case ARGP_KEY_HELP_POST_DOC:
350       return xasprintf (text, program_name, GRUB_BOOT_DIR_NAME "/" GRUB_DIR_NAME);
351     default:
352       return grub_install_help_filter (key, text, input);
353     }
354 }
355
356 #pragma GCC diagnostic error "-Wformat-nonliteral"
357
358 /* TRANSLATORS: INSTALL_DEVICE isn't an identifier and is the DEVICE you
359    install to.  */
360 struct argp argp = {
361   options, argp_parser, N_("[OPTION] [INSTALL_DEVICE]"),
362   N_("Install GRUB on your drive.")"\v"
363   N_("INSTALL_DEVICE must be system device filename.\n"
364      "%s copies GRUB images into %s.  On some platforms, it"
365      " may also install GRUB into the boot sector."), 
366   NULL, help_filter, NULL
367 };
368
369 static int
370 probe_raid_level (grub_disk_t disk)
371 {
372   /* disk might be NULL in the case of a LVM physical volume with no LVM
373      signature.  Ignore such cases here.  */
374   if (!disk)
375     return -1;
376
377   if (disk->dev->id != GRUB_DISK_DEVICE_DISKFILTER_ID)
378     return -1;
379
380   if (disk->name[0] != 'm' || disk->name[1] != 'd')
381     return -1;
382
383   if (!((struct grub_diskfilter_lv *) disk->data)->segments)
384     return -1;
385   return ((struct grub_diskfilter_lv *) disk->data)->segments->type;
386 }
387
388 static void
389 push_partmap_module (const char *map, void *data __attribute__ ((unused)))
390 {
391   char buf[50];
392
393   if (strcmp (map, "openbsd") == 0 || strcmp (map, "netbsd") == 0)
394     {
395       grub_install_push_module ("part_bsd");
396       return;
397     }
398
399   snprintf (buf, sizeof (buf), "part_%s", map);
400   grub_install_push_module (buf);
401 }
402
403 static void
404 push_cryptodisk_module (const char *mod, void *data __attribute__ ((unused)))
405 {
406   grub_install_push_module (mod);
407 }
408
409 static void
410 probe_mods (grub_disk_t disk)
411 {
412   grub_partition_t part;
413   grub_disk_memberlist_t list = NULL, tmp;
414   int raid_level;
415
416   if (disk->partition == NULL)
417     grub_util_info ("no partition map found for %s", disk->name);
418
419   for (part = disk->partition; part; part = part->parent)
420     push_partmap_module (part->partmap->name, NULL);
421
422   if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID)
423     {
424       grub_diskfilter_get_partmap (disk, push_partmap_module, NULL);
425       have_abstractions = 1;
426     }
427
428   if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID
429       && (grub_memcmp (disk->name, "lvm/", sizeof ("lvm/") - 1) == 0 ||
430           grub_memcmp (disk->name, "lvmid/", sizeof ("lvmid/") - 1) == 0))
431     grub_install_push_module ("lvm");
432
433   if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID
434       && grub_memcmp (disk->name, "ldm/", sizeof ("ldm/") - 1) == 0)
435     grub_install_push_module ("ldm");
436
437   if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID)
438     {
439       grub_util_cryptodisk_get_abstraction (disk,
440                                             push_cryptodisk_module, NULL);
441       have_abstractions = 1;
442       have_cryptodisk = 1;
443     }
444
445   raid_level = probe_raid_level (disk);
446   if (raid_level >= 0)
447     {
448       grub_install_push_module ("diskfilter");
449       if (disk->dev->raidname)
450         grub_install_push_module (disk->dev->raidname (disk));
451     }
452   if (raid_level == 5)
453     grub_install_push_module ("raid5rec");
454   if (raid_level == 6)
455     grub_install_push_module ("raid6rec");
456
457   /* In case of LVM/RAID, check the member devices as well.  */
458   if (disk->dev->memberlist)
459     list = disk->dev->memberlist (disk);
460   while (list)
461     {
462       probe_mods (list->disk);
463       tmp = list->next;
464       free (list);
465       list = tmp;
466     }
467 }
468
469 static int
470 have_bootdev (enum grub_install_plat pl)
471 {
472   switch (pl)
473     {
474     case GRUB_INSTALL_PLATFORM_I386_PC:
475     case GRUB_INSTALL_PLATFORM_I386_EFI:
476     case GRUB_INSTALL_PLATFORM_X86_64_EFI:
477     case GRUB_INSTALL_PLATFORM_IA64_EFI:
478     case GRUB_INSTALL_PLATFORM_ARM_EFI:
479     case GRUB_INSTALL_PLATFORM_ARM64_EFI:
480     case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
481     case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
482     case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
483     case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
484     case GRUB_INSTALL_PLATFORM_MIPS_ARC:
485       return 1;
486
487     case GRUB_INSTALL_PLATFORM_I386_QEMU:
488     case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
489     case GRUB_INSTALL_PLATFORM_ARM_COREBOOT:
490     case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
491     case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
492     case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
493
494     case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
495     case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
496
497     case GRUB_INSTALL_PLATFORM_I386_XEN:
498     case GRUB_INSTALL_PLATFORM_X86_64_XEN:
499       return 0;
500
501       /* pacify warning.  */
502     case GRUB_INSTALL_PLATFORM_MAX:
503       return 0;
504     }
505   return 0;
506 }
507
508 static void
509 probe_cryptodisk_uuid (grub_disk_t disk)
510 {
511   grub_disk_memberlist_t list = NULL, tmp;
512
513   /* In case of LVM/RAID, check the member devices as well.  */
514   if (disk->dev->memberlist)
515     {
516       list = disk->dev->memberlist (disk);
517     }
518   while (list)
519     {
520       probe_cryptodisk_uuid (list->disk);
521       tmp = list->next;
522       free (list);
523       list = tmp;
524     }
525   if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID)
526     {
527       const char *uuid = grub_util_cryptodisk_get_uuid (disk);
528       if (!load_cfg_f)
529         load_cfg_f = grub_util_fopen (load_cfg, "wb");
530       have_load_cfg = 1;
531
532       fprintf (load_cfg_f, "cryptomount -u %s\n",
533               uuid);
534     }
535 }
536
537 static int
538 is_same_disk (const char *a, const char *b)
539 {
540   while (1)
541     {
542       if ((*a == ',' || *a == '\0') && (*b == ',' || *b == '\0'))
543         return 1;
544       if (*a != *b)
545         return 0;
546       if (*a == '\\')
547         {
548           if (a[1] != b[1])
549             return 0;
550           a += 2;
551           b += 2;
552           continue;
553         }
554       a++;
555       b++;
556     }
557 }
558
559 static char *
560 get_rndstr (void)
561 {
562   grub_uint8_t rnd[15];
563   const size_t sz = sizeof (rnd) * GRUB_CHAR_BIT / 5;
564   char * ret = xmalloc (sz + 1);
565   size_t i;
566   if (grub_get_random (rnd, sizeof (rnd)))
567     grub_util_error ("%s", _("couldn't retrieve random data"));
568   for (i = 0; i < sz; i++)
569     {
570       grub_size_t b = i * 5;
571       grub_uint8_t r;
572       grub_size_t f1 = GRUB_CHAR_BIT - b % GRUB_CHAR_BIT;
573       grub_size_t f2;
574       if (f1 > 5)
575         f1 = 5;
576       f2 = 5 - f1;
577       r = (rnd[b / GRUB_CHAR_BIT] >> (b % GRUB_CHAR_BIT)) & ((1 << f1) - 1);
578       if (f2)
579         r |= (rnd[b / GRUB_CHAR_BIT + 1] & ((1 << f2) - 1)) << f1;
580       if (r < 10)
581         ret[i] = '0' + r;
582       else
583         ret[i] = 'a' + (r - 10);
584     }
585   ret[sz] = '\0';
586   return ret;
587 }
588
589 static char *
590 escape (const char *in)
591 {
592   char *ptr;
593   char *ret;
594   int overhead = 0;
595
596   for (ptr = (char*)in; *ptr; ptr++)
597     if (*ptr == '\'')
598       overhead += 3;
599   ret = grub_malloc (ptr - in + overhead + 1);
600   if (!ret)
601     return NULL;
602
603   grub_strchrsub (ret, in, '\'', "'\\''");
604   return ret;
605 }
606
607 static struct grub_util_config config;
608
609 static void
610 device_map_check_duplicates (const char *dev_map)
611 {
612   FILE *fp;
613   char buf[1024];       /* XXX */
614   size_t alloced = 8;
615   size_t filled = 0;
616   char **d;
617   size_t i;
618
619   if (dev_map[0] == '\0')
620     return;
621
622   fp = grub_util_fopen (dev_map, "r");
623   if (! fp)
624     return;
625
626   d = xmalloc (alloced * sizeof (d[0]));
627
628   while (fgets (buf, sizeof (buf), fp))
629     {
630       char *p = buf;
631       char *e;
632
633       /* Skip leading spaces.  */
634       while (*p && grub_isspace (*p))
635         p++;
636
637       /* If the first character is `#' or NUL, skip this line.  */
638       if (*p == '\0' || *p == '#')
639         continue;
640
641       if (*p != '(')
642         continue;
643
644       p++;
645
646       e = p;
647       p = strchr (p, ')');
648       if (! p)
649         continue;
650
651       if (filled >= alloced)
652         {
653           alloced *= 2;
654           d = xrealloc (d, alloced * sizeof (d[0]));
655         }
656
657       *p = '\0';
658
659       d[filled++] = xstrdup (e);
660     }
661
662   fclose (fp);
663
664   qsort (d, filled, sizeof (d[0]), grub_qsort_strcmp);
665
666   for (i = 0; i + 1 < filled; i++)
667     if (strcmp (d[i], d[i+1]) == 0)
668       {
669         grub_util_error (_("the drive %s is defined multiple times in the device map %s"),
670                          d[i], dev_map);
671       }
672
673   for (i = 0; i < filled; i++)
674     free (d[i]);
675
676   free (d);
677 }
678
679 static grub_err_t
680 write_to_disk (grub_device_t dev, const char *fn)
681 {
682   char *core_img;
683   size_t core_size;
684   grub_err_t err;
685
686   core_size = grub_util_get_image_size (fn);
687
688   core_img = grub_util_read_image (fn);    
689
690   grub_util_info ("writing `%s' to `%s'", fn, dev->disk->name);
691   err = grub_disk_write (dev->disk, 0, 0,
692                          core_size, core_img);
693   free (core_img);
694   return err;
695 }
696
697 static int
698 is_prep_partition (grub_device_t dev)
699 {
700   if (!dev->disk)
701     return 0;
702   if (!dev->disk->partition)
703     return 0;
704   if (strcmp(dev->disk->partition->partmap->name, "msdos") == 0)
705     return (dev->disk->partition->msdostype == 0x41);
706
707   if (strcmp (dev->disk->partition->partmap->name, "gpt") == 0)
708     {
709       struct grub_gpt_partentry gptdata;
710       grub_partition_t p = dev->disk->partition;
711       int ret = 0;
712       dev->disk->partition = dev->disk->partition->parent;
713
714       if (grub_disk_read (dev->disk, p->offset, p->index,
715                           sizeof (gptdata), &gptdata) == 0)
716         {
717           const grub_gpt_part_type_t template = {
718             grub_cpu_to_le32_compile_time (0x9e1a2d38),
719             grub_cpu_to_le16_compile_time (0xc612),
720             grub_cpu_to_le16_compile_time (0x4316),
721             { 0xaa, 0x26, 0x8b, 0x49, 0x52, 0x1e, 0x5a, 0x8b }
722           };
723
724           ret = grub_memcmp (&template, &gptdata.type,
725                              sizeof (template)) == 0;
726         }
727       dev->disk->partition = p;
728       return ret;
729     }
730
731   return 0;
732 }
733
734 static int
735 is_prep_empty (grub_device_t dev)
736 {
737   grub_disk_addr_t dsize, addr;
738   grub_uint32_t buffer[32768];
739
740   dsize = grub_disk_get_size (dev->disk);
741   for (addr = 0; addr < dsize;
742        addr += sizeof (buffer) / GRUB_DISK_SECTOR_SIZE)
743     {
744       grub_size_t sz = sizeof (buffer);
745       grub_uint32_t *ptr;
746
747       if (sizeof (buffer) / GRUB_DISK_SECTOR_SIZE > dsize - addr)
748         sz = (dsize - addr) * GRUB_DISK_SECTOR_SIZE;
749       grub_disk_read (dev->disk, addr, 0, sz, buffer);
750
751       if (addr == 0 && grub_memcmp (buffer, ELFMAG, SELFMAG) == 0)
752         return 1;
753
754       for (ptr = buffer; ptr < buffer + sz / sizeof (*buffer); ptr++)
755         if (*ptr)
756           return 0;
757     }
758
759   return 1;
760 }
761
762 static void
763 bless (grub_device_t dev, const char *path, int x86)
764 {
765   struct stat st;
766   grub_err_t err;
767
768   grub_util_info ("blessing %s", path);
769
770   if (stat (path, &st) < 0)
771     grub_util_error (N_("cannot stat `%s': %s"),
772                      path, strerror (errno));
773
774   err = grub_mac_bless_inode (dev, st.st_ino, S_ISDIR (st.st_mode), x86);
775   if (err)
776     grub_util_error ("%s", grub_errmsg);
777   grub_util_info ("blessed");
778 }
779
780 static void
781 fill_core_services (const char *core_services)
782 {
783   char *label;
784   FILE *f;
785   char *label_text;
786   char *label_string = xasprintf ("%s %s", bootloader_id, product_version);
787   char *sysv_plist;
788
789   label = grub_util_path_concat (2, core_services, ".disk_label");
790   grub_util_info ("rendering label %s", label_string);
791   grub_util_render_label (label_font, label_bgcolor ? : "white",
792                           label_color ? : "black", label_string, label);
793   grub_util_info ("label rendered");
794   free (label);
795   label_text = grub_util_path_concat (2, core_services, ".disk_label.contentDetails");
796   f = grub_util_fopen (label_text, "wb");
797   fprintf (f, "%s\n", label_string);
798   fclose (f);
799   free (label_string);
800   free (label_text);
801
802   sysv_plist = grub_util_path_concat (2, core_services, "SystemVersion.plist");
803   f = grub_util_fopen (sysv_plist, "wb");
804   fprintf (f,
805            "<plist version=\"1.0\">\n"
806            "<dict>\n"
807            "        <key>ProductBuildVersion</key>\n"
808            "        <string></string>\n"
809            "        <key>ProductName</key>\n"
810            "        <string>%s</string>\n"
811            "        <key>ProductVersion</key>\n"
812            "        <string>%s</string>\n"
813            "</dict>\n"
814            "</plist>\n", bootloader_id, product_version);
815   fclose (f);
816   free (sysv_plist);
817 }
818
819 int
820 main (int argc, char *argv[])
821 {
822   int is_efi = 0;
823   const char *efi_distributor = NULL;
824   const char *efi_file = NULL;
825   char **grub_devices;
826   grub_fs_t grub_fs;
827   grub_device_t grub_dev = NULL;
828   enum grub_install_plat platform;
829   char *grubdir, *device_map;
830   char **curdev, **curdrive;
831   char **grub_drives;
832   char *relative_grubdir;
833   char **efidir_device_names = NULL;
834   grub_device_t efidir_grub_dev = NULL;
835   char *efidir_grub_devname;
836   int efidir_is_mac = 0;
837   int is_prep = 0;
838   const char *pkgdatadir;
839
840   grub_util_host_init (&argc, &argv);
841   product_version = xstrdup (PACKAGE_VERSION);
842   pkgdatadir = grub_util_get_pkgdatadir ();
843   label_font = grub_util_path_concat (2, pkgdatadir, "unicode.pf2");
844
845   argp_parse (&argp, argc, argv, 0, 0, 0);
846
847   if (verbosity > 1)
848     grub_env_set ("debug", "all");
849
850   grub_util_load_config (&config);
851
852   if (!bootloader_id && config.grub_distributor)
853     {
854       char *ptr;
855       bootloader_id = xstrdup (config.grub_distributor);
856       for (ptr = bootloader_id; *ptr && *ptr != ' '; ptr++)
857         if (*ptr >= 'A' && *ptr <= 'Z')
858           *ptr = *ptr - 'A' + 'a';
859       *ptr = '\0';
860     }
861   if (!bootloader_id || bootloader_id[0] == '\0')
862     {
863       free (bootloader_id);
864       bootloader_id = xstrdup ("grub");
865     }
866
867   if (!grub_install_source_directory)
868     {
869       if (!target)
870         {
871           const char * t;
872           t = get_default_platform ();
873           if (!t)
874             grub_util_error ("%s", 
875                              _("Unable to determine your platform."
876                                " Use --target.")
877                              );
878           target = xstrdup (t); 
879         }
880       grub_install_source_directory
881         = grub_util_path_concat (2, grub_util_get_pkglibdir (), target);
882     }
883
884   platform = grub_install_get_target (grub_install_source_directory);
885
886   {
887     char *platname = grub_install_get_platform_name (platform);
888     fprintf (stderr, _("Installing for %s platform.\n"), platname);
889     free (platname);
890   }
891
892   switch (platform)
893     {
894     case GRUB_INSTALL_PLATFORM_I386_PC:
895       if (!disk_module)
896         disk_module = xstrdup ("biosdisk");
897       break;
898     case GRUB_INSTALL_PLATFORM_I386_EFI:
899     case GRUB_INSTALL_PLATFORM_X86_64_EFI:
900     case GRUB_INSTALL_PLATFORM_ARM_EFI:
901     case GRUB_INSTALL_PLATFORM_ARM64_EFI:
902     case GRUB_INSTALL_PLATFORM_IA64_EFI:
903     case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
904     case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
905     case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
906     case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
907     case GRUB_INSTALL_PLATFORM_MIPS_ARC:
908     case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
909     case GRUB_INSTALL_PLATFORM_I386_XEN:
910     case GRUB_INSTALL_PLATFORM_X86_64_XEN:
911       break;
912
913     case GRUB_INSTALL_PLATFORM_I386_QEMU:
914     case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
915     case GRUB_INSTALL_PLATFORM_ARM_COREBOOT:
916     case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
917     case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
918     case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
919     case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
920       disk_module = xstrdup ("native");
921       break;
922
923       /* pacify warning.  */
924     case GRUB_INSTALL_PLATFORM_MAX:
925       break;
926     }
927
928   switch (platform)
929     {
930     case GRUB_INSTALL_PLATFORM_I386_PC:
931     case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
932       if (!install_device)
933         grub_util_error ("%s", _("install device isn't specified"));
934       break;
935     case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
936       if (install_device)
937         is_prep = 1;
938       break;
939     case GRUB_INSTALL_PLATFORM_MIPS_ARC:
940     case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
941       break;
942     case GRUB_INSTALL_PLATFORM_I386_EFI:
943     case GRUB_INSTALL_PLATFORM_X86_64_EFI:
944     case GRUB_INSTALL_PLATFORM_ARM_EFI:
945     case GRUB_INSTALL_PLATFORM_ARM64_EFI:
946     case GRUB_INSTALL_PLATFORM_IA64_EFI:
947     case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
948     case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
949     case GRUB_INSTALL_PLATFORM_I386_QEMU:
950     case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
951     case GRUB_INSTALL_PLATFORM_ARM_COREBOOT:
952     case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
953     case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
954     case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
955     case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
956     case GRUB_INSTALL_PLATFORM_I386_XEN:
957     case GRUB_INSTALL_PLATFORM_X86_64_XEN:
958       free (install_device);
959       install_device = NULL;
960       break;
961
962       /* pacify warning.  */
963     case GRUB_INSTALL_PLATFORM_MAX:
964       break;
965     }
966
967   if (!bootdir)
968     bootdir = grub_util_path_concat (3, "/", rootdir, GRUB_BOOT_DIR_NAME);
969
970   {
971     char * t = grub_util_path_concat (2, bootdir, GRUB_DIR_NAME);
972     grub_install_mkdir_p (t);
973     grubdir = grub_canonicalize_file_name (t);
974     if (!grubdir)
975       grub_util_error (_("failed to get canonical path of `%s'"), t);
976     free (t);
977   }
978   device_map = grub_util_path_concat (2, grubdir, "device.map");
979
980   if (recheck)
981     grub_util_unlink (device_map);
982
983   device_map_check_duplicates (device_map);
984   grub_util_biosdisk_init (device_map);
985
986   /* Initialize all modules. */
987   grub_init_all ();
988   grub_gcry_init_all ();
989   grub_hostfs_init ();
990   grub_host_init ();
991
992   switch (platform)
993     {
994     case GRUB_INSTALL_PLATFORM_I386_EFI:
995     case GRUB_INSTALL_PLATFORM_X86_64_EFI:
996     case GRUB_INSTALL_PLATFORM_ARM_EFI:
997     case GRUB_INSTALL_PLATFORM_ARM64_EFI:
998     case GRUB_INSTALL_PLATFORM_IA64_EFI:
999       is_efi = 1;
1000       break;
1001     default:
1002       is_efi = 0;
1003       break;
1004
1005       /* pacify warning.  */
1006     case GRUB_INSTALL_PLATFORM_MAX:
1007       break;
1008     }
1009
1010   /* Find the EFI System Partition.  */
1011
1012   if (is_efi)
1013     {
1014       grub_fs_t fs;
1015       free (install_device);
1016       install_device = NULL;
1017       if (!efidir)
1018         {
1019           char *d = grub_util_path_concat (2, bootdir, "efi");
1020           char *dr = NULL;
1021           if (!grub_util_is_directory (d))
1022             {
1023               free (d);
1024               d = grub_util_path_concat (2, bootdir, "EFI");
1025             }
1026           /*
1027             The EFI System Partition may have been given directly using
1028             --root-directory.
1029           */
1030           if (!grub_util_is_directory (d)
1031               && rootdir && grub_strcmp (rootdir, "/") != 0)
1032             {
1033               free (d);
1034               d = xstrdup (rootdir);
1035             }
1036           if (grub_util_is_directory (d))
1037             dr = grub_make_system_path_relative_to_its_root (d);
1038           /* Is it a mount point? */
1039           if (dr && dr[0] == '\0')
1040             efidir = d;
1041           else
1042             free (d);
1043           free (dr);
1044         }
1045       if (!efidir)
1046         grub_util_error ("%s", _("cannot find EFI directory"));
1047       efidir_device_names = grub_guess_root_devices (efidir);
1048       if (!efidir_device_names || !efidir_device_names[0])
1049         grub_util_error (_("cannot find a device for %s (is /dev mounted?)"),
1050                              efidir);
1051       install_device = efidir_device_names[0];
1052
1053       for (curdev = efidir_device_names; *curdev; curdev++)
1054           grub_util_pull_device (*curdev);
1055       
1056       efidir_grub_devname = grub_util_get_grub_dev (efidir_device_names[0]);
1057       if (!efidir_grub_devname)
1058         grub_util_error (_("cannot find a GRUB drive for %s.  Check your device.map"),
1059                          efidir_device_names[0]);
1060
1061       efidir_grub_dev = grub_device_open (efidir_grub_devname);
1062       if (! efidir_grub_dev)
1063         grub_util_error ("%s", grub_errmsg);
1064
1065       fs = grub_fs_probe (efidir_grub_dev);
1066       if (! fs)
1067         grub_util_error ("%s", grub_errmsg);
1068
1069       efidir_is_mac = 0;
1070
1071       if (grub_strcmp (fs->name, "hfs") == 0
1072           || grub_strcmp (fs->name, "hfsplus") == 0)
1073         efidir_is_mac = 1;
1074
1075       if (!efidir_is_mac && grub_strcmp (fs->name, "fat") != 0)
1076         grub_util_error (_("%s doesn't look like an EFI partition"), efidir);
1077
1078       /* The EFI specification requires that an EFI System Partition must
1079          contain an "EFI" subdirectory, and that OS loaders are stored in
1080          subdirectories below EFI.  Vendors are expected to pick names that do
1081          not collide with other vendors.  To minimise collisions, we use the
1082          name of our distributor if possible.
1083       */
1084       char *t;
1085       efi_distributor = bootloader_id;
1086       if (removable)
1087         {
1088           /* The specification makes stricter requirements of removable
1089              devices, in order that only one image can be automatically loaded
1090              from them.  The image must always reside under /EFI/BOOT, and it
1091              must have a specific file name depending on the architecture.
1092           */
1093           efi_distributor = "BOOT";
1094           switch (platform)
1095             {
1096             case GRUB_INSTALL_PLATFORM_I386_EFI:
1097               efi_file = "BOOTIA32.EFI";
1098               break;
1099             case GRUB_INSTALL_PLATFORM_X86_64_EFI:
1100               efi_file = "BOOTX64.EFI";
1101               break;
1102             case GRUB_INSTALL_PLATFORM_IA64_EFI:
1103               efi_file = "BOOTIA64.EFI";
1104               break;
1105             case GRUB_INSTALL_PLATFORM_ARM_EFI:
1106               efi_file = "BOOTARM.EFI";
1107               break;
1108             case GRUB_INSTALL_PLATFORM_ARM64_EFI:
1109               efi_file = "BOOTAA64.EFI";
1110               break;
1111             default:
1112               grub_util_error ("%s", _("You've found a bug"));
1113               break;
1114             }
1115         }
1116       else
1117         {
1118           /* It is convenient for each architecture to have a different
1119              efi_file, so that different versions can be installed in parallel.
1120           */
1121           switch (platform)
1122             {
1123             case GRUB_INSTALL_PLATFORM_I386_EFI:
1124               efi_file = "grubia32.efi";
1125               break;
1126             case GRUB_INSTALL_PLATFORM_X86_64_EFI:
1127               efi_file = "grubx64.efi";
1128               break;
1129             case GRUB_INSTALL_PLATFORM_IA64_EFI:
1130               efi_file = "grubia64.efi";
1131               break;
1132             case GRUB_INSTALL_PLATFORM_ARM_EFI:
1133               efi_file = "grubarm.efi";
1134               break;
1135             case GRUB_INSTALL_PLATFORM_ARM64_EFI:
1136               efi_file = "grubaa64.efi";
1137               break;
1138             default:
1139               efi_file = "grub.efi";
1140               break;
1141             }
1142         }
1143       t = grub_util_path_concat (3, efidir, "EFI", efi_distributor);
1144       free (efidir);
1145       efidir = t;
1146       grub_install_mkdir_p (efidir);
1147     }
1148
1149   if (platform == GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275)
1150     {
1151       int is_guess = 0;
1152       if (!macppcdir)
1153         {
1154           char *d;
1155
1156           is_guess = 1;
1157           d = grub_util_path_concat (2, bootdir, "macppc");
1158           if (!grub_util_is_directory (d))
1159             {
1160               free (d);
1161               d = grub_util_path_concat (2, bootdir, "efi");
1162             }
1163           /* Find the Mac HFS(+) System Partition.  */
1164           if (!grub_util_is_directory (d))
1165             {
1166               free (d);
1167               d = grub_util_path_concat (2, bootdir, "EFI");
1168             }
1169           if (!grub_util_is_directory (d))
1170             {
1171               free (d);
1172               d = 0;
1173             }
1174           if (d)
1175             macppcdir = d;
1176         }
1177       if (macppcdir)
1178         {
1179           char **macppcdir_device_names = NULL;
1180           grub_device_t macppcdir_grub_dev = NULL;
1181           char *macppcdir_grub_devname;
1182           grub_fs_t fs;
1183
1184           macppcdir_device_names = grub_guess_root_devices (macppcdir);
1185           if (!macppcdir_device_names || !macppcdir_device_names[0])
1186             grub_util_error (_("cannot find a device for %s (is /dev mounted?)"),
1187                              macppcdir);
1188
1189           for (curdev = macppcdir_device_names; *curdev; curdev++)
1190             grub_util_pull_device (*curdev);
1191       
1192           macppcdir_grub_devname = grub_util_get_grub_dev (macppcdir_device_names[0]);
1193           if (!macppcdir_grub_devname)
1194             grub_util_error (_("cannot find a GRUB drive for %s.  Check your device.map"),
1195                              macppcdir_device_names[0]);
1196           
1197           macppcdir_grub_dev = grub_device_open (macppcdir_grub_devname);
1198           if (! macppcdir_grub_dev)
1199             grub_util_error ("%s", grub_errmsg);
1200
1201           fs = grub_fs_probe (macppcdir_grub_dev);
1202           if (! fs)
1203             grub_util_error ("%s", grub_errmsg);
1204
1205           if (grub_strcmp (fs->name, "hfs") != 0
1206               && grub_strcmp (fs->name, "hfsplus") != 0
1207               && !is_guess)
1208             grub_util_error (_("filesystem on %s is neither HFS nor HFS+"),
1209                              macppcdir);
1210           if (grub_strcmp (fs->name, "hfs") == 0
1211               || grub_strcmp (fs->name, "hfsplus") == 0)
1212             {
1213               install_device = macppcdir_device_names[0];
1214               is_prep = 0;
1215             }
1216         }
1217     }
1218
1219   grub_install_copy_files (grub_install_source_directory,
1220                            grubdir, platform);
1221
1222   char *envfile = grub_util_path_concat (2, grubdir, "grubenv");
1223   if (!grub_util_is_regular (envfile))
1224     grub_util_create_envblk_file (envfile);
1225
1226   size_t ndev = 0;
1227
1228   /* Write device to a variable so we don't have to traverse /dev every time.  */
1229   grub_devices = grub_guess_root_devices (grubdir);
1230   if (!grub_devices || !grub_devices[0])
1231     grub_util_error (_("cannot find a device for %s (is /dev mounted?)"),
1232                      grubdir);
1233
1234   for (curdev = grub_devices; *curdev; curdev++)
1235     {
1236       grub_util_pull_device (*curdev);
1237       ndev++;
1238     }
1239
1240   grub_drives = xmalloc (sizeof (grub_drives[0]) * (ndev + 1)); 
1241
1242   for (curdev = grub_devices, curdrive = grub_drives; *curdev; curdev++,
1243        curdrive++)
1244     {
1245       *curdrive = grub_util_get_grub_dev (*curdev);
1246       if (! *curdrive)
1247         grub_util_error (_("cannot find a GRUB drive for %s.  Check your device.map"),
1248                          *curdev);
1249     }
1250   *curdrive = 0;
1251
1252   grub_dev = grub_device_open (grub_drives[0]);
1253   if (! grub_dev)
1254     grub_util_error ("%s", grub_errmsg);
1255
1256   grub_fs = grub_fs_probe (grub_dev);
1257   if (! grub_fs)
1258     grub_util_error ("%s", grub_errmsg);
1259
1260   grub_install_push_module (grub_fs->name);
1261
1262   if (grub_dev->disk)
1263     probe_mods (grub_dev->disk);
1264
1265   for (curdrive = grub_drives + 1; *curdrive; curdrive++)
1266     {
1267       grub_device_t dev = grub_device_open (*curdrive);
1268       if (!dev)
1269         continue;
1270       if (dev->disk)
1271         probe_mods (dev->disk);
1272       grub_device_close (dev);
1273     }
1274
1275   if (!config.is_cryptodisk_enabled && have_cryptodisk)
1276     grub_util_error (_("attempt to install to encrypted disk without cryptodisk enabled. "
1277                        "Set `%s' in file `%s'"), "GRUB_ENABLE_CRYPTODISK=y",
1278                      grub_util_get_config_filename ());
1279
1280   if (disk_module && grub_strcmp (disk_module, "ata") == 0)
1281     grub_install_push_module ("pata");
1282   else if (disk_module && grub_strcmp (disk_module, "native") == 0)
1283     {
1284       grub_install_push_module ("pata");
1285       grub_install_push_module ("ahci");
1286       grub_install_push_module ("ohci");
1287       grub_install_push_module ("uhci");
1288       grub_install_push_module ("ehci");
1289       grub_install_push_module ("usbms");
1290     }
1291   else if (disk_module && disk_module[0])
1292     grub_install_push_module (disk_module);
1293
1294   relative_grubdir = grub_make_system_path_relative_to_its_root (grubdir);
1295   if (relative_grubdir[0] == '\0')
1296     {
1297       free (relative_grubdir);
1298       relative_grubdir = xstrdup ("/");
1299     }
1300
1301   char *platname =  grub_install_get_platform_name (platform);
1302   char *platdir;
1303   {
1304     char *t = grub_util_path_concat (2, grubdir,
1305                                    platname);
1306     platdir = grub_canonicalize_file_name (t);
1307     if (!platdir)
1308       grub_util_error (_("failed to get canonical path of `%s'"),
1309                        t);
1310     free (t);
1311   }
1312   load_cfg = grub_util_path_concat (2, platdir,
1313                                   "load.cfg");
1314
1315   grub_util_unlink (load_cfg);
1316
1317   if (debug_image && debug_image[0])
1318     {
1319       load_cfg_f = grub_util_fopen (load_cfg, "wb");
1320       have_load_cfg = 1;
1321       fprintf (load_cfg_f, "set debug='%s'\n",
1322               debug_image);
1323     }
1324   char *prefix_drive = NULL;
1325   char *install_drive = NULL;
1326
1327   if (install_device)
1328     {
1329       if (install_device[0] == '('
1330           && install_device[grub_strlen (install_device) - 1] == ')')
1331         {
1332           size_t len = grub_strlen (install_device) - 2;
1333           install_drive = xmalloc (len + 1);
1334           memcpy (install_drive, install_device + 1, len);
1335           install_drive[len] = '\0';
1336         }
1337       else
1338         {
1339           grub_util_pull_device (install_device);
1340           install_drive = grub_util_get_grub_dev (install_device);
1341           if (!install_drive)
1342             grub_util_error (_("cannot find a GRUB drive for %s.  Check your device.map"),
1343                              install_device);
1344         }
1345     }
1346
1347   if (!have_abstractions)
1348     {
1349       if ((disk_module && grub_strcmp (disk_module, "biosdisk") != 0)
1350           || grub_drives[1]
1351           || (!install_drive
1352               && platform != GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275)
1353           || (install_drive && !is_same_disk (grub_drives[0], install_drive))
1354           || !have_bootdev (platform))
1355         {
1356           char *uuid = NULL;
1357           /*  generic method (used on coreboot and ata mod).  */
1358           if (!force_file_id && grub_fs->uuid && grub_fs->uuid (grub_dev,
1359                                                                 &uuid))
1360             {
1361               grub_print_error ();
1362               grub_errno = 0;
1363               uuid = NULL;
1364             }
1365
1366           if (!load_cfg_f)
1367             load_cfg_f = grub_util_fopen (load_cfg, "wb");
1368           have_load_cfg = 1;
1369           if (uuid)
1370             {
1371               fprintf (load_cfg_f, "search.fs_uuid %s root ",
1372                       uuid);
1373               grub_install_push_module ("search_fs_uuid");
1374             }
1375           else
1376             {
1377               char *rndstr = get_rndstr ();
1378               char *fl = grub_util_path_concat (3, grubdir,
1379                                                      "uuid", rndstr);
1380               char *fldir = grub_util_path_concat (2, grubdir,
1381                                                         "uuid");
1382               char *relfl;
1383               FILE *flf;
1384               grub_install_mkdir_p (fldir);
1385               flf = grub_util_fopen (fl, "w");
1386               if (!flf)
1387                 grub_util_error (_("Can't create file: %s"), strerror (errno));
1388               fclose (flf);
1389               relfl = grub_make_system_path_relative_to_its_root (fl);
1390               fprintf (load_cfg_f, "search.file %s root ",
1391                        relfl);
1392               grub_install_push_module ("search_fs_file");
1393             }
1394           for (curdev = grub_devices, curdrive = grub_drives; *curdev; curdev++,
1395                  curdrive++)
1396             {
1397               const char *map;
1398               char *g = NULL;
1399               grub_device_t dev;
1400               if (curdrive == grub_drives)
1401                 dev = grub_dev;
1402               else
1403                 dev = grub_device_open (*curdrive);
1404               if (!dev)
1405                 continue;
1406
1407               if (dev->disk->dev->id != GRUB_DISK_DEVICE_HOSTDISK_ID)
1408                 {
1409                   grub_util_fprint_full_disk_name (load_cfg_f,
1410                                                    dev->disk->name,
1411                                                    dev);
1412                   fprintf (load_cfg_f, " ");
1413                   if (dev != grub_dev)
1414                     grub_device_close (dev);
1415                   continue;
1416                 }
1417
1418               map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
1419
1420               if (map)
1421                 {
1422                   grub_util_fprint_full_disk_name (load_cfg_f, map, dev);
1423                   fprintf (load_cfg_f, " ");
1424                 }
1425
1426
1427               if (disk_module && disk_module[0]
1428                   && grub_strcmp (disk_module, "biosdisk") != 0)
1429                   g = grub_util_guess_baremetal_drive (*curdev);
1430               else
1431                 switch (platform)
1432                   {
1433                   case GRUB_INSTALL_PLATFORM_I386_PC:
1434                     g = grub_util_guess_bios_drive (*curdev);
1435                     break;
1436                   case GRUB_INSTALL_PLATFORM_I386_EFI:
1437                   case GRUB_INSTALL_PLATFORM_X86_64_EFI:
1438                   case GRUB_INSTALL_PLATFORM_ARM_EFI:
1439                   case GRUB_INSTALL_PLATFORM_ARM64_EFI:
1440                   case GRUB_INSTALL_PLATFORM_IA64_EFI:
1441                     g = grub_util_guess_efi_drive (*curdev);
1442                     break;
1443                   case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
1444                   case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
1445                   case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
1446                     {
1447                       const char * ofpath = grub_util_devname_to_ofpath (*curdev);
1448                       g = xasprintf ("ieee1275/%s", ofpath);
1449                       break;
1450                     }
1451                   case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
1452                   case GRUB_INSTALL_PLATFORM_I386_QEMU:
1453                   case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
1454                   case GRUB_INSTALL_PLATFORM_ARM_COREBOOT:
1455                   case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
1456                   case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
1457                   case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
1458                     g = grub_util_guess_baremetal_drive (*curdev);
1459                     break;
1460                   case GRUB_INSTALL_PLATFORM_MIPS_ARC:
1461                   case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
1462                   case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
1463                   case GRUB_INSTALL_PLATFORM_I386_XEN:
1464                   case GRUB_INSTALL_PLATFORM_X86_64_XEN:
1465                     grub_util_warn ("%s", _("no hints available for your platform. Expect reduced performance"));
1466                     break;
1467                     /* pacify warning.  */
1468                   case GRUB_INSTALL_PLATFORM_MAX:
1469                     break;
1470                   }
1471               if (g)
1472                 {
1473                   grub_util_fprint_full_disk_name (load_cfg_f, g, dev);
1474                   fprintf (load_cfg_f, " ");
1475                   free (g);
1476                 }
1477               if (dev != grub_dev)
1478                 grub_device_close (dev);
1479             }
1480           fprintf (load_cfg_f, "\n");
1481           char *escaped_relpath = escape (relative_grubdir);
1482           fprintf (load_cfg_f, "set prefix=($root)'%s'\n",
1483                    escaped_relpath);
1484         }
1485       else
1486         {
1487           /* We need to hardcode the partition number in the core image's prefix.  */
1488           char *p;
1489           for (p = grub_drives[0]; *p; )
1490             {
1491               if (*p == '\\' && p[1])
1492                 {
1493                   p += 2;
1494                   continue;
1495                 }
1496               if (*p == ',' || *p == '\0')
1497                 break;
1498               p++;
1499             }
1500           prefix_drive = xasprintf ("(%s)", p);
1501         }
1502     }
1503   else
1504     {
1505       if (config.is_cryptodisk_enabled)
1506         {
1507           if (grub_dev->disk)
1508             probe_cryptodisk_uuid (grub_dev->disk);
1509
1510           for (curdrive = grub_drives + 1; *curdrive; curdrive++)
1511             {
1512               grub_device_t dev = grub_device_open (*curdrive);
1513               if (!dev)
1514                 continue;
1515               if (dev->disk)
1516                 probe_cryptodisk_uuid (dev->disk);
1517               grub_device_close (dev);
1518             }
1519         }
1520       prefix_drive = xasprintf ("(%s)", grub_drives[0]);
1521     }
1522
1523   char mkimage_target[200];
1524   const char *core_name = NULL;
1525
1526   switch (platform)
1527     {
1528     case GRUB_INSTALL_PLATFORM_I386_EFI:
1529     case GRUB_INSTALL_PLATFORM_X86_64_EFI:
1530     case GRUB_INSTALL_PLATFORM_ARM_EFI:
1531     case GRUB_INSTALL_PLATFORM_ARM64_EFI:
1532     case GRUB_INSTALL_PLATFORM_IA64_EFI:
1533       core_name = "core.efi";
1534       snprintf (mkimage_target, sizeof (mkimage_target),
1535                 "%s-%s",
1536                 grub_install_get_platform_cpu (platform),
1537                 grub_install_get_platform_platform (platform));
1538       break;
1539     case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
1540     case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
1541     case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
1542       core_name = "core.elf";
1543       snprintf (mkimage_target, sizeof (mkimage_target),
1544                 "%s-%s-elf",
1545                 grub_install_get_platform_cpu (platform),
1546                 grub_install_get_platform_platform (platform));
1547       break;
1548
1549     case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
1550     case GRUB_INSTALL_PLATFORM_ARM_COREBOOT:
1551     case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
1552     case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
1553     case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
1554     case GRUB_INSTALL_PLATFORM_I386_XEN:
1555     case GRUB_INSTALL_PLATFORM_X86_64_XEN:
1556       core_name = "core.elf";
1557       snprintf (mkimage_target, sizeof (mkimage_target),
1558                 "%s-%s",
1559                 grub_install_get_platform_cpu (platform),
1560                 grub_install_get_platform_platform (platform));
1561       break;
1562
1563
1564     case GRUB_INSTALL_PLATFORM_I386_PC:
1565     case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
1566     case GRUB_INSTALL_PLATFORM_MIPS_ARC:
1567     case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
1568     case GRUB_INSTALL_PLATFORM_I386_QEMU:
1569       snprintf (mkimage_target, sizeof (mkimage_target),
1570                 "%s-%s",
1571                 grub_install_get_platform_cpu (platform),
1572                 grub_install_get_platform_platform (platform));
1573       core_name = "core.img";
1574       break;
1575     case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
1576       strcpy (mkimage_target, "sparc64-ieee1275-raw");
1577       core_name = "core.img";
1578       break;
1579       /* pacify warning.  */
1580     case GRUB_INSTALL_PLATFORM_MAX:
1581       break;
1582     }
1583
1584   if (!core_name)
1585     grub_util_error ("%s", _("You've found a bug"));
1586
1587   if (load_cfg_f)
1588     fclose (load_cfg_f);
1589
1590   char *imgfile = grub_util_path_concat (2, platdir,
1591                                        core_name);
1592   char *prefix = xasprintf ("%s%s", prefix_drive ? : "",
1593                             relative_grubdir);
1594   grub_install_make_image_wrap (/* source dir  */ grub_install_source_directory,
1595                                 /*prefix */ prefix,
1596                                 /* output */ imgfile,
1597                                 /* memdisk */ NULL,
1598                                 have_load_cfg ? load_cfg : NULL,
1599                                 /* image target */ mkimage_target, 0);
1600   /* Backward-compatibility kludges.  */
1601   switch (platform)
1602     {
1603     case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
1604       {
1605         char *dst = grub_util_path_concat (2, bootdir, "grub.elf");
1606         grub_install_copy_file (imgfile, dst, 1);
1607         free (dst);
1608       }
1609       break;
1610
1611     case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
1612     case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
1613       {
1614         char *dst = grub_util_path_concat (2, grubdir, "grub");
1615         grub_install_copy_file (imgfile, dst, 1);
1616         free (dst);
1617       }
1618       break;
1619
1620     case GRUB_INSTALL_PLATFORM_I386_EFI:
1621     case GRUB_INSTALL_PLATFORM_X86_64_EFI:
1622       {
1623         char *dst = grub_util_path_concat (2, platdir, "grub.efi");
1624         grub_install_make_image_wrap (/* source dir  */ grub_install_source_directory,
1625                                       /* prefix */ "",
1626                                        /* output */ dst,
1627                                        /* memdisk */ NULL,
1628                                       have_load_cfg ? load_cfg : NULL,
1629                                        /* image target */ mkimage_target, 0);
1630       }
1631       break;
1632     case GRUB_INSTALL_PLATFORM_ARM_EFI:
1633     case GRUB_INSTALL_PLATFORM_ARM64_EFI:
1634     case GRUB_INSTALL_PLATFORM_IA64_EFI:
1635     case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
1636     case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
1637     case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
1638     case GRUB_INSTALL_PLATFORM_ARM_COREBOOT:
1639     case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
1640     case GRUB_INSTALL_PLATFORM_I386_PC:
1641     case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
1642     case GRUB_INSTALL_PLATFORM_MIPS_ARC:
1643     case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
1644     case GRUB_INSTALL_PLATFORM_I386_QEMU:
1645     case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
1646     case GRUB_INSTALL_PLATFORM_I386_XEN:
1647     case GRUB_INSTALL_PLATFORM_X86_64_XEN:
1648       break;
1649       /* pacify warning.  */
1650     case GRUB_INSTALL_PLATFORM_MAX:
1651       break;
1652     }
1653
1654   /* Perform the platform-dependent install */
1655
1656   switch (platform)
1657     {
1658     case GRUB_INSTALL_PLATFORM_I386_PC:
1659       {
1660         char *boot_img_src = grub_util_path_concat (2, 
1661                                                   grub_install_source_directory,
1662                                                   "boot.img");
1663         char *boot_img = grub_util_path_concat (2, platdir,
1664                                               "boot.img");
1665         grub_install_copy_file (boot_img_src, boot_img, 1);
1666
1667         grub_util_info ("%sgrub-bios-setup %s %s %s %s %s --directory='%s' --device-map='%s' '%s'",
1668                         /* TRANSLATORS: This is a prefix in the log to indicate that usually
1669                            a command would be executed but due to an option was skipped.  */
1670                         install_bootsector ? "" : _("NOT RUNNING: "),
1671                         allow_floppy ? "--allow-floppy " : "",
1672                         verbosity ? "--verbose " : "",
1673                         force ? "--force " : "",
1674                         !fs_probe ? "--skip-fs-probe" : "",
1675                         !add_rs_codes ? "--no-rs-codes" : "",
1676                         platdir,
1677                         device_map,
1678                         install_device);
1679                         
1680         /*  Now perform the installation.  */
1681         if (install_bootsector)
1682           grub_util_bios_setup (platdir, "boot.img", "core.img",
1683                                 install_drive, force,
1684                                 fs_probe, allow_floppy, add_rs_codes);
1685         break;
1686       }
1687     case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
1688       {
1689         char *boot_img_src = grub_util_path_concat (2, 
1690                                                   grub_install_source_directory,
1691                                                   "boot.img");
1692         char *boot_img = grub_util_path_concat (2, platdir,
1693                                               "boot.img");
1694         grub_install_copy_file (boot_img_src, boot_img, 1);
1695
1696         grub_util_info ("%sgrub-sparc64-setup %s %s %s %s --directory='%s' --device-map='%s' '%s'",
1697                         install_bootsector ? "" : "NOT RUNNING: ",
1698                         allow_floppy ? "--allow-floppy " : "",
1699                         verbosity ? "--verbose " : "",
1700                         force ? "--force " : "",
1701                         !fs_probe ? "--skip-fs-probe" : "",
1702                         platdir,
1703                         device_map,
1704                         install_drive);
1705                         
1706         /*  Now perform the installation.  */
1707         if (install_bootsector)
1708           grub_util_sparc_setup (platdir, "boot.img", "core.img",
1709                                  install_drive, force,
1710                                  fs_probe, allow_floppy,
1711                                  0 /* unused */ );
1712         break;
1713       }
1714
1715     case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
1716       if (macppcdir)
1717         {
1718           char *core_services = grub_util_path_concat (4, macppcdir,
1719                                                        "System", "Library",
1720                                                        "CoreServices");
1721           char *mach_kernel = grub_util_path_concat (2, macppcdir,
1722                                                      "mach_kernel");
1723           char *grub_elf, *bootx;
1724           FILE *f;
1725           grub_device_t ins_dev;
1726           char *grub_chrp = grub_util_path_concat (2,
1727                                                    grub_install_source_directory,
1728                                                    "grub.chrp");
1729
1730           grub_install_mkdir_p (core_services);
1731
1732           bootx = grub_util_path_concat (2, core_services, "BootX");
1733           grub_install_copy_file (grub_chrp, bootx, 1);
1734
1735           grub_elf = grub_util_path_concat (2, core_services, "grub.elf");
1736           grub_install_copy_file (imgfile, grub_elf, 1);
1737
1738           f = grub_util_fopen (mach_kernel, "a+");
1739           if (!f)
1740             grub_util_error (_("Can't create file: %s"), strerror (errno));
1741           fclose (f);
1742
1743           fill_core_services (core_services);
1744
1745           ins_dev = grub_device_open (install_drive);
1746
1747           bless (ins_dev, core_services, 0);
1748
1749           if (update_nvram)
1750             {
1751               const char *dev;
1752               int partno;
1753
1754               partno = ins_dev->disk->partition
1755                 ? ins_dev->disk->partition->number + 1 : 0;
1756               dev = grub_util_get_os_disk (install_device);
1757               grub_install_register_ieee1275 (0, dev, partno,
1758                                               "\\\\BootX");
1759             }
1760           grub_device_close (ins_dev);
1761           free (grub_elf);
1762           free (bootx);
1763           free (mach_kernel);
1764           free (grub_chrp);
1765           break;
1766         }
1767       /* If a install device is defined, copy the core.elf to PReP partition.  */
1768       if (is_prep && install_device && install_device[0])
1769         {
1770           grub_device_t ins_dev;
1771           ins_dev = grub_device_open (install_drive);
1772           if (!ins_dev || !is_prep_partition (ins_dev))
1773             {
1774               grub_util_error ("%s", _("the chosen partition is not a PReP partition"));
1775             }
1776           if (is_prep_empty (ins_dev))
1777             {
1778               if (write_to_disk (ins_dev, imgfile))
1779                 grub_util_error ("%s", _("failed to copy Grub to the PReP partition"));
1780             }
1781           else
1782             {
1783               char *s = xasprintf ("dd if=/dev/zero of=%s", install_device);
1784               grub_util_error (_("the PReP partition is not empty. If you are sure you want to use it, run dd to clear it: `%s'"),
1785                                s);
1786             }
1787           grub_device_close (ins_dev);
1788           if (update_nvram)
1789             grub_install_register_ieee1275 (1, grub_util_get_os_disk (install_device),
1790                                             0, NULL);
1791           break;
1792       }
1793       /* fallthrough.  */
1794     case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
1795       if (update_nvram)
1796         {
1797           const char *dev;
1798           char *relpath;
1799           int partno;
1800           relpath = grub_make_system_path_relative_to_its_root (imgfile);
1801           partno = grub_dev->disk->partition
1802             ? grub_dev->disk->partition->number + 1 : 0;
1803           dev = grub_util_get_os_disk (grub_devices[0]);
1804           grub_install_register_ieee1275 (0, dev,
1805                                           partno, relpath);
1806         }
1807       break;
1808     case GRUB_INSTALL_PLATFORM_MIPS_ARC:
1809       grub_install_sgi_setup (install_device, imgfile, "grub");
1810       break;
1811
1812     case GRUB_INSTALL_PLATFORM_I386_EFI:
1813       if (!efidir_is_mac)
1814         {
1815           char *dst = grub_util_path_concat (2, efidir, "grub.efi");
1816           /* For old macs. Suggested by Peter Jones.  */
1817           grub_install_copy_file (imgfile, dst, 1);
1818           free (dst);
1819         }
1820       /* Fallthrough.  */
1821     case GRUB_INSTALL_PLATFORM_X86_64_EFI:
1822       if (efidir_is_mac)
1823         {
1824           char *boot_efi;
1825           char *core_services = grub_util_path_concat (4, efidir,
1826                                                        "System", "Library",
1827                                                        "CoreServices");
1828           char *mach_kernel = grub_util_path_concat (2, efidir,
1829                                                      "mach_kernel");
1830           FILE *f;
1831           grub_device_t ins_dev;
1832
1833           grub_install_mkdir_p (core_services);
1834
1835           boot_efi = grub_util_path_concat (2, core_services, "boot.efi");
1836           grub_install_copy_file (imgfile, boot_efi, 1);
1837
1838           f = grub_util_fopen (mach_kernel, "r+");
1839           if (!f)
1840             grub_util_error (_("Can't create file: %s"), strerror (errno));
1841           fclose (f);
1842
1843           fill_core_services(core_services);
1844
1845           ins_dev = grub_device_open (install_drive);
1846
1847           bless (ins_dev, boot_efi, 1);
1848           if (!removable && update_nvram)
1849             {
1850               /* Try to make this image bootable using the EFI Boot Manager, if available.  */
1851               grub_install_register_efi (efidir_grub_dev,
1852                                          "\\System\\Library\\CoreServices",
1853                                          efi_distributor);
1854             }
1855
1856           grub_device_close (ins_dev);
1857           free (boot_efi);
1858           free (mach_kernel);
1859           break;
1860         }
1861       /* FALLTHROUGH */
1862     case GRUB_INSTALL_PLATFORM_ARM_EFI:
1863     case GRUB_INSTALL_PLATFORM_ARM64_EFI:
1864     case GRUB_INSTALL_PLATFORM_IA64_EFI:
1865       {
1866         char *dst = grub_util_path_concat (2, efidir, efi_file);
1867         grub_install_copy_file (imgfile, dst, 1);
1868         free (dst);
1869       }
1870       if (!removable && update_nvram)
1871         {
1872           char * efifile_path;
1873           char * part;
1874
1875           /* Try to make this image bootable using the EFI Boot Manager, if available.  */
1876           if (!efi_distributor || efi_distributor[0] == '\0')
1877             grub_util_error ("%s", _("EFI bootloader id isn't specified."));
1878           efifile_path = xasprintf ("\\EFI\\%s\\%s",
1879                                     efi_distributor,
1880                                     efi_file);
1881           part = (efidir_grub_dev->disk->partition
1882                   ? grub_partition_get_name (efidir_grub_dev->disk->partition)
1883                   : 0);
1884           grub_util_info ("Registering with EFI: distributor = `%s',"
1885                           " path = `%s', ESP at %s%s%s",
1886                           efi_distributor, efifile_path,
1887                           efidir_grub_dev->disk->name,
1888                           (part ? ",": ""), (part ? : ""));
1889           grub_free (part);
1890           grub_install_register_efi (efidir_grub_dev,
1891                                      efifile_path, efi_distributor);
1892         }
1893       break;
1894
1895     case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON:
1896     case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
1897     case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
1898     case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
1899     case GRUB_INSTALL_PLATFORM_ARM_COREBOOT:
1900     case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
1901     case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
1902     case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
1903     case GRUB_INSTALL_PLATFORM_I386_QEMU:
1904     case GRUB_INSTALL_PLATFORM_I386_XEN:
1905     case GRUB_INSTALL_PLATFORM_X86_64_XEN:
1906       grub_util_warn ("%s",
1907                       _("WARNING: no platform-specific install was performed"));
1908       break;
1909       /* pacify warning.  */
1910     case GRUB_INSTALL_PLATFORM_MAX:
1911       break;
1912     }
1913
1914   fprintf (stderr, "%s\n", _("Installation finished. No error reported."));
1915
1916   /* Free resources.  */
1917   grub_gcry_fini_all ();
1918   grub_fini_all ();
1919
1920   return 0;
1921 }