xref: /illumos-gate/usr/src/cmd/format/menu.c (revision 9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829)
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 **
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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