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