123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- /*
- * 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/hostdisk.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)
- {
- size_t alloced = 4096;
- char *ret = xmalloc (alloced);
- size_t offset = 0;
- int fd;
- pid_t pid;
- 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))
- {
- size_t r;
- if (alloced == offset)
- {
- alloced *= 2;
- ret = xrealloc (ret, alloced);
- }
- r = fread (ret + offset, 1, alloced - offset, fp);
- offset += r;
- }
- if (offset > 0 && ret[offset - 1] == '\n')
- offset--;
- if (offset > 0 && ret[offset - 1] == '\r')
- offset--;
- if (alloced == offset)
- {
- alloced++;
- ret = xrealloc (ret, alloced);
- }
- ret[offset] = '\0';
- fclose (fp);
- return ret;
- fail:
- grub_util_error (_("couldn't find IEEE1275 device 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 (grub_device_t efidir_grub_dev,
- const char *efifile_path,
- const char *efi_distributor)
- {
- const char * efidir_disk;
- int efidir_part;
- efidir_disk = grub_util_biosdisk_get_osdev (efidir_grub_dev->disk);
- efidir_part = efidir_grub_dev->disk->partition ? efidir_grub_dev->disk->partition->number + 1 : 1;
- 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."));
- }
|