1 /* ----------------------------------------------------------------------- * 2 * 3 * Copyright 2009 Pierre-Alexandre Meyer - All Rights Reserved 4 * 5 * Permission is hereby granted, free of charge, to any person 6 * obtaining a copy of this software and associated documentation 7 * files (the "Software"), to deal in the Software without 8 * restriction, including without limitation the rights to use, 9 * copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Software, and to permit persons to whom 11 * the Software is furnished to do so, subject to the following 12 * conditions: 13 * 14 * The above copyright notice and this permission notice shall 15 * be included in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 * OTHER DEALINGS IN THE SOFTWARE. 25 * 26 * ----------------------------------------------------------------------- 27 */ 28 29 #include <stdio.h> 30 #include <string.h> 31 #include <stdlib.h> 32 #include <syslinux/config.h> 33 #include <syslinux/reboot.h> 34 35 #include "hdt-menu.h" 36 #include "hdt-cli.h" 37 #include "hdt-common.h" 38 39 /** 40 * cli_clear_screen - clear (erase) the entire screen 41 **/ 42 static void cli_clear_screen(int argc __unused, char **argv __unused, 43 struct s_hardware *hardware __unused) 44 { 45 clear_screen(); 46 } 47 48 /** 49 * main_show_modes - show availables modes 50 **/ 51 static void main_show_modes(int argc __unused, char **argv __unused, 52 struct s_hardware *hardware __unused) 53 { 54 int i = 0; 55 56 reset_more_printf(); 57 more_printf("Available modes:\n"); 58 while (list_modes[i]) { 59 printf("%s ", list_modes[i]->name); 60 i++; 61 } 62 more_printf("\n"); 63 } 64 65 /** 66 * cli_set_mode - set the mode of the cli, in the cli 67 * 68 * The mode number must be supplied in argv, position 0. 69 **/ 70 static void cli_set_mode(int argc, char **argv, struct s_hardware *hardware) 71 { 72 cli_mode_t new_mode; 73 74 reset_more_printf(); 75 if (argc <= 0) { 76 more_printf("Which mode?\n"); 77 return; 78 } 79 80 /* 81 * Note! argv[0] is a string representing the mode, we need the 82 * equivalent cli_mode_t to pass it to set_mode. 83 */ 84 new_mode = mode_s_to_mode_t(argv[0]); 85 set_mode(new_mode, hardware); 86 } 87 88 /** 89 * do_exit - shared helper to exit a mode 90 **/ 91 static void do_exit(int argc __unused, char **argv __unused, 92 struct s_hardware *hardware) 93 { 94 int new_mode = HDT_MODE; 95 96 switch (hdt_cli.mode) { 97 case HDT_MODE: 98 new_mode = EXIT_MODE; 99 break; 100 default: 101 new_mode = HDT_MODE; 102 break; 103 } 104 105 dprintf("CLI DEBUG: Switching from mode %d to mode %d\n", hdt_cli.mode, 106 new_mode); 107 set_mode(new_mode, hardware); 108 } 109 110 /** 111 * show_cli_help - shared helper to show available commands 112 **/ 113 static void show_cli_help(int argc __unused, char **argv __unused, 114 struct s_hardware *hardware __unused) 115 { 116 int j = 0; 117 struct cli_mode_descr *current_mode; 118 struct cli_callback_descr *associated_module = NULL; 119 120 find_cli_mode_descr(hdt_cli.mode, ¤t_mode); 121 122 more_printf("Available commands are:\n"); 123 124 /* List first default modules of the mode */ 125 if (current_mode->default_modules && current_mode->default_modules->modules) { 126 while (current_mode->default_modules->modules[j].name) { 127 printf("%s ", current_mode->default_modules->modules[j].name); 128 j++; 129 } 130 printf("\n"); 131 } 132 133 /* List finally the default modules of the hdt mode */ 134 if (current_mode->mode != hdt_mode.mode && 135 hdt_mode.default_modules && hdt_mode.default_modules->modules) { 136 j = 0; 137 while (hdt_mode.default_modules->modules[j].name) { 138 /* 139 * Any default command that is present in hdt mode but 140 * not in the current mode is available. A default 141 * command can be redefined in the current mode though. 142 * This next call test this use case: if it is 143 * overwritten, do not print it again. 144 */ 145 find_cli_callback_descr(hdt_mode.default_modules->modules[j].name, 146 current_mode->default_modules, 147 &associated_module); 148 if (associated_module == NULL) 149 printf("%s ", hdt_mode.default_modules->modules[j].name); 150 j++; 151 } 152 printf("\n"); 153 } 154 155 /* List secondly the show modules of the mode */ 156 if (current_mode->show_modules && current_mode->show_modules->modules) { 157 more_printf("\nshow commands:\n"); 158 j = 0; 159 while (current_mode->show_modules->modules[j].name) { 160 printf("%s ", current_mode->show_modules->modules[j].name); 161 j++; 162 } 163 printf("\n"); 164 } 165 166 /* List thirdly the set modules of the mode */ 167 if (current_mode->set_modules && current_mode->set_modules->modules) { 168 more_printf("\nset commands:\n"); 169 j = 0; 170 while (current_mode->set_modules->modules[j].name) { 171 printf("%s ", current_mode->set_modules->modules[j].name); 172 j++; 173 } 174 printf("\n"); 175 } 176 177 178 printf("\n"); 179 main_show_modes(argc, argv, hardware); 180 } 181 182 /** 183 * show_cli_help - shared helper to show available commands 184 **/ 185 static void goto_menu(int argc __unused, char **argv __unused, 186 struct s_hardware *hardware) 187 { 188 char version_string[256]; 189 snprintf(version_string, sizeof version_string, "%s %s (%s)", 190 PRODUCT_NAME, VERSION, CODENAME); 191 start_menu_mode(hardware, version_string); 192 return; 193 } 194 195 /** 196 * main_show_summary - give an overview of the system 197 **/ 198 void main_show_summary(int argc __unused, char **argv __unused, 199 struct s_hardware *hardware) 200 { 201 reset_more_printf(); 202 clear_screen(); 203 main_show_cpu(argc, argv, hardware); 204 if (hardware->is_dmi_valid) { 205 more_printf("System\n"); 206 more_printf(" Manufacturer : %s\n", hardware->dmi.system.manufacturer); 207 more_printf(" Product Name : %s\n", hardware->dmi.system.product_name); 208 more_printf(" Serial : %s\n", hardware->dmi.system.serial); 209 more_printf("Bios\n"); 210 more_printf(" Version : %s\n", hardware->dmi.bios.version); 211 more_printf(" Release : %s\n", hardware->dmi.bios.release_date); 212 more_printf("Memory Size : %lu MB (%lu KB)\n", 213 (hardware->detected_memory_size + (1 << 9)) >> 10, 214 hardware->detected_memory_size); 215 } 216 main_show_pci(argc, argv, hardware); 217 218 if (hardware->is_pxe_valid) 219 main_show_pxe(argc, argv, hardware); 220 221 main_show_kernel(argc, argv, hardware); 222 } 223 224 void main_show_hdt(int argc __unused, char **argv __unused, 225 struct s_hardware *hardware __unused) 226 { 227 reset_more_printf(); 228 more_printf("HDT\n"); 229 more_printf(" Product : %s\n", PRODUCT_NAME); 230 more_printf(" Version : %s (%s)\n", VERSION, CODENAME); 231 more_printf(" Website : %s\n", WEBSITE_URL); 232 more_printf(" IRC Channel : %s\n", IRC_CHANNEL); 233 more_printf(" Mailing List : %s\n", CONTACT); 234 more_printf(" Project Leader : %s\n", AUTHOR); 235 more_printf(" Core Developer : %s\n", CORE_DEVELOPER); 236 char *contributors[NB_CONTRIBUTORS] = CONTRIBUTORS; 237 for (int c = 0; c < NB_CONTRIBUTORS; c++) { 238 more_printf(" Contributor : %s\n", contributors[c]); 239 } 240 } 241 242 /** 243 * do_reboot - reboot the system 244 **/ 245 static void do_reboot(int argc __unused, char **argv __unused, 246 struct s_hardware *hardware) 247 { 248 (void) hardware; 249 /* Let's call the internal rebooting call */ 250 syslinux_reboot(1); 251 } 252 253 /** 254 * do_dump - dump info 255 **/ 256 static void do_dump(int argc __unused, char **argv __unused, 257 struct s_hardware *hardware) 258 { 259 dump(hardware); 260 } 261 262 /** 263 * do_sleep - sleep a number of milliseconds 264 **/ 265 static void do_sleep(int argc , char **argv , 266 struct s_hardware *hardware) 267 { 268 (void) hardware; 269 if (argc != 1) return; 270 more_printf("Sleep %d milliseconds\n",atoi(argv[0])); 271 msleep(atoi(argv[0])); 272 } 273 274 /** 275 * do_display - display an image to user 276 **/ 277 static void do_display(int argc , char **argv , 278 struct s_hardware *hardware) 279 { 280 (void) hardware; 281 if ((argc != 1) || (vesamode == false)) return; 282 more_printf("Display %s file\n",argv[0]); 283 vesacon_load_background(argv[0]); 284 } 285 286 /** 287 * do_say - say message to user 288 **/ 289 static void do_say(int argc , char **argv , 290 struct s_hardware *hardware) 291 { 292 (void) hardware; 293 if (argc == 0) return; 294 295 char text_to_say[255]={0}; 296 int arg=0; 297 #if DEBUG 298 for (int i=0; i<argc;i++) dprintf("SAY: arg[%d]={%s}\n",i,argv[i]); 299 #endif 300 char *argument = strchr(argv[arg],'`'); 301 if ( argument != NULL) { 302 argument++; 303 strcat(text_to_say, argument); 304 305 while ((strchr(argument, '`') == NULL) && (arg+1<argc)) { 306 arg++; 307 argument = (char *)argv[arg]; 308 strcat(text_to_say, " "); 309 strcat(text_to_say, argument); 310 } 311 312 /* Removing last ` if any */ 313 char *last_quote = strrchr(text_to_say,'`'); 314 if ( last_quote != NULL ) { 315 *last_quote='\0'; 316 dprintf("SAY CMD = [%s]\n",text_to_say); 317 } 318 319 more_printf("%s\n",text_to_say); 320 } 321 } 322 323 /* Default hdt mode */ 324 struct cli_callback_descr list_hdt_default_modules[] = { 325 { 326 .name = CLI_CLEAR, 327 .exec = cli_clear_screen, 328 .nomodule = false, 329 }, 330 { 331 .name = CLI_EXIT, 332 .exec = do_exit, 333 .nomodule = false, 334 }, 335 { 336 .name = CLI_HELP, 337 .exec = show_cli_help, 338 .nomodule = false, 339 }, 340 { 341 .name = CLI_MENU, 342 .exec = goto_menu, 343 .nomodule = false, 344 }, 345 { 346 .name = CLI_REBOOT, 347 .exec = do_reboot, 348 .nomodule = false, 349 }, 350 { 351 .name = CLI_HISTORY, 352 .exec = print_history, 353 .nomodule = false, 354 }, 355 { 356 .name = CLI_DUMP, 357 .exec = do_dump, 358 .nomodule = false, 359 }, 360 { 361 .name = CLI_SAY, 362 .exec = do_say, 363 .nomodule = true, 364 }, 365 { 366 .name = CLI_DISPLAY, 367 .exec = do_display, 368 .nomodule = true, 369 }, 370 { 371 .name = CLI_SLEEP, 372 .exec = do_sleep, 373 .nomodule = true, 374 }, 375 { 376 .name = NULL, 377 .exec = NULL, 378 .nomodule = false}, 379 }; 380 381 struct cli_callback_descr list_hdt_show_modules[] = { 382 { 383 .name = CLI_SUMMARY, 384 .exec = main_show_summary, 385 .nomodule = false, 386 }, 387 { 388 .name = CLI_PCI, 389 .exec = main_show_pci, 390 .nomodule = false, 391 }, 392 { 393 .name = CLI_DMI, 394 .exec = main_show_dmi, 395 .nomodule = false, 396 }, 397 { 398 .name = CLI_CPU, 399 .exec = main_show_cpu, 400 .nomodule = false, 401 }, 402 { 403 .name = CLI_DISK, 404 .exec = disks_summary, 405 .nomodule = false, 406 }, 407 { 408 .name = CLI_PXE, 409 .exec = main_show_pxe, 410 .nomodule = false, 411 }, 412 { 413 .name = CLI_SYSLINUX, 414 .exec = main_show_syslinux, 415 .nomodule = false, 416 }, 417 { 418 .name = CLI_KERNEL, 419 .exec = main_show_kernel, 420 .nomodule = false, 421 }, 422 { 423 .name = CLI_VESA, 424 .exec = main_show_vesa, 425 .nomodule = false, 426 }, 427 { 428 .name = CLI_HDT, 429 .exec = main_show_hdt, 430 .nomodule = false, 431 }, 432 { 433 .name = CLI_VPD, 434 .exec = main_show_vpd, 435 .nomodule = false, 436 }, 437 { 438 .name = CLI_MEMORY, 439 .exec = show_dmi_memory_modules, 440 .nomodule = false, 441 }, 442 { 443 .name = CLI_ACPI, 444 .exec = main_show_acpi, 445 .nomodule = false, 446 }, 447 { 448 .name = "modes", 449 .exec = main_show_modes, 450 .nomodule = false, 451 }, 452 { 453 .name = NULL, 454 .exec = NULL, 455 .nomodule = false, 456 }, 457 }; 458 459 struct cli_callback_descr list_hdt_set_modules[] = { 460 { 461 .name = CLI_MODE, 462 .exec = cli_set_mode, 463 .nomodule = false, 464 }, 465 { 466 .name = NULL, 467 .exec = NULL, 468 .nomodule = false, 469 }, 470 }; 471 472 struct cli_module_descr hdt_default_modules = { 473 .modules = list_hdt_default_modules, 474 }; 475 476 struct cli_module_descr hdt_show_modules = { 477 .modules = list_hdt_show_modules, 478 .default_callback = main_show_summary, 479 }; 480 481 struct cli_module_descr hdt_set_modules = { 482 .modules = list_hdt_set_modules, 483 }; 484 485 struct cli_mode_descr hdt_mode = { 486 .mode = HDT_MODE, 487 .name = CLI_HDT, 488 .default_modules = &hdt_default_modules, 489 .show_modules = &hdt_show_modules, 490 .set_modules = &hdt_set_modules, 491 }; 492