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 **/
cli_clear_screen(int argc __unused,char ** argv __unused,struct s_hardware * hardware __unused)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 **/
main_show_modes(int argc __unused,char ** argv __unused,struct s_hardware * hardware __unused)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 **/
cli_set_mode(int argc,char ** argv,struct s_hardware * hardware)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 **/
do_exit(int argc __unused,char ** argv __unused,struct s_hardware * hardware)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 **/
show_cli_help(int argc __unused,char ** argv __unused,struct s_hardware * hardware __unused)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 **/
goto_menu(int argc __unused,char ** argv __unused,struct s_hardware * hardware)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 **/
main_show_summary(int argc __unused,char ** argv __unused,struct s_hardware * hardware)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
main_show_hdt(int argc __unused,char ** argv __unused,struct s_hardware * hardware __unused)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 **/
do_reboot(int argc __unused,char ** argv __unused,struct s_hardware * hardware)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 **/
do_dump(int argc __unused,char ** argv __unused,struct s_hardware * hardware)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 **/
do_sleep(int argc,char ** argv,struct s_hardware * hardware)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 **/
do_display(int argc,char ** argv,struct s_hardware * hardware)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 **/
do_say(int argc,char ** argv,struct s_hardware * hardware)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