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