xref: /illumos-gate/usr/src/grub/grub-0.97/grub/main.c (revision 1b8adde7)
17c478bd9Sstevel@tonic-gate /* main.c - experimental GRUB stage2 that runs under Unix */
27c478bd9Sstevel@tonic-gate /*
37c478bd9Sstevel@tonic-gate  *  GRUB  --  GRand Unified Bootloader
47c478bd9Sstevel@tonic-gate  *  Copyright (C) 1999,2000,2001,2002  Free Software Foundation, Inc.
57c478bd9Sstevel@tonic-gate  *
67c478bd9Sstevel@tonic-gate  *  This program is free software; you can redistribute it and/or modify
77c478bd9Sstevel@tonic-gate  *  it under the terms of the GNU General Public License as published by
87c478bd9Sstevel@tonic-gate  *  the Free Software Foundation; either version 2 of the License, or
97c478bd9Sstevel@tonic-gate  *  (at your option) any later version.
107c478bd9Sstevel@tonic-gate  *
117c478bd9Sstevel@tonic-gate  *  This program is distributed in the hope that it will be useful,
127c478bd9Sstevel@tonic-gate  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
137c478bd9Sstevel@tonic-gate  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
147c478bd9Sstevel@tonic-gate  *  GNU General Public License for more details.
157c478bd9Sstevel@tonic-gate  *
167c478bd9Sstevel@tonic-gate  *  You should have received a copy of the GNU General Public License
177c478bd9Sstevel@tonic-gate  *  along with this program; if not, write to the Free Software
187c478bd9Sstevel@tonic-gate  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
197c478bd9Sstevel@tonic-gate  */
207c478bd9Sstevel@tonic-gate 
217c478bd9Sstevel@tonic-gate /* Simulator entry point. */
227c478bd9Sstevel@tonic-gate int grub_stage2 (void);
237c478bd9Sstevel@tonic-gate 
247c478bd9Sstevel@tonic-gate #include <stdio.h>
257c478bd9Sstevel@tonic-gate #include <getopt.h>
267c478bd9Sstevel@tonic-gate #include <unistd.h>
277c478bd9Sstevel@tonic-gate #include <string.h>
287c478bd9Sstevel@tonic-gate #include <stdlib.h>
297c478bd9Sstevel@tonic-gate #include <limits.h>
307c478bd9Sstevel@tonic-gate #include <setjmp.h>
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate #define WITHOUT_LIBC_STUBS 1
337c478bd9Sstevel@tonic-gate #include <shared.h>
347c478bd9Sstevel@tonic-gate #include <term.h>
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate char *program_name = 0;
377c478bd9Sstevel@tonic-gate int use_config_file = 1;
387c478bd9Sstevel@tonic-gate int use_preset_menu = 0;
397c478bd9Sstevel@tonic-gate #ifdef HAVE_LIBCURSES
407c478bd9Sstevel@tonic-gate int use_curses = 1;
417c478bd9Sstevel@tonic-gate #else
427c478bd9Sstevel@tonic-gate int use_curses = 0;
437c478bd9Sstevel@tonic-gate #endif
447c478bd9Sstevel@tonic-gate int verbose = 0;
457c478bd9Sstevel@tonic-gate int read_only = 0;
467c478bd9Sstevel@tonic-gate int floppy_disks = 1;
477c478bd9Sstevel@tonic-gate char *device_map_file = 0;
487c478bd9Sstevel@tonic-gate static int default_boot_drive;
497c478bd9Sstevel@tonic-gate static int default_install_partition;
507c478bd9Sstevel@tonic-gate static char *default_config_file;
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate #define OPT_HELP		-2
537c478bd9Sstevel@tonic-gate #define OPT_VERSION		-3
547c478bd9Sstevel@tonic-gate #define OPT_HOLD		-4
557c478bd9Sstevel@tonic-gate #define OPT_CONFIG_FILE		-5
567c478bd9Sstevel@tonic-gate #define OPT_INSTALL_PARTITION	-6
577c478bd9Sstevel@tonic-gate #define OPT_BOOT_DRIVE		-7
587c478bd9Sstevel@tonic-gate #define OPT_NO_CONFIG_FILE	-8
597c478bd9Sstevel@tonic-gate #define OPT_NO_CURSES		-9
607c478bd9Sstevel@tonic-gate #define OPT_BATCH		-10
617c478bd9Sstevel@tonic-gate #define OPT_VERBOSE		-11
627c478bd9Sstevel@tonic-gate #define OPT_READ_ONLY		-12
637c478bd9Sstevel@tonic-gate #define OPT_PROBE_SECOND_FLOPPY	-13
647c478bd9Sstevel@tonic-gate #define OPT_NO_FLOPPY		-14
657c478bd9Sstevel@tonic-gate #define OPT_DEVICE_MAP		-15
667c478bd9Sstevel@tonic-gate #define OPT_PRESET_MENU		-16
677c478bd9Sstevel@tonic-gate #define OPT_NO_PAGER		-17
687c478bd9Sstevel@tonic-gate #define OPTSTRING ""
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate static struct option longopts[] =
717c478bd9Sstevel@tonic-gate {
727c478bd9Sstevel@tonic-gate   {"batch", no_argument, 0, OPT_BATCH},
737c478bd9Sstevel@tonic-gate   {"boot-drive", required_argument, 0, OPT_BOOT_DRIVE},
747c478bd9Sstevel@tonic-gate   {"config-file", required_argument, 0, OPT_CONFIG_FILE},
757c478bd9Sstevel@tonic-gate   {"device-map", required_argument, 0, OPT_DEVICE_MAP},
767c478bd9Sstevel@tonic-gate   {"help", no_argument, 0, OPT_HELP},
777c478bd9Sstevel@tonic-gate   {"hold", optional_argument, 0, OPT_HOLD},
787c478bd9Sstevel@tonic-gate   {"install-partition", required_argument, 0, OPT_INSTALL_PARTITION},
797c478bd9Sstevel@tonic-gate   {"no-config-file", no_argument, 0, OPT_NO_CONFIG_FILE},
807c478bd9Sstevel@tonic-gate   {"no-curses", no_argument, 0, OPT_NO_CURSES},
817c478bd9Sstevel@tonic-gate   {"no-floppy", no_argument, 0, OPT_NO_FLOPPY},
827c478bd9Sstevel@tonic-gate   {"no-pager", no_argument, 0, OPT_NO_PAGER},
837c478bd9Sstevel@tonic-gate   {"preset-menu", no_argument, 0, OPT_PRESET_MENU},
847c478bd9Sstevel@tonic-gate   {"probe-second-floppy", no_argument, 0, OPT_PROBE_SECOND_FLOPPY},
857c478bd9Sstevel@tonic-gate   {"read-only", no_argument, 0, OPT_READ_ONLY},
867c478bd9Sstevel@tonic-gate   {"verbose", no_argument, 0, OPT_VERBOSE},
877c478bd9Sstevel@tonic-gate   {"version", no_argument, 0, OPT_VERSION},
887c478bd9Sstevel@tonic-gate   {0},
897c478bd9Sstevel@tonic-gate };
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate static void
usage(int status)937c478bd9Sstevel@tonic-gate usage (int status)
947c478bd9Sstevel@tonic-gate {
957c478bd9Sstevel@tonic-gate   if (status)
967c478bd9Sstevel@tonic-gate     fprintf (stderr, "Try ``grub --help'' for more information.\n");
977c478bd9Sstevel@tonic-gate   else
987c478bd9Sstevel@tonic-gate     printf ("\
997c478bd9Sstevel@tonic-gate Usage: grub [OPTION]...\n\
1007c478bd9Sstevel@tonic-gate \n\
1017c478bd9Sstevel@tonic-gate Enter the GRand Unified Bootloader command shell.\n\
1027c478bd9Sstevel@tonic-gate \n\
1037c478bd9Sstevel@tonic-gate     --batch                  turn on batch mode for non-interactive use\n\
1047c478bd9Sstevel@tonic-gate     --boot-drive=DRIVE       specify stage2 boot_drive [default=0x%x]\n\
1057c478bd9Sstevel@tonic-gate     --config-file=FILE       specify stage2 config_file [default=%s]\n\
1067c478bd9Sstevel@tonic-gate     --device-map=FILE        use the device map file FILE\n\
1077c478bd9Sstevel@tonic-gate     --help                   display this message and exit\n\
1087c478bd9Sstevel@tonic-gate     --hold                   wait until a debugger will attach\n\
1097c478bd9Sstevel@tonic-gate     --install-partition=PAR  specify stage2 install_partition [default=0x%x]\n\
1107c478bd9Sstevel@tonic-gate     --no-config-file         do not use the config file\n\
1117c478bd9Sstevel@tonic-gate     --no-curses              do not use curses\n\
1127c478bd9Sstevel@tonic-gate     --no-floppy              do not probe any floppy drive\n\
1137c478bd9Sstevel@tonic-gate     --no-pager               do not use internal pager\n\
1147c478bd9Sstevel@tonic-gate     --preset-menu            use the preset menu\n\
1157c478bd9Sstevel@tonic-gate     --probe-second-floppy    probe the second floppy drive\n\
1167c478bd9Sstevel@tonic-gate     --read-only              do not write anything to devices\n\
1177c478bd9Sstevel@tonic-gate     --verbose                print verbose messages\n\
1187c478bd9Sstevel@tonic-gate     --version                print version information and exit\n\
1197c478bd9Sstevel@tonic-gate \n\
1207c478bd9Sstevel@tonic-gate Report bugs to <bug-grub@gnu.org>.\n\
1217c478bd9Sstevel@tonic-gate ",
1227c478bd9Sstevel@tonic-gate 	    default_boot_drive, default_config_file,
1237c478bd9Sstevel@tonic-gate 	    default_install_partition);
1247c478bd9Sstevel@tonic-gate 
1257c478bd9Sstevel@tonic-gate   exit (status);
1267c478bd9Sstevel@tonic-gate }
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate int
main(int argc,char ** argv)1307c478bd9Sstevel@tonic-gate main (int argc, char **argv)
1317c478bd9Sstevel@tonic-gate {
1327c478bd9Sstevel@tonic-gate   int c;
1337c478bd9Sstevel@tonic-gate   int hold = 0;
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate   /* First of all, call sync so that all in-core data is scheduled to be
1367c478bd9Sstevel@tonic-gate      actually written to disks. This is very important because GRUB does
1377c478bd9Sstevel@tonic-gate      not use ordinary stdio interface but raw devices.  */
1387c478bd9Sstevel@tonic-gate   sync ();
1397c478bd9Sstevel@tonic-gate 
1407c478bd9Sstevel@tonic-gate   program_name = argv[0];
1417c478bd9Sstevel@tonic-gate   default_boot_drive = boot_drive;
1427c478bd9Sstevel@tonic-gate   default_install_partition = install_partition;
1437c478bd9Sstevel@tonic-gate   if (config_file)
1447c478bd9Sstevel@tonic-gate     default_config_file = config_file;
1457c478bd9Sstevel@tonic-gate   else
1467c478bd9Sstevel@tonic-gate     default_config_file = "NONE";
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate   /* Parse command-line options. */
1497c478bd9Sstevel@tonic-gate   do
1507c478bd9Sstevel@tonic-gate     {
1517c478bd9Sstevel@tonic-gate       c = getopt_long (argc, argv, OPTSTRING, longopts, 0);
1527c478bd9Sstevel@tonic-gate       switch (c)
1537c478bd9Sstevel@tonic-gate 	{
1547c478bd9Sstevel@tonic-gate 	case EOF:
1557c478bd9Sstevel@tonic-gate 	  /* Fall through the bottom of the loop. */
1567c478bd9Sstevel@tonic-gate 	  break;
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate 	case OPT_HELP:
1597c478bd9Sstevel@tonic-gate 	  usage (0);
1607c478bd9Sstevel@tonic-gate 	  break;
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate 	case OPT_VERSION:
1637c478bd9Sstevel@tonic-gate 	  printf ("grub (GNU GRUB " VERSION ")\n");
1647c478bd9Sstevel@tonic-gate 	  exit (0);
1657c478bd9Sstevel@tonic-gate 	  break;
1667c478bd9Sstevel@tonic-gate 
1677c478bd9Sstevel@tonic-gate 	case OPT_HOLD:
1687c478bd9Sstevel@tonic-gate 	  if (! optarg)
1697c478bd9Sstevel@tonic-gate 	    hold = -1;
1707c478bd9Sstevel@tonic-gate 	  else
1717c478bd9Sstevel@tonic-gate 	    hold = atoi (optarg);
1727c478bd9Sstevel@tonic-gate 	  break;
1737c478bd9Sstevel@tonic-gate 
1747c478bd9Sstevel@tonic-gate 	case OPT_CONFIG_FILE:
1757c478bd9Sstevel@tonic-gate 	  strncpy (config_file, optarg, 127); /* FIXME: arbitrary */
1767c478bd9Sstevel@tonic-gate 	  config_file[127] = '\0';
1777c478bd9Sstevel@tonic-gate 	  break;
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate 	case OPT_INSTALL_PARTITION:
1807c478bd9Sstevel@tonic-gate 	  install_partition = strtoul (optarg, 0, 0);
1817c478bd9Sstevel@tonic-gate 	  if (install_partition == ULONG_MAX)
1827c478bd9Sstevel@tonic-gate 	    {
1837c478bd9Sstevel@tonic-gate 	      perror ("strtoul");
1847c478bd9Sstevel@tonic-gate 	      exit (1);
1857c478bd9Sstevel@tonic-gate 	    }
1867c478bd9Sstevel@tonic-gate 	  break;
1877c478bd9Sstevel@tonic-gate 
1887c478bd9Sstevel@tonic-gate 	case OPT_BOOT_DRIVE:
1897c478bd9Sstevel@tonic-gate 	  boot_drive = strtoul (optarg, 0, 0);
1907c478bd9Sstevel@tonic-gate 	  if (boot_drive == ULONG_MAX)
1917c478bd9Sstevel@tonic-gate 	    {
1927c478bd9Sstevel@tonic-gate 	      perror ("strtoul");
1937c478bd9Sstevel@tonic-gate 	      exit (1);
1947c478bd9Sstevel@tonic-gate 	    }
1957c478bd9Sstevel@tonic-gate 	  break;
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate 	case OPT_NO_CONFIG_FILE:
1987c478bd9Sstevel@tonic-gate 	  use_config_file = 0;
1997c478bd9Sstevel@tonic-gate 	  break;
2007c478bd9Sstevel@tonic-gate 
2017c478bd9Sstevel@tonic-gate 	case OPT_NO_CURSES:
2027c478bd9Sstevel@tonic-gate 	  use_curses = 0;
2037c478bd9Sstevel@tonic-gate 	  break;
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate 	case OPT_NO_PAGER:
2067c478bd9Sstevel@tonic-gate 	  use_pager = 0;
2077c478bd9Sstevel@tonic-gate 	  break;
2087c478bd9Sstevel@tonic-gate 
2097c478bd9Sstevel@tonic-gate 	case OPT_BATCH:
2107c478bd9Sstevel@tonic-gate 	  /* This is the same as "--no-config-file --no-curses --no-pager".  */
2117c478bd9Sstevel@tonic-gate 	  use_config_file = 0;
2127c478bd9Sstevel@tonic-gate 	  use_curses = 0;
2137c478bd9Sstevel@tonic-gate 	  use_pager = 0;
2147c478bd9Sstevel@tonic-gate 	  break;
2157c478bd9Sstevel@tonic-gate 
2167c478bd9Sstevel@tonic-gate 	case OPT_READ_ONLY:
2177c478bd9Sstevel@tonic-gate 	  read_only = 1;
2187c478bd9Sstevel@tonic-gate 	  break;
2197c478bd9Sstevel@tonic-gate 
2207c478bd9Sstevel@tonic-gate 	case OPT_VERBOSE:
2217c478bd9Sstevel@tonic-gate 	  verbose = 1;
2227c478bd9Sstevel@tonic-gate 	  break;
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate 	case OPT_NO_FLOPPY:
2257c478bd9Sstevel@tonic-gate 	  floppy_disks = 0;
2267c478bd9Sstevel@tonic-gate 	  break;
2277c478bd9Sstevel@tonic-gate 
2287c478bd9Sstevel@tonic-gate 	case OPT_PROBE_SECOND_FLOPPY:
2297c478bd9Sstevel@tonic-gate 	  floppy_disks = 2;
2307c478bd9Sstevel@tonic-gate 	  break;
2317c478bd9Sstevel@tonic-gate 
2327c478bd9Sstevel@tonic-gate 	case OPT_DEVICE_MAP:
2337c478bd9Sstevel@tonic-gate 	  device_map_file = strdup (optarg);
2347c478bd9Sstevel@tonic-gate 	  break;
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate 	case OPT_PRESET_MENU:
2377c478bd9Sstevel@tonic-gate 	  use_preset_menu = 1;
2387c478bd9Sstevel@tonic-gate 	  break;
2397c478bd9Sstevel@tonic-gate 
2407c478bd9Sstevel@tonic-gate 	default:
2417c478bd9Sstevel@tonic-gate 	  usage (1);
2427c478bd9Sstevel@tonic-gate 	}
2437c478bd9Sstevel@tonic-gate     }
2447c478bd9Sstevel@tonic-gate   while (c != EOF);
2457c478bd9Sstevel@tonic-gate 
2467c478bd9Sstevel@tonic-gate   /* Wait until the HOLD variable is cleared by an attached debugger. */
2477c478bd9Sstevel@tonic-gate   if (hold && verbose)
2487c478bd9Sstevel@tonic-gate     printf ("Run \"gdb %s %d\", and set HOLD to zero.\n",
2497c478bd9Sstevel@tonic-gate 	    program_name, (int) getpid ());
2507c478bd9Sstevel@tonic-gate   while (hold)
2517c478bd9Sstevel@tonic-gate     {
2527c478bd9Sstevel@tonic-gate       if (hold > 0)
2537c478bd9Sstevel@tonic-gate 	hold--;
2547c478bd9Sstevel@tonic-gate 
2557c478bd9Sstevel@tonic-gate       sleep (1);
2567c478bd9Sstevel@tonic-gate     }
2577c478bd9Sstevel@tonic-gate 
2587c478bd9Sstevel@tonic-gate   /* If we don't have curses (!HAVE_LIBCURSES or --no-curses or
2597c478bd9Sstevel@tonic-gate      --batch) put terminal to dumb for better handling of line i/o */
2607c478bd9Sstevel@tonic-gate   if (! use_curses)
2617c478bd9Sstevel@tonic-gate     current_term->flags = TERM_NO_EDIT | TERM_DUMB;
2627c478bd9Sstevel@tonic-gate 
2637c478bd9Sstevel@tonic-gate   /* Transfer control to the stage2 simulator. */
2647c478bd9Sstevel@tonic-gate   exit (grub_stage2 ());
2657c478bd9Sstevel@tonic-gate }
266