1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #pragma ident "%Z%%M% %I% %E% SMI"
27
28 /*
29 * This file contains routines relating to running the menus.
30 */
31 #include <string.h>
32 #include "global.h"
33 #include "menu.h"
34 #include "misc.h"
35
36 #ifdef __STDC__
37
38 /* Function prototypes for ANSI C Compilers */
39 static int (*find_enabled_menu_item())(struct menu_item *menu, int item);
40
41 #else /* __STDC__ */
42
43 /* Function prototypes for non-ANSI C Compilers */
44 static int (*find_enabled_menu_item())();
45
46 #endif /* __STDC__ */
47
48 static char cur_title[MAXPATHLEN];
49
50 /*
51 * This routine takes a menu struct and concatenates the
52 * command names into an array of strings describing the menu.
53 * All menus have a 'quit' command at the bottom to exit the menu.
54 */
55 char **
create_menu_list(menu)56 create_menu_list(menu)
57 struct menu_item *menu;
58 {
59 register struct menu_item *mptr;
60 register char **cpptr;
61 register char **list;
62 int nitems;
63
64 /*
65 * A minimum list consists of the quit command, followed
66 * by a terminating null.
67 */
68 nitems = 2;
69 /*
70 * Count the number of active commands in the menu and allocate
71 * space for the array of pointers.
72 */
73 for (mptr = menu; mptr->menu_cmd != NULL; mptr++) {
74 if ((*mptr->menu_state)())
75 nitems++;
76 }
77 list = (char **)zalloc(nitems * sizeof (char *));
78 cpptr = list;
79 /*
80 * Fill in the array with the names of the menu commands.
81 */
82 for (mptr = menu; mptr->menu_cmd != NULL; mptr++) {
83 if ((*mptr->menu_state)()) {
84 *cpptr++ = mptr->menu_cmd;
85 }
86 }
87 /*
88 * Add the 'quit' command to the end.
89 */
90 *cpptr = "quit";
91 return (list);
92 }
93
94 /*
95 * This routine takes a menu list created by the above routine and
96 * prints it nicely on the screen.
97 */
98 void
display_menu_list(list)99 display_menu_list(list)
100 char **list;
101 {
102 register char **str;
103
104 for (str = list; *str != NULL; str++)
105 fmt_print(" %s\n", *str);
106 }
107
108 /*
109 * Find the "i"th enabled menu in a menu list. This depends
110 * on menu_state() returning the same status as when the
111 * original list of enabled commands was constructed.
112 */
113 static int (*
114 find_enabled_menu_item(menu, item))()
115 struct menu_item *menu;
116 int item;
117 {
118 struct menu_item *mp;
119
120 for (mp = menu; mp->menu_cmd != NULL; mp++) {
121 if ((*mp->menu_state)()) {
122 if (item-- == 0) {
123 return (mp->menu_func);
124 }
125 }
126 }
127
128 return (NULL);
129 }
130
131 /*
132 * This routine 'runs' a menu. It repeatedly requests a command and
133 * executes the command chosen. It exits when the 'quit' command is
134 * executed.
135 */
136 /*ARGSUSED*/
137 void
run_menu(menu,title,prompt,display_flag)138 run_menu(menu, title, prompt, display_flag)
139 struct menu_item *menu;
140 char *title;
141 char *prompt;
142 int display_flag;
143 {
144 char **list;
145 int i;
146 struct env env;
147 u_ioparam_t ioparam;
148 int (*f)();
149
150
151 /*
152 * Create the menu list and display it.
153 */
154 list = create_menu_list(menu);
155 (void) strcpy(cur_title, title);
156 fmt_print("\n\n%s MENU:\n", title);
157 display_menu_list(list);
158 /*
159 * Save the environment so a ctrl-C out of a command lands here.
160 */
161 saveenv(env);
162 for (;;) {
163 /*
164 * Ask the user which command they want to run.
165 */
166 ioparam.io_charlist = list;
167 i = input(FIO_MSTR, prompt, '>', &ioparam,
168 (int *)NULL, CMD_INPUT);
169 /*
170 * If they choose 'quit', the party's over.
171 */
172 if ((f = find_enabled_menu_item(menu, i)) == NULL)
173 break;
174
175 /*
176 * Mark the saved environment active so the user can now
177 * do a ctrl-C to get out of the command.
178 */
179 useenv();
180 /*
181 * Run the command. If it returns an error and we are
182 * running out of a command file, the party's really over.
183 */
184 if ((*f)() && option_f)
185 fullabort();
186 /*
187 * Mark the saved environment inactive so ctrl-C doesn't
188 * work at the menu itself.
189 */
190 unuseenv();
191 /*
192 * Since menu items are dynamic, some commands
193 * cause changes to occur. Destroy the old menu,
194 * and rebuild it, so we're always up-to-date.
195 */
196 destroy_data((char *)list);
197 list = create_menu_list(menu);
198 /*
199 * Redisplay menu, if we're returning to this one.
200 */
201 if (cur_menu != last_menu) {
202 last_menu = cur_menu;
203 (void) strcpy(cur_title, title);
204 fmt_print("\n\n%s MENU:\n", title);
205 display_menu_list(list);
206 }
207 }
208 /*
209 * Clean up the environment stack and throw away the menu list.
210 */
211 clearenv();
212 destroy_data((char *)list);
213 }
214
215 /*
216 * re-display the screen after exiting from shell escape
217 *
218 */
219 void
redisplay_menu_list(list)220 redisplay_menu_list(list)
221 char **list;
222 {
223 fmt_print("\n\n%s MENU:\n", cur_title);
224 display_menu_list(list);
225 }
226
227
228 /*
229 * Glue to always return true. Used for menu items which
230 * are always enabled.
231 */
232 int
233 true()
234 {
235 return (1);
236 }
237
238 /*
239 * Note: The following functions are used to enable the inclusion
240 * of device specific options (see init_menus.c). But when we are
241 * running non interactively with commands taken from a script file,
242 * current disk (cur_disk, cur_type, cur_ctype) may not be defined.
243 * They get defined when the script selects a disk using "disk" option
244 * in the main menu. However, in the normal interactive mode, the disk
245 * selection happens before entering the main menu.
246 */
247 /*
248 * Return true for menu items enabled only for embedded SCSI controllers
249 */
250 int
embedded_scsi()251 embedded_scsi()
252 {
253 if (cur_ctype == NULL && option_f)
254 return (0);
255 return (EMBEDDED_SCSI);
256 }
257
258 /*
259 * Return false for menu items disabled only for embedded SCSI controllers
260 */
261 int
not_embedded_scsi()262 not_embedded_scsi()
263 {
264 if (cur_ctype == NULL && option_f)
265 return (0);
266 return (!EMBEDDED_SCSI);
267 }
268
269 /*
270 * Return false for menu items disabled for scsi controllers
271 */
272 int
not_scsi()273 not_scsi()
274 {
275 if (cur_ctype == NULL && option_f)
276 return (0);
277 return (!SCSI);
278 }
279
280 /*
281 * Return false for menu items disabled for efi labels
282 */
283 int
not_efi()284 not_efi()
285 {
286 if ((cur_disk == NULL) && option_f)
287 return (0);
288 if (cur_disk->label_type == L_TYPE_EFI)
289 return (0);
290 return (1);
291 }
292
293 int
disp_expert_change_expert_efi()294 disp_expert_change_expert_efi()
295 {
296 if ((cur_disk == NULL) && option_f)
297 return (0);
298 if ((cur_disk->label_type == L_TYPE_EFI) && expert_mode)
299 return (1);
300 if (cur_disk->label_type != L_TYPE_EFI)
301 return (1);
302 return (0);
303 }
304
305 int
disp_expand_efi()306 disp_expand_efi()
307 {
308 if ((cur_disk == NULL) && option_f)
309 return (0);
310 if (cur_disk->label_type != L_TYPE_EFI)
311 return (0);
312 if (cur_parts == NULL)
313 return (0);
314 return (1);
315 }
316
317 int
disp_all_change_expert_efi()318 disp_all_change_expert_efi()
319 {
320 if ((cur_disk == NULL) && option_f)
321 return (0);
322 if ((cur_disk->label_type != L_TYPE_EFI) || (!expert_mode))
323 return (0);
324 return (1);
325 }
326
327 /*
328 * Return true for menu items enabled scsi controllers
329 */
330 int
scsi()331 scsi()
332 {
333 if (cur_ctype == NULL && option_f)
334 return (0);
335 return (SCSI);
336 }
337
338
339 /*
340 * Return true for menu items enabled if expert mode is enabled
341 */
342 int
scsi_expert()343 scsi_expert()
344 {
345 if (cur_ctype == NULL && option_f)
346 return (0);
347 return (SCSI && expert_mode);
348 }
349
350 #if defined(i386)
351 /*
352 * Return true for menu items enabled if expert mode is enabled
353 */
354 int
expert()355 expert()
356 {
357 return (expert_mode);
358 }
359 #endif /* defined(i386) */
360
361 /*
362 * Return true for menu items enabled if developer mode is enabled
363 */
364 int
developer()365 developer()
366 {
367 return (dev_expert);
368 }
369
370 /*
371 * For x86, always return true for menu items enabled
372 * since fdisk is already supported on these two platforms.
373 * For Sparc, only return true for menu items enabled
374 * if a PCATA disk is selected.
375 */
376 int
support_fdisk_on_sparc()377 support_fdisk_on_sparc()
378 {
379 #if defined(sparc)
380 /*
381 * If it's a SCSI disk then we don't support fdisk and we
382 * don't need to know the type cause we can ask the disk,
383 * therefore we return true only if we *KNOW* it's an ATA
384 * disk.
385 */
386 if (cur_ctype && cur_ctype->ctype_ctype == DKC_PCMCIA_ATA) {
387 return (1);
388 } else {
389 return (0);
390 }
391 #elif defined(i386)
392 return (1);
393 #else
394 #error No Platform defined
395 #endif /* defined(sparc) */
396
397 }
398