hdt: fix precedence problem in double-space check
[syslinux.git] / com32 / hdt / hdt-common.c
blobf475399c95b728393c093f1d0231188968bf1113
1 /* ----------------------------------------------------------------------- *
3 * Copyright 2009 Erwan Velu - All Rights Reserved
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:
14 * The above copyright notice and this permission notice shall
15 * be included in all copies or substantial portions of the Software.
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.
26 * -----------------------------------------------------------------------
29 #include <stdlib.h>
30 #include <string.h>
31 #include <stdio.h>
32 #include <getkey.h>
33 #include "syslinux/config.h"
34 #include "../lib/sys/vesa/vesa.h"
35 #include "hdt-common.h"
36 #include <disk/util.h>
37 #include <disk/mbrs.h>
38 #include <memory.h>
40 /* ISOlinux requires a 8.3 format */
41 void convert_isolinux_filename(char *filename, struct s_hardware *hardware)
43 /* Exit if we are not running ISOLINUX */
44 if (hardware->sv->filesystem != SYSLINUX_FS_ISOLINUX)
45 return;
46 /* Searching the dot */
47 char *dot = strchr(filename, '.');
48 /* Exiting if no dot exists in that string */
49 if (dot == NULL)
50 return;
51 /* Exiting if the extension is 3 char or less */
52 if (strlen(dot) <= 4)
53 return;
55 /* We have an extension bigger than .blah
56 * so we have to shorten it to 3*/
57 dot[4] = '\0';
60 void detect_parameters(const int argc, const char *argv[],
61 struct s_hardware *hardware)
63 /* Quiet mode - make the output more quiet */
64 quiet = true;
66 /* Vesa mode isn't set until we explictly call it */
67 vesamode = false;
69 /* Automode isn't the default*/
70 automode = false;
72 /* Menu mode is the default*/
73 menumode = true;
75 for (int i = 1; i < argc; i++) {
76 if (!strncmp(argv[i], "quiet", 5)) {
77 quiet = true;
78 } else if (!strncmp(argv[i], "verbose", 7)) {
79 quiet = false;
80 } else if (!strncmp(argv[i], "modules_pcimap=", 15)) {
81 strlcpy(hardware->modules_pcimap_path, argv[i] + 15,
82 sizeof(hardware->modules_pcimap_path));
83 convert_isolinux_filename(hardware->modules_pcimap_path, hardware);
84 } else if (!strncmp(argv[i], "pciids=", 7)) {
85 strlcpy(hardware->pciids_path, argv[i] + 7,
86 sizeof(hardware->pciids_path));
87 convert_isolinux_filename(hardware->pciids_path, hardware);
88 } else if (!strncmp(argv[i], "modules_alias=", 14)) {
89 strlcpy(hardware->modules_alias_path, argv[i] + 14,
90 sizeof(hardware->modules_alias_path));
91 convert_isolinux_filename(hardware->modules_alias_path, hardware);
92 } else if (!strncmp(argv[i], "memtest=", 8)) {
93 strlcpy(hardware->memtest_label, argv[i] + 8,
94 sizeof(hardware->memtest_label));
95 convert_isolinux_filename(hardware->memtest_label, hardware);
96 } else if (!strncmp(argv[i], "vesa", 4)) {
97 vesamode = true;
98 max_console_lines = MAX_VESA_CLI_LINES;
99 /* If the user defines a background image */
100 if (!strncmp(argv[i], "vesa=", 5)) {
101 strlcpy(hardware->vesa_background, argv[i] + 5,
102 sizeof(hardware->vesa_background));
104 } else if (!strncmp(argv[i], "novesa", 6)) {
105 vesamode = false;
106 max_console_lines = MAX_CLI_LINES;
107 } else if (!strncmp(argv[i], "nomenu", 6)) {
108 menumode = false;
109 } else if (!strncmp(argv[i], "dump_path=", 10)) {
110 strlcpy(hardware->dump_path, argv[i] + 10,
111 sizeof(hardware->dump_path));
112 } else if (!strncmp(argv[i], "tftp_ip=", 8)) {
113 strlcpy(hardware->tftp_ip, argv[i] + 8,
114 sizeof(hardware->tftp_ip));
115 } else if (!strncmp(argv[i], "auto=", 5)) {
116 /* The auto= parameter is separated in several argv[]
117 * as it can contains spaces.
118 * We use the AUTO_DELIMITER char to define the limits
119 * of this parameter.
120 * i.e auto='show dmi; show pci'
123 automode=true;
124 /* Extracting the first parameter */
125 strcpy(hardware->auto_label, argv[i] + 6);
126 strcat(hardware->auto_label, " ");
127 char *pos;
128 i++;
130 /* While we can't find the other AUTO_DELIMITER, let's process the argv[] */
131 while (((pos = strstr(argv[i], AUTO_DELIMITER)) == NULL)
132 && (i < argc)) {
133 strcat(hardware->auto_label, argv[i]);
134 strcat(hardware->auto_label, " ");
135 i++;
138 /* If we didn't reach the end of the line, let's grab the last item */
139 if (i < argc) {
140 strcat(hardware->auto_label, argv[i]);
141 hardware->auto_label[strlen(hardware->auto_label) - 1] = 0;
147 void detect_syslinux(struct s_hardware *hardware)
149 hardware->sv = syslinux_version();
150 switch (hardware->sv->filesystem) {
151 case SYSLINUX_FS_SYSLINUX:
152 strlcpy(hardware->syslinux_fs, "SYSlinux", 9);
153 break;
154 case SYSLINUX_FS_PXELINUX:
155 strlcpy(hardware->syslinux_fs, "PXElinux", 9);
156 break;
157 case SYSLINUX_FS_ISOLINUX:
158 strlcpy(hardware->syslinux_fs, "ISOlinux", 9);
159 break;
160 case SYSLINUX_FS_EXTLINUX:
161 strlcpy(hardware->syslinux_fs, "EXTlinux", 9);
162 break;
163 case SYSLINUX_FS_UNKNOWN:
164 default:
165 strlcpy(hardware->syslinux_fs, "Unknown Bootloader",
166 sizeof hardware->syslinux_fs);
167 break;
171 void init_hardware(struct s_hardware *hardware)
173 hardware->pci_ids_return_code = 0;
174 hardware->modules_pcimap_return_code = 0;
175 hardware->modules_alias_return_code = 0;
176 hardware->cpu_detection = false;
177 hardware->pci_detection = false;
178 hardware->disk_detection = false;
179 hardware->disks_count = 0;
180 hardware->dmi_detection = false;
181 hardware->pxe_detection = false;
182 hardware->vesa_detection = false;
183 hardware->vpd_detection = false;
184 hardware->memory_detection = false;
185 hardware->acpi_detection = false;
186 hardware->nb_pci_devices = 0;
187 hardware->is_dmi_valid = false;
188 hardware->is_pxe_valid = false;
189 hardware->is_vpd_valid = false;
190 hardware->is_acpi_valid = false;
191 hardware->pci_domain = NULL;
192 hardware->detected_memory_size = 0;
193 hardware->physical_cpu_count =1; /* we have at least one cpu */
195 /* Cleaning structures */
196 memset(hardware->disk_info, 0, sizeof(hardware->disk_info));
197 memset(hardware->mbr_ids, 0, sizeof(hardware->mbr_ids));
198 memset(&hardware->dmi, 0, sizeof(s_dmi));
199 memset(&hardware->cpu, 0, sizeof(s_cpu));
200 memset(&hardware->pxe, 0, sizeof(struct s_pxe));
201 memset(&hardware->vesa, 0, sizeof(struct s_vesa));
202 memset(&hardware->vpd, 0, sizeof(s_vpd));
203 memset(&hardware->acpi, 0, sizeof(s_acpi));
204 memset(hardware->syslinux_fs, 0, sizeof hardware->syslinux_fs);
205 memset(hardware->pciids_path, 0, sizeof hardware->pciids_path);
206 memset(hardware->modules_pcimap_path, 0,
207 sizeof hardware->modules_pcimap_path);
208 memset(hardware->modules_alias_path, 0,
209 sizeof hardware->modules_alias_path);
210 memset(hardware->memtest_label, 0, sizeof hardware->memtest_label);
211 memset(hardware->auto_label, 0, sizeof hardware->auto_label);
212 memset(hardware->dump_path, 0, sizeof hardware->dump_path);
213 memset(hardware->vesa_background, 0, sizeof hardware->vesa_background);
214 memset(hardware->tftp_ip, 0, sizeof hardware->tftp_ip);
215 strcat(hardware->dump_path, "hdt");
216 strcat(hardware->pciids_path, "pci.ids");
217 strcat(hardware->modules_pcimap_path, "modules.pcimap");
218 strcat(hardware->modules_alias_path, "modules.alias");
219 strcat(hardware->memtest_label, "memtest");
220 strlcpy(hardware->vesa_background, CLI_DEFAULT_BACKGROUND,
221 sizeof(hardware->vesa_background));
225 * Detecting if a DMI table exist
226 * if yes, let's parse it
228 int detect_dmi(struct s_hardware *hardware)
230 if (hardware->dmi_detection == true)
231 return -1;
232 hardware->dmi_detection = true;
233 if (dmi_iterate(&hardware->dmi) == -ENODMITABLE) {
234 hardware->is_dmi_valid = false;
235 return -ENODMITABLE;
238 parse_dmitable(&hardware->dmi);
239 hardware->is_dmi_valid = true;
240 return 0;
244 * Detecting ACPI
245 * if yes, let's parse it
247 int detect_acpi(struct s_hardware *hardware)
249 int retval;
250 if (hardware->acpi_detection == true)
251 return -1;
252 hardware->acpi_detection = true;
253 if ((retval=parse_acpi(&hardware->acpi)) != ACPI_FOUND) {
254 hardware->is_acpi_valid = false;
255 return retval;
258 hardware->is_acpi_valid = true;
259 return retval;
263 * vpd_detection - populate the VPD structure
265 * VPD is a structure available on IBM machines.
266 * It is documented at:
267 * http://www.pc.ibm.com/qtechinfo/MIGR-45120.html
268 * (XXX the page seems to be gone)
270 int detect_vpd(struct s_hardware *hardware)
272 if (hardware->vpd_detection)
273 return -1;
274 else
275 hardware->vpd_detection = true;
277 if (vpd_decode(&hardware->vpd) == -ENOVPDTABLE) {
278 hardware->is_vpd_valid = false;
279 return -ENOVPDTABLE;
280 } else {
281 hardware->is_vpd_valid = true;
282 return 0;
286 /* Detection vesa stuff*/
287 int detect_vesa(struct s_hardware *hardware)
289 static com32sys_t rm;
290 struct vesa_general_info *gi;
291 struct vesa_mode_info *mi;
292 uint16_t mode, *mode_ptr;
293 char *oem_ptr;
295 if (hardware->vesa_detection == true)
296 return -1;
298 hardware->vesa_detection = true;
299 hardware->is_vesa_valid = false;
301 /* Allocate space in the bounce buffer for these structures */
302 gi = &((struct vesa_info *)__com32.cs_bounce)->gi;
303 mi = &((struct vesa_info *)__com32.cs_bounce)->mi;
305 gi->signature = VBE2_MAGIC; /* Get VBE2 extended data */
306 rm.eax.w[0] = 0x4F00; /* Get SVGA general information */
307 rm.edi.w[0] = OFFS(gi);
308 rm.es = SEG(gi);
309 __intcall(0x10, &rm, &rm);
311 if (rm.eax.w[0] != 0x004F) {
312 return -1;
315 mode_ptr = GET_PTR(gi->video_mode_ptr);
316 oem_ptr = GET_PTR(gi->oem_vendor_name_ptr);
317 strlcpy(hardware->vesa.vendor, oem_ptr, sizeof(hardware->vesa.vendor));
318 oem_ptr = GET_PTR(gi->oem_product_name_ptr);
319 strlcpy(hardware->vesa.product, oem_ptr, sizeof(hardware->vesa.product));
320 oem_ptr = GET_PTR(gi->oem_product_rev_ptr);
321 strlcpy(hardware->vesa.product_revision, oem_ptr,
322 sizeof(hardware->vesa.product_revision));
324 hardware->vesa.major_version = (gi->version >> 8) & 0xff;
325 hardware->vesa.minor_version = gi->version & 0xff;
326 hardware->vesa.total_memory = gi->total_memory;
327 hardware->vesa.software_rev = gi->oem_software_rev;
329 hardware->vesa.vmi_count = 0;
331 while ((mode = *mode_ptr++) != 0xFFFF) {
333 rm.eax.w[0] = 0x4F01; /* Get SVGA mode information */
334 rm.ecx.w[0] = mode;
335 rm.edi.w[0] = OFFS(mi);
336 rm.es = SEG(mi);
337 __intcall(0x10, &rm, &rm);
339 /* Must be a supported mode */
340 if (rm.eax.w[0] != 0x004f)
341 continue;
343 /* Saving detected values */
344 memcpy(&hardware->vesa.vmi[hardware->vesa.vmi_count].mi, mi,
345 sizeof(struct vesa_mode_info));
346 hardware->vesa.vmi[hardware->vesa.vmi_count].mode = mode;
348 hardware->vesa.vmi_count++;
350 hardware->is_vesa_valid = true;
351 return 0;
354 /* Try to detect disks from port 0x80 to 0xff */
355 void detect_disks(struct s_hardware *hardware)
357 int i = -1;
358 int err;
360 if (hardware->disk_detection)
361 return;
363 hardware->disk_detection = true;
364 for (int drive = 0x80; drive < 0xff; drive++) {
365 i++;
366 hardware->disk_info[i].disk = drive;
367 err = get_drive_parameters(&hardware->disk_info[i]);
370 * Do not print output when drive does not exist or
371 * doesn't support int13 (cdrom, ...)
373 if (err == -1 || !hardware->disk_info[i].cbios)
374 continue;
376 /* Detect MBR */
377 hardware->mbr_ids[i] = get_mbr_id(&hardware->disk_info[i]);
379 hardware->disks_count++;
383 int detect_pxe(struct s_hardware *hardware)
385 void *dhcpdata;
387 size_t dhcplen;
388 t_PXENV_UNDI_GET_NIC_TYPE gnt;
390 if (hardware->pxe_detection == true)
391 return -1;
392 hardware->pxe_detection = true;
393 hardware->is_pxe_valid = false;
394 memset(&gnt, 0, sizeof(t_PXENV_UNDI_GET_NIC_TYPE));
395 memset(&hardware->pxe, 0, sizeof(struct s_pxe));
397 /* This code can only work if pxelinux is loaded */
398 if (hardware->sv->filesystem != SYSLINUX_FS_PXELINUX) {
399 return -1;
401 // printf("PXE: PXElinux detected\n");
402 if (!pxe_get_cached_info(PXENV_PACKET_TYPE_DHCP_ACK, &dhcpdata, &dhcplen)) {
403 pxe_bootp_t *dhcp = &hardware->pxe.dhcpdata;
404 memcpy(&hardware->pxe.dhcpdata, dhcpdata,
405 sizeof(hardware->pxe.dhcpdata));
406 snprintf(hardware->pxe.mac_addr, sizeof(hardware->pxe.mac_addr),
407 "%02x:%02x:%02x:%02x:%02x:%02x", dhcp->CAddr[0],
408 dhcp->CAddr[1], dhcp->CAddr[2], dhcp->CAddr[3],
409 dhcp->CAddr[4], dhcp->CAddr[5]);
411 /* Saving our IP address in a easy format */
412 hardware->pxe.ip_addr[0] = hardware->pxe.dhcpdata.yip & 0xff;
413 hardware->pxe.ip_addr[1] = hardware->pxe.dhcpdata.yip >> 8 & 0xff;
414 hardware->pxe.ip_addr[2] = hardware->pxe.dhcpdata.yip >> 16 & 0xff;
415 hardware->pxe.ip_addr[3] = hardware->pxe.dhcpdata.yip >> 24 & 0xff;
417 if (!pxe_get_nic_type(&gnt)) {
418 switch (gnt.NicType) {
419 case PCI_NIC:
420 hardware->is_pxe_valid = true;
421 hardware->pxe.vendor_id = gnt.info.pci.Vendor_ID;
422 hardware->pxe.product_id = gnt.info.pci.Dev_ID;
423 hardware->pxe.subvendor_id = gnt.info.pci.SubVendor_ID;
424 hardware->pxe.subproduct_id =
425 gnt.info.pci.SubDevice_ID,
426 hardware->pxe.rev = gnt.info.pci.Rev;
427 hardware->pxe.pci_bus = (gnt.info.pci.BusDevFunc >> 8) & 0xff;
428 hardware->pxe.pci_dev = (gnt.info.pci.BusDevFunc >> 3) & 0x7;
429 hardware->pxe.pci_func = gnt.info.pci.BusDevFunc & 0x03;
430 hardware->pxe.base_class = gnt.info.pci.Base_Class;
431 hardware->pxe.sub_class = gnt.info.pci.Sub_Class;
432 hardware->pxe.prog_intf = gnt.info.pci.Prog_Intf;
433 hardware->pxe.nictype = gnt.NicType;
434 break;
435 case CardBus_NIC:
436 hardware->is_pxe_valid = true;
437 hardware->pxe.vendor_id = gnt.info.cardbus.Vendor_ID;
438 hardware->pxe.product_id = gnt.info.cardbus.Dev_ID;
439 hardware->pxe.subvendor_id = gnt.info.cardbus.SubVendor_ID;
440 hardware->pxe.subproduct_id =
441 gnt.info.cardbus.SubDevice_ID,
442 hardware->pxe.rev = gnt.info.cardbus.Rev;
443 hardware->pxe.pci_bus =
444 (gnt.info.cardbus.BusDevFunc >> 8) & 0xff;
445 hardware->pxe.pci_dev =
446 (gnt.info.cardbus.BusDevFunc >> 3) & 0x7;
447 hardware->pxe.pci_func = gnt.info.cardbus.BusDevFunc & 0x03;
448 hardware->pxe.base_class = gnt.info.cardbus.Base_Class;
449 hardware->pxe.sub_class = gnt.info.cardbus.Sub_Class;
450 hardware->pxe.prog_intf = gnt.info.cardbus.Prog_Intf;
451 hardware->pxe.nictype = gnt.NicType;
452 break;
453 case PnP_NIC:
454 default:
455 return -1;
456 break;
459 /* The firt pass try to find the exact pci device */
460 hardware->pxe.pci_device = NULL;
461 hardware->pxe.pci_device_pos = 0;
462 struct pci_device *pci_device;
463 int pci_number = 0;
464 for_each_pci_func(pci_device, hardware->pci_domain) {
465 pci_number++;
466 if ((__pci_bus == hardware->pxe.pci_bus) &&
467 (__pci_slot == hardware->pxe.pci_dev) &&
468 (__pci_func == hardware->pxe.pci_func) &&
469 (pci_device->vendor == hardware->pxe.vendor_id)
470 && (pci_device->product == hardware->pxe.product_id)) {
471 hardware->pxe.pci_device = pci_device;
472 hardware->pxe.pci_device_pos = pci_number;
473 return 0;
477 /* If we reach that part, it means the pci device pointed by
478 * the pxe rom wasn't found in our list.
479 * Let's try to find the device only by its pci ids.
480 * The pci device we'll match is maybe not exactly the good one
481 * as we can have the same pci id several times.
482 * At least, the pci id, the vendor/product will be right.
483 * That's clearly a workaround for some weird cases.
484 * This should happend very unlikely */
485 hardware->pxe.pci_device = NULL;
486 hardware->pxe.pci_device_pos = 0;
487 pci_number = 0;
488 for_each_pci_func(pci_device, hardware->pci_domain) {
489 pci_number++;
490 if ((pci_device->vendor == hardware->pxe.vendor_id)
491 && (pci_device->product == hardware->pxe.product_id)) {
492 hardware->pxe.pci_device = pci_device;
493 hardware->pxe.pci_device_pos = pci_number;
494 return 0;
500 return 0;
503 void detect_memory(struct s_hardware *hardware) {
504 if (hardware->memory_detection == false) {
505 hardware->memory_detection = true;
506 hardware->detected_memory_size = detect_memsize();
510 void detect_pci(struct s_hardware *hardware)
512 if (hardware->pci_detection == true)
513 return;
514 hardware->pci_detection = true;
516 hardware->nb_pci_devices = 0;
518 /* Scanning to detect pci buses and devices */
519 hardware->pci_domain = pci_scan();
521 if (!hardware->pci_domain)
522 return;
524 /* Gathering addtional information */
525 gather_additional_pci_config(hardware->pci_domain);
527 struct pci_device *pci_device;
528 for_each_pci_func(pci_device, hardware->pci_domain) {
529 hardware->nb_pci_devices++;
532 if (!quiet) {
533 more_printf("PCI: %d devices detected\n", hardware->nb_pci_devices);
534 more_printf("PCI: Resolving names\n");
536 /* Assigning product & vendor name for each device */
537 hardware->pci_ids_return_code =
538 get_name_from_pci_ids(hardware->pci_domain, hardware->pciids_path);
540 if (!quiet)
541 more_printf("PCI: Resolving class names\n");
542 /* Assigning class name for each device */
543 hardware->pci_ids_return_code =
544 get_class_name_from_pci_ids(hardware->pci_domain,
545 hardware->pciids_path);
547 if (!quiet)
548 more_printf("PCI: Resolving module names\n");
549 /* Detecting which kernel module should match each device using modules.pcimap */
550 hardware->modules_pcimap_return_code =
551 get_module_name_from_pcimap(hardware->pci_domain,
552 hardware->modules_pcimap_path);
554 /* Detecting which kernel module should match each device using modules.alias */
555 hardware->modules_alias_return_code =
556 get_module_name_from_alias(hardware->pci_domain,
557 hardware->modules_alias_path);
561 void cpu_detect(struct s_hardware *hardware)
563 if (hardware->cpu_detection == true)
564 return;
565 detect_cpu(&hardware->cpu);
566 /* Old processors doesn't manage the identify commands
567 * Let's use the dmi value in that case */
568 if (strlen(remove_spaces(hardware->cpu.model)) == 0)
569 strlcpy(hardware->cpu.model, hardware->dmi.processor.version,
570 sizeof(hardware->cpu.model));
572 /* Some CPUs like to put many spaces in the model name
573 * That makes some weird display in console/menu
574 * Let's remove that mulitple spaces */
575 strlcpy(hardware->cpu.model,del_multi_spaces(hardware->cpu.model),sizeof(hardware->cpu.model));
577 if ((hardware->is_acpi_valid) && (hardware->acpi.madt.valid)) {
578 hardware->physical_cpu_count=hardware->acpi.madt.processor_local_apic_count / hardware->cpu.num_cores;
580 hardware->cpu_detection = true;
584 * Find the last instance of a particular command line argument
585 * (which should include the final =; do not use for boolean arguments)
587 const char *find_argument(const char **argv, const char *argument)
589 int la = strlen(argument);
590 const char **arg;
591 const char *ptr = NULL;
593 for (arg = argv; *arg; arg++) {
594 if (!memcmp(*arg, argument, la))
595 ptr = *arg + la;
598 return ptr;
601 void clear_screen(void)
603 move_cursor_to_next_line();
604 disable_utf8();
605 set_g1_special_char();
606 set_us_g0_charset();
607 display_cursor(false);
608 clear_entire_screen();
609 gotoxy(0,0);
610 reset_more_printf();
613 /* remove begining spaces */
614 char *skip_spaces(char *p)
616 while (*p && *p <= ' ') {
617 p++;
620 return p;
623 /* remove trailing & begining spaces */
624 char *remove_spaces(char *p)
626 char *save = p;
627 p += strlen(p) - 1;
628 while (*p && *p <= ' ') {
629 *p = '\0';
630 p--;
632 p = save;
633 while (*p && *p <= ' ') {
634 p++;
637 return p;
640 /* remove trailing LF */
641 char *remove_trailing_lf(char *p)
643 char *save = p;
644 p += strlen(p) - 1;
645 while (*p && *p == 10) {
646 *p = '\0';
647 p--;
649 p = save;
651 return p;
654 /* delete multiple spaces, one is enough */
655 char *del_multi_spaces(char *p)
657 /* Saving the original pointer */
658 char *save = p;
660 /* Let's parse the complete string
661 * As we search for a double spacing
662 * we have to be sure then string is
663 * long enough to be processed */
664 while (*p && *(p + 1)) {
666 /* If we have two consecutive spaces */
667 if ((*p == ' ') && (*(p + 1) == ' ')) {
669 /* Let's copy to the current position
670 * the content from the second space*/
671 strlcpy(p, p + 1, strlen(p + 1));
673 /* Don't increment the pointer as we
674 * changed the content of the current position*/
675 continue;
678 /* Nothing as been found, let's see on the next char */
679 p++;
681 /* Returning the original pointer */
682 return save;
685 /* Reset the more_printf counter */
686 void reset_more_printf(void)
688 display_line_nb = 0;
691 int draw_background(const char *what)
693 if (!what)
694 return vesacon_default_background();
695 else
696 return vesacon_load_background(what);
699 void init_console(struct s_hardware *hardware)
701 if (vesamode) {
702 openconsole(&dev_rawcon_r, &dev_vesaserial_w);
703 draw_background(hardware->vesa_background);
704 } else
705 console_ansi_raw();
708 void detect_hardware(struct s_hardware *hardware)
710 if (!quiet)
711 more_printf("ACPI: Detecting\n");
712 detect_acpi(hardware);
714 if (!quiet)
715 more_printf("MEMORY: Detecting\n");
716 detect_memory(hardware);
718 if (!quiet)
719 more_printf("DMI: Detecting Table\n");
720 if (detect_dmi(hardware) == -ENODMITABLE) {
721 printf("DMI: ERROR ! Table not found ! \n");
722 printf("DMI: Many hardware components will not be detected ! \n");
723 } else {
724 if (!quiet)
725 more_printf("DMI: Table found ! (version %u.%u)\n",
726 hardware->dmi.dmitable.major_version,
727 hardware->dmi.dmitable.minor_version);
730 if (!quiet)
731 more_printf("CPU: Detecting\n");
732 cpu_detect(hardware);
734 if (!quiet)
735 more_printf("DISKS: Detecting\n");
736 detect_disks(hardware);
738 if (!quiet)
739 more_printf("VPD: Detecting\n");
740 detect_vpd(hardware);
742 detect_pci(hardware);
743 if (!quiet)
744 more_printf("PCI: %d Devices Found\n", hardware->nb_pci_devices);
746 if (!quiet)
747 more_printf("PXE: Detecting\n");
748 detect_pxe(hardware);
750 if (!quiet)
751 more_printf("VESA: Detecting\n");
752 detect_vesa(hardware);