platform.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /*
  2. * GRUB -- GRand Unified Bootloader
  3. * Copyright (C) 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. #include <config.h>
  19. #include <grub/util/install.h>
  20. #include <grub/emu/hostdisk.h>
  21. #include <grub/util/misc.h>
  22. #include <grub/misc.h>
  23. #include <grub/i18n.h>
  24. #include <grub/emu/exec.h>
  25. #include <sys/types.h>
  26. #include <dirent.h>
  27. #include <string.h>
  28. #include <errno.h>
  29. static char *
  30. get_ofpathname (const char *dev)
  31. {
  32. size_t alloced = 4096;
  33. char *ret = xmalloc (alloced);
  34. size_t offset = 0;
  35. int fd;
  36. pid_t pid;
  37. pid = grub_util_exec_pipe ((const char * []){ "ofpathname", dev, NULL }, &fd);
  38. if (!pid)
  39. goto fail;
  40. FILE *fp = fdopen (fd, "r");
  41. if (!fp)
  42. goto fail;
  43. while (!feof (fp))
  44. {
  45. size_t r;
  46. if (alloced == offset)
  47. {
  48. alloced *= 2;
  49. ret = xrealloc (ret, alloced);
  50. }
  51. r = fread (ret + offset, 1, alloced - offset, fp);
  52. offset += r;
  53. }
  54. if (offset > 0 && ret[offset - 1] == '\n')
  55. offset--;
  56. if (offset > 0 && ret[offset - 1] == '\r')
  57. offset--;
  58. if (alloced == offset)
  59. {
  60. alloced++;
  61. ret = xrealloc (ret, alloced);
  62. }
  63. ret[offset] = '\0';
  64. fclose (fp);
  65. return ret;
  66. fail:
  67. grub_util_error (_("couldn't find IEEE1275 device path for %s.\nYou will have to set `boot-device' variable manually"),
  68. dev);
  69. }
  70. static void
  71. grub_install_remove_efi_entries_by_distributor (const char *efi_distributor)
  72. {
  73. int fd;
  74. pid_t pid = grub_util_exec_pipe ((const char * []){ "efibootmgr", NULL }, &fd);
  75. char *line = NULL;
  76. size_t len = 0;
  77. if (!pid)
  78. {
  79. grub_util_warn (_("Unable to open stream from %s: %s"),
  80. "efibootmgr", strerror (errno));
  81. return;
  82. }
  83. FILE *fp = fdopen (fd, "r");
  84. if (!fp)
  85. {
  86. grub_util_warn (_("Unable to open stream from %s: %s"),
  87. "efibootmgr", strerror (errno));
  88. return;
  89. }
  90. line = xmalloc (80);
  91. len = 80;
  92. while (1)
  93. {
  94. int ret;
  95. char *bootnum;
  96. ret = getline (&line, &len, fp);
  97. if (ret == -1)
  98. break;
  99. if (grub_memcmp (line, "Boot", sizeof ("Boot") - 1) != 0
  100. || line[sizeof ("Boot") - 1] < '0'
  101. || line[sizeof ("Boot") - 1] > '9')
  102. continue;
  103. if (!strcasestr (line, efi_distributor))
  104. continue;
  105. bootnum = line + sizeof ("Boot") - 1;
  106. bootnum[4] = '\0';
  107. if (!verbosity)
  108. grub_util_exec ((const char * []){ "efibootmgr", "-q",
  109. "-b", bootnum, "-B", NULL });
  110. else
  111. grub_util_exec ((const char * []){ "efibootmgr",
  112. "-b", bootnum, "-B", NULL });
  113. }
  114. free (line);
  115. }
  116. void
  117. grub_install_register_efi (grub_device_t efidir_grub_dev,
  118. const char *efifile_path,
  119. const char *efi_distributor)
  120. {
  121. const char * efidir_disk;
  122. int efidir_part;
  123. efidir_disk = grub_util_biosdisk_get_osdev (efidir_grub_dev->disk);
  124. efidir_part = efidir_grub_dev->disk->partition ? efidir_grub_dev->disk->partition->number + 1 : 1;
  125. if (grub_util_exec_redirect_null ((const char * []){ "efibootmgr", "--version", NULL }))
  126. {
  127. /* TRANSLATORS: This message is shown when required executable `%s'
  128. isn't found. */
  129. grub_util_error (_("%s: not found"), "efibootmgr");
  130. }
  131. /* On Linux, we need the efivars kernel modules. */
  132. #ifdef __linux__
  133. grub_util_exec ((const char * []){ "modprobe", "-q", "efivars", NULL });
  134. #endif
  135. /* Delete old entries from the same distributor. */
  136. grub_install_remove_efi_entries_by_distributor (efi_distributor);
  137. char *efidir_part_str = xasprintf ("%d", efidir_part);
  138. if (!verbosity)
  139. grub_util_exec ((const char * []){ "efibootmgr", "-q",
  140. "-c", "-d", efidir_disk,
  141. "-p", efidir_part_str, "-w",
  142. "-L", efi_distributor, "-l",
  143. efifile_path, NULL });
  144. else
  145. grub_util_exec ((const char * []){ "efibootmgr",
  146. "-c", "-d", efidir_disk,
  147. "-p", efidir_part_str, "-w",
  148. "-L", efi_distributor, "-l",
  149. efifile_path, NULL });
  150. free (efidir_part_str);
  151. }
  152. void
  153. grub_install_register_ieee1275 (int is_prep, const char *install_device,
  154. int partno, const char *relpath)
  155. {
  156. char *boot_device;
  157. if (grub_util_exec_redirect_null ((const char * []){ "ofpathname", "--version", NULL }))
  158. {
  159. /* TRANSLATORS: This message is shown when required executable `%s'
  160. isn't found. */
  161. grub_util_error (_("%s: not found"), "ofpathname");
  162. }
  163. /* Get the Open Firmware device tree path translation. */
  164. if (!is_prep)
  165. {
  166. char *ptr;
  167. char *ofpath;
  168. const char *iptr;
  169. ofpath = get_ofpathname (install_device);
  170. boot_device = xmalloc (strlen (ofpath) + 1
  171. + sizeof ("XXXXXXXXXXXXXXXXXXXX")
  172. + 1 + strlen (relpath) + 1);
  173. ptr = grub_stpcpy (boot_device, ofpath);
  174. *ptr++ = ':';
  175. grub_snprintf (ptr, sizeof ("XXXXXXXXXXXXXXXXXXXX"), "%d",
  176. partno);
  177. ptr += strlen (ptr);
  178. *ptr++ = ',';
  179. for (iptr = relpath; *iptr; iptr++, ptr++)
  180. {
  181. if (*iptr == '/')
  182. *ptr = '\\';
  183. else
  184. *ptr = *iptr;
  185. }
  186. *ptr = '\0';
  187. }
  188. else
  189. boot_device = get_ofpathname (install_device);
  190. if (grub_util_exec ((const char * []){ "nvsetenv", "boot-device",
  191. boot_device, NULL }))
  192. {
  193. char *cmd = xasprintf ("setenv boot-device %s", boot_device);
  194. grub_util_error (_("`nvsetenv' failed. \nYou will have to set `boot-device' variable manually. At the IEEE1275 prompt, type:\n %s\n"),
  195. cmd);
  196. free (cmd);
  197. }
  198. free (boot_device);
  199. }
  200. void
  201. grub_install_sgi_setup (const char *install_device,
  202. const char *imgfile, const char *destname)
  203. {
  204. grub_util_exec ((const char * []){ "dvhtool", "-d",
  205. install_device, "--unix-to-vh",
  206. imgfile, destname, NULL });
  207. grub_util_warn ("%s", _("You will have to set `SystemPartition' and `OSLoader' manually."));
  208. }