xref: /illumos-gate/usr/src/grub/grub-0.97/grub/main.c (revision 1b8adde7)
1 /* main.c - experimental GRUB stage2 that runs under Unix */
2 /*
3  *  GRUB  --  GRand Unified Bootloader
4  *  Copyright (C) 1999,2000,2001,2002  Free Software Foundation, Inc.
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20 
21 /* Simulator entry point. */
22 int grub_stage2 (void);
23 
24 #include <stdio.h>
25 #include <getopt.h>
26 #include <unistd.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #include <limits.h>
30 #include <setjmp.h>
31 
32 #define WITHOUT_LIBC_STUBS 1
33 #include <shared.h>
34 #include <term.h>
35 
36 char *program_name = 0;
37 int use_config_file = 1;
38 int use_preset_menu = 0;
39 #ifdef HAVE_LIBCURSES
40 int use_curses = 1;
41 #else
42 int use_curses = 0;
43 #endif
44 int verbose = 0;
45 int read_only = 0;
46 int floppy_disks = 1;
47 char *device_map_file = 0;
48 static int default_boot_drive;
49 static int default_install_partition;
50 static char *default_config_file;
51 
52 #define OPT_HELP		-2
53 #define OPT_VERSION		-3
54 #define OPT_HOLD		-4
55 #define OPT_CONFIG_FILE		-5
56 #define OPT_INSTALL_PARTITION	-6
57 #define OPT_BOOT_DRIVE		-7
58 #define OPT_NO_CONFIG_FILE	-8
59 #define OPT_NO_CURSES		-9
60 #define OPT_BATCH		-10
61 #define OPT_VERBOSE		-11
62 #define OPT_READ_ONLY		-12
63 #define OPT_PROBE_SECOND_FLOPPY	-13
64 #define OPT_NO_FLOPPY		-14
65 #define OPT_DEVICE_MAP		-15
66 #define OPT_PRESET_MENU		-16
67 #define OPT_NO_PAGER		-17
68 #define OPTSTRING ""
69 
70 static struct option longopts[] =
71 {
72   {"batch", no_argument, 0, OPT_BATCH},
73   {"boot-drive", required_argument, 0, OPT_BOOT_DRIVE},
74   {"config-file", required_argument, 0, OPT_CONFIG_FILE},
75   {"device-map", required_argument, 0, OPT_DEVICE_MAP},
76   {"help", no_argument, 0, OPT_HELP},
77   {"hold", optional_argument, 0, OPT_HOLD},
78   {"install-partition", required_argument, 0, OPT_INSTALL_PARTITION},
79   {"no-config-file", no_argument, 0, OPT_NO_CONFIG_FILE},
80   {"no-curses", no_argument, 0, OPT_NO_CURSES},
81   {"no-floppy", no_argument, 0, OPT_NO_FLOPPY},
82   {"no-pager", no_argument, 0, OPT_NO_PAGER},
83   {"preset-menu", no_argument, 0, OPT_PRESET_MENU},
84   {"probe-second-floppy", no_argument, 0, OPT_PROBE_SECOND_FLOPPY},
85   {"read-only", no_argument, 0, OPT_READ_ONLY},
86   {"verbose", no_argument, 0, OPT_VERBOSE},
87   {"version", no_argument, 0, OPT_VERSION},
88   {0},
89 };
90 
91 
92 static void
usage(int status)93 usage (int status)
94 {
95   if (status)
96     fprintf (stderr, "Try ``grub --help'' for more information.\n");
97   else
98     printf ("\
99 Usage: grub [OPTION]...\n\
100 \n\
101 Enter the GRand Unified Bootloader command shell.\n\
102 \n\
103     --batch                  turn on batch mode for non-interactive use\n\
104     --boot-drive=DRIVE       specify stage2 boot_drive [default=0x%x]\n\
105     --config-file=FILE       specify stage2 config_file [default=%s]\n\
106     --device-map=FILE        use the device map file FILE\n\
107     --help                   display this message and exit\n\
108     --hold                   wait until a debugger will attach\n\
109     --install-partition=PAR  specify stage2 install_partition [default=0x%x]\n\
110     --no-config-file         do not use the config file\n\
111     --no-curses              do not use curses\n\
112     --no-floppy              do not probe any floppy drive\n\
113     --no-pager               do not use internal pager\n\
114     --preset-menu            use the preset menu\n\
115     --probe-second-floppy    probe the second floppy drive\n\
116     --read-only              do not write anything to devices\n\
117     --verbose                print verbose messages\n\
118     --version                print version information and exit\n\
119 \n\
120 Report bugs to <bug-grub@gnu.org>.\n\
121 ",
122 	    default_boot_drive, default_config_file,
123 	    default_install_partition);
124 
125   exit (status);
126 }
127 
128 
129 int
main(int argc,char ** argv)130 main (int argc, char **argv)
131 {
132   int c;
133   int hold = 0;
134 
135   /* First of all, call sync so that all in-core data is scheduled to be
136      actually written to disks. This is very important because GRUB does
137      not use ordinary stdio interface but raw devices.  */
138   sync ();
139 
140   program_name = argv[0];
141   default_boot_drive = boot_drive;
142   default_install_partition = install_partition;
143   if (config_file)
144     default_config_file = config_file;
145   else
146     default_config_file = "NONE";
147 
148   /* Parse command-line options. */
149   do
150     {
151       c = getopt_long (argc, argv, OPTSTRING, longopts, 0);
152       switch (c)
153 	{
154 	case EOF:
155 	  /* Fall through the bottom of the loop. */
156 	  break;
157 
158 	case OPT_HELP:
159 	  usage (0);
160 	  break;
161 
162 	case OPT_VERSION:
163 	  printf ("grub (GNU GRUB " VERSION ")\n");
164 	  exit (0);
165 	  break;
166 
167 	case OPT_HOLD:
168 	  if (! optarg)
169 	    hold = -1;
170 	  else
171 	    hold = atoi (optarg);
172 	  break;
173 
174 	case OPT_CONFIG_FILE:
175 	  strncpy (config_file, optarg, 127); /* FIXME: arbitrary */
176 	  config_file[127] = '\0';
177 	  break;
178 
179 	case OPT_INSTALL_PARTITION:
180 	  install_partition = strtoul (optarg, 0, 0);
181 	  if (install_partition == ULONG_MAX)
182 	    {
183 	      perror ("strtoul");
184 	      exit (1);
185 	    }
186 	  break;
187 
188 	case OPT_BOOT_DRIVE:
189 	  boot_drive = strtoul (optarg, 0, 0);
190 	  if (boot_drive == ULONG_MAX)
191 	    {
192 	      perror ("strtoul");
193 	      exit (1);
194 	    }
195 	  break;
196 
197 	case OPT_NO_CONFIG_FILE:
198 	  use_config_file = 0;
199 	  break;
200 
201 	case OPT_NO_CURSES:
202 	  use_curses = 0;
203 	  break;
204 
205 	case OPT_NO_PAGER:
206 	  use_pager = 0;
207 	  break;
208 
209 	case OPT_BATCH:
210 	  /* This is the same as "--no-config-file --no-curses --no-pager".  */
211 	  use_config_file = 0;
212 	  use_curses = 0;
213 	  use_pager = 0;
214 	  break;
215 
216 	case OPT_READ_ONLY:
217 	  read_only = 1;
218 	  break;
219 
220 	case OPT_VERBOSE:
221 	  verbose = 1;
222 	  break;
223 
224 	case OPT_NO_FLOPPY:
225 	  floppy_disks = 0;
226 	  break;
227 
228 	case OPT_PROBE_SECOND_FLOPPY:
229 	  floppy_disks = 2;
230 	  break;
231 
232 	case OPT_DEVICE_MAP:
233 	  device_map_file = strdup (optarg);
234 	  break;
235 
236 	case OPT_PRESET_MENU:
237 	  use_preset_menu = 1;
238 	  break;
239 
240 	default:
241 	  usage (1);
242 	}
243     }
244   while (c != EOF);
245 
246   /* Wait until the HOLD variable is cleared by an attached debugger. */
247   if (hold && verbose)
248     printf ("Run \"gdb %s %d\", and set HOLD to zero.\n",
249 	    program_name, (int) getpid ());
250   while (hold)
251     {
252       if (hold > 0)
253 	hold--;
254 
255       sleep (1);
256     }
257 
258   /* If we don't have curses (!HAVE_LIBCURSES or --no-curses or
259      --batch) put terminal to dumb for better handling of line i/o */
260   if (! use_curses)
261     current_term->flags = TERM_NO_EDIT | TERM_DUMB;
262 
263   /* Transfer control to the stage2 simulator. */
264   exit (grub_stage2 ());
265 }
266