aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@linux.intel.com>2011-04-26 09:46:34 +0100
committerMatt Fleming <matt.fleming@linux.intel.com>2011-04-26 09:46:34 +0100
commit10d05cbef13345ef3730234c1da7b0a34cdca9b6 (patch)
treed5a582d888db9c2dc360c9005c133b713f248e55
parent844e965443e08133a7a366a496d8cc52ef93ca48 (diff)
parentd7d20a78c72237f85d8508c93aa411529d0ac17a (diff)
downloadsyslinux-10d05cbef13345ef3730234c1da7b0a34cdca9b6.tar.gz
syslinux-10d05cbef13345ef3730234c1da7b0a34cdca9b6.tar.xz
syslinux-10d05cbef13345ef3730234c1da7b0a34cdca9b6.zip
Merge remote-tracking branch 'zytor/master' into elflink
We need the recent Makefile filename changes to be merged into the elflink branch because it will make things simpler when converting all modules to ELF format. Conflicts: com32/Makefile com32/modules/Makefile version
-rw-r--r--Makefile3
-rw-r--r--Makefile.private2
-rw-r--r--NEWS11
-rw-r--r--com32/Makefile3
-rw-r--r--com32/cmenu/Makefile5
-rw-r--r--com32/gdbstub/Makefile3
-rw-r--r--com32/gfxboot/Makefile3
-rw-r--r--com32/gfxboot/gfxboot.c19
-rw-r--r--com32/gplinclude/acpi/acpi.h1
-rw-r--r--com32/gplinclude/cpuid.h236
-rw-r--r--com32/gplinclude/zzjson/zzjson.h116
-rw-r--r--com32/gpllib/Makefile7
-rw-r--r--com32/gpllib/acpi/acpi.c19
-rw-r--r--com32/gpllib/cpuid.c175
-rw-r--r--com32/gpllib/zzjson/zzjson_create.c240
-rw-r--r--com32/gpllib/zzjson/zzjson_free.c29
-rw-r--r--com32/gpllib/zzjson/zzjson_parse.c490
-rw-r--r--com32/gpllib/zzjson/zzjson_print.c110
-rw-r--r--com32/gpllib/zzjson/zzjson_query.c63
-rw-r--r--com32/hdt/Makefile25
-rw-r--r--com32/hdt/floppy/hdt.cfg9
-rw-r--r--com32/hdt/hdt-cli-acpi.c23
-rw-r--r--com32/hdt/hdt-cli-hdt.c13
-rw-r--r--com32/hdt/hdt-cli.c3
-rw-r--r--com32/hdt/hdt-cli.h1
-rw-r--r--com32/hdt/hdt-common.c33
-rw-r--r--com32/hdt/hdt-common.h11
-rw-r--r--com32/hdt/hdt-dump-acpi.c600
-rw-r--r--com32/hdt/hdt-dump-cpu.c53
-rw-r--r--com32/hdt/hdt-dump-disks.c137
-rw-r--r--com32/hdt/hdt-dump-dmi.c447
-rw-r--r--com32/hdt/hdt-dump-hdt.c50
-rw-r--r--com32/hdt/hdt-dump-kernel.c69
-rw-r--r--com32/hdt/hdt-dump-memory.c133
-rw-r--r--com32/hdt/hdt-dump-pci.c136
-rw-r--r--com32/hdt/hdt-dump-pxe.c80
-rw-r--r--com32/hdt/hdt-dump-syslinux.c43
-rw-r--r--com32/hdt/hdt-dump-vesa.c67
-rw-r--r--com32/hdt/hdt-dump-vpd.c47
-rw-r--r--com32/hdt/hdt-dump.c169
-rw-r--r--com32/hdt/hdt-dump.h85
-rw-r--r--com32/hdt/hdt-menu-acpi.c4
-rw-r--r--com32/hdt/hdt-menu-disk.c10
-rw-r--r--com32/hdt/hdt-menu-pxe.c6
-rw-r--r--com32/hdt/hdt-menu.c12
-rw-r--r--com32/hdt/hdt.h4
-rw-r--r--com32/include/bufprintf.h10
-rw-r--r--com32/include/cpufeature.h2
-rw-r--r--com32/include/ctype.h1
-rw-r--r--com32/include/netinet/in.h3
-rw-r--r--com32/include/sys/bitops.h2
-rw-r--r--com32/lib/Makefile8
-rw-r--r--com32/lib/bufprintf.c41
-rw-r--r--com32/lib/chrreplace.c11
-rw-r--r--com32/lib/inet.c39
-rw-r--r--com32/lib/jpeg/tinyjpeg-internal.h2
-rw-r--r--com32/lib/jpeg/tinyjpeg.c4
-rw-r--r--com32/lib/pci/scan.c11
-rw-r--r--com32/libupload/.gitignore2
-rw-r--r--com32/libupload/Makefile39
-rw-r--r--com32/libupload/cpio.c (renamed from com32/sysdump/cpio.c)12
-rw-r--r--com32/libupload/ctime.c (renamed from com32/sysdump/ctime.c)0
-rw-r--r--com32/libupload/ctime.h (renamed from com32/sysdump/ctime.h)0
-rw-r--r--com32/libupload/serial.c (renamed from com32/sysdump/serial.c)0
-rw-r--r--com32/libupload/serial.h (renamed from com32/sysdump/serial.h)0
-rw-r--r--com32/libupload/srecsend.h (renamed from com32/sysdump/srecsend.h)0
-rw-r--r--com32/libupload/tftp.h22
-rw-r--r--com32/libupload/upload_backend.h56
-rw-r--r--com32/libupload/upload_srec.c (renamed from com32/sysdump/be_srec.c)8
-rw-r--r--com32/libupload/upload_tftp.c (renamed from com32/sysdump/be_tftp.c)66
-rw-r--r--com32/libupload/upload_ymodem.c (renamed from com32/sysdump/be_ymodem.c)8
-rw-r--r--com32/libupload/ymodem.txt (renamed from com32/sysdump/ymodem.txt)0
-rw-r--r--com32/libupload/zout.c (renamed from com32/sysdump/zout.c)19
-rw-r--r--com32/libutil/Makefile6
-rw-r--r--com32/libutil/include/getkey.h4
-rw-r--r--com32/libutil/keyname.c138
-rw-r--r--com32/lua/src/Makefile6
-rw-r--r--com32/mboot/Makefile6
-rw-r--r--com32/menu/Makefile8
-rw-r--r--com32/menu/menu.h2
-rw-r--r--com32/menu/menumain.c9
-rw-r--r--com32/menu/readconfig.c48
-rw-r--r--com32/modules/Makefile7
-rw-r--r--com32/modules/zzjson.c101
-rw-r--r--com32/rosh/Makefile3
-rw-r--r--com32/samples/Makefile3
-rw-r--r--com32/samples/keytest.c9
-rw-r--r--com32/sysdump/Makefile7
-rw-r--r--com32/sysdump/acpi.c9
-rw-r--r--com32/sysdump/backend.h55
-rw-r--r--com32/sysdump/cpuid.c3
-rw-r--r--com32/sysdump/data.h2
-rw-r--r--com32/sysdump/dmi.c7
-rw-r--r--com32/sysdump/main.c21
-rw-r--r--com32/sysdump/memmap.c5
-rw-r--r--com32/sysdump/memory.c5
-rw-r--r--com32/sysdump/pci.c5
-rw-r--r--com32/sysdump/sysdump.h16
-rw-r--r--com32/sysdump/vesa.c5
-rw-r--r--com32/tools/Makefile4
-rw-r--r--core/Makefile5
-rw-r--r--core/diskboot.inc2
-rw-r--r--core/diskfs.inc4
-rw-r--r--core/diskstart.inc49
-rw-r--r--core/fs/fat/fat.c6
-rw-r--r--core/fs/iso9660/iso9660.c50
-rw-r--r--core/head.inc4
-rw-r--r--core/isolinux.asm173
-rw-r--r--core/ui.inc7
-rw-r--r--diag/geodsp/Makefile21
-rw-r--r--diag/geodsp/mk-lba-img.c55
-rw-r--r--diag/mbr/Makefile3
-rw-r--r--doc/isolinux.txt31
-rw-r--r--doc/menu.txt19
-rw-r--r--dos/Makefile3
-rw-r--r--dosutil/Makefile3
-rw-r--r--extlinux/Makefile3
-rwxr-xr-xextlinux/main.c15
-rw-r--r--libinstaller/syslxcom.c13
-rw-r--r--libinstaller/syslxcom.h1
-rw-r--r--libinstaller/syslxmod.c21
-rw-r--r--linux/Makefile3
-rwxr-xr-xlinux/syslinux.c4
-rw-r--r--lzo/Makefile3
-rw-r--r--mbr/Makefile3
-rw-r--r--memdisk/Makefile3
-rw-r--r--memdump/Makefile3
-rw-r--r--mk/build.mk (renamed from MCONFIG.build)2
-rw-r--r--mk/com32.mk (renamed from com32/MCONFIG)2
-rw-r--r--mk/devel.mk (renamed from MCONFIG.devel)0
-rw-r--r--mk/embedded.mk (renamed from MCONFIG.embedded)2
-rw-r--r--mk/lib.mk (renamed from com32/lib/MCONFIG)2
-rw-r--r--mk/rosh.mk (renamed from com32/rosh/MCONFIG)2
-rw-r--r--mk/syslinux.mk (renamed from MCONFIG)4
-rw-r--r--modules/Makefile3
-rwxr-xr-xmtools/Makefile3
-rw-r--r--sample/Makefile3
-rw-r--r--syslinux.spec.in3
-rw-r--r--utils/Makefile3
-rwxr-xr-xutils/ppmtolss162
140 files changed, 4486 insertions, 717 deletions
diff --git a/Makefile b/Makefile
index 60a59560..0f500a33 100644
--- a/Makefile
+++ b/Makefile
@@ -15,7 +15,8 @@
# Main Makefile for SYSLINUX
#
topdir = .
-include $(topdir)/MCONFIG
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/syslinux.mk
-include $(topdir)/version.mk
#
diff --git a/Makefile.private b/Makefile.private
index c70c204d..6ca0598f 100644
--- a/Makefile.private
+++ b/Makefile.private
@@ -18,7 +18,7 @@
.PHONY: official release
# These files are removed when tarballs are generated.
-PRIVATE = Makefile.private MCONFIG.devel
+PRIVATE = Makefile.private mk/devel.mk
GIT_DIR ?= .git
ABS_GIT_DIR := $(shell cd '$(GIT_DIR)' 2>/dev/null && pwd)
diff --git a/NEWS b/NEWS
index 8467df4f..443e1a51 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,13 @@ Starting with 1.47, changes marked with SYSLINUX, PXELINUX, ISOLINUX
or EXTLINUX apply to that specific program only; other changes apply
to all derivatives.
+Changes in 4.05:
+ * HDT updated, and now supports uploading data to a TFTP
+ server.
+ * ISOLINUX: remove the .img file support; it has been broken
+ on virtually all systems since the beginning, and has been
+ totally broken since 4.00 at least. Use MEMDISK instead.
+
Changes in 4.04:
* PXELINUX: Fix handling of unqualified DNS names.
* PXELINUX: Fix timer bug when PXELINUX might be unloaded
@@ -48,6 +55,10 @@ Changes in 4.04:
* Include a set of diagnostics by Gene Cumm.
* Fixes for gcc 4.6 and binutils 2.21.51.
* chain.c32: Allow "uuid" as a synonym to "guid".
+ * Handle directory names starting with .. for vfat and
+ iso9660.
+ * New MENU HIDDENKEY command to provide a one-keystroke way to
+ activate a boot option from a hidden menu intro screen.
Changes in 4.03:
* Don't hang if no configuration file is found.
diff --git a/com32/Makefile b/com32/Makefile
index bc13cf62..d2492359 100644
--- a/com32/Makefile
+++ b/com32/Makefile
@@ -1,4 +1,5 @@
-SUBDIRS = tools lib gpllib libutil modules mboot menu samples elflink elflink/modules rosh cmenu \
+SUBDIRS = libupload tools lib gpllib libutil modules mboot menu samples elflink elflink/modules rosh cmenu \
hdt gfxboot sysdump lua/src elflink/ldlinux
+
all tidy dist clean spotless install:
set -e; for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done
diff --git a/com32/cmenu/Makefile b/com32/cmenu/Makefile
index 794af741..446bbcdd 100644
--- a/com32/cmenu/Makefile
+++ b/com32/cmenu/Makefile
@@ -17,11 +17,12 @@
NOGPL := 1
-# This must be defined before MCONFIG is included
+# This must be defined before com32.mk is included
LIBS = libmenu/libmenu.a
topdir = ../..
-include ../MCONFIG
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/com32.mk
CFLAGS += -I./libmenu
diff --git a/com32/gdbstub/Makefile b/com32/gdbstub/Makefile
index 5513876b..38d003cc 100644
--- a/com32/gdbstub/Makefile
+++ b/com32/gdbstub/Makefile
@@ -15,7 +15,8 @@
##
topdir = ../..
-include ../MCONFIG
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/com32.mk
CFLAGS += -fPIE
diff --git a/com32/gfxboot/Makefile b/com32/gfxboot/Makefile
index 73133e1b..183115f4 100644
--- a/com32/gfxboot/Makefile
+++ b/com32/gfxboot/Makefile
@@ -12,7 +12,8 @@
## -----------------------------------------------------------------------
topdir = ../..
-include ../MCONFIG
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/com32.mk
MODULES = gfxboot.c32
diff --git a/com32/gfxboot/gfxboot.c b/com32/gfxboot/gfxboot.c
index 37499202..35d180a6 100644
--- a/com32/gfxboot/gfxboot.c
+++ b/com32/gfxboot/gfxboot.c
@@ -102,6 +102,8 @@ typedef struct __attribute__ ((packed)) {
// 0: GFX_CB_MENU_INIT accepts 32 bit addresses
// 1: knows about xmem_start, xmem_end
uint16_t reserved_1; // 62:
+ uint32_t gfxboot_cwd; // 64: if set, points to current gfxboot working directory relative
+ // to syslinux working directory
} gfx_config_t;
@@ -181,6 +183,7 @@ int main(int argc, char **argv)
{
int menu_index;
const union syslinux_derivative_info *sdi;
+ char working_dir[256];
openconsole(&dev_stdcon_r, &dev_stdcon_w);
@@ -224,6 +227,10 @@ int main(int argc, char **argv)
return 0;
}
+ if(getcwd(working_dir, sizeof working_dir)) {
+ gfx_config.gfxboot_cwd = (uint32_t) working_dir;
+ }
+
if(gfx_init(argv[1])) {
printf("Error setting up gfxboot\n");
if(argc > 2) show_message(argv[2]);
@@ -806,6 +813,12 @@ void boot(int index)
int i, label_len;
unsigned ipapp;
const struct syslinux_ipappend_strings *ipappend;
+ char *gfxboot_cwd = (char *) gfx_config.gfxboot_cwd;
+
+ if(gfxboot_cwd) {
+ chdir(gfxboot_cwd);
+ gfx_config.gfxboot_cwd = 0;
+ }
for(menu_ptr = menu; menu_ptr; menu_ptr = menu_ptr->next, index--) {
if(!index) break;
@@ -922,11 +935,15 @@ void boot_entry(menu_t *menu_ptr, char *arg)
*skip_nonspaces(s) = 0;
initrd_arg = s;
}
+ else if(initrd_arg) {
+ free(s0);
+ initrd_arg = s0 = strdup(initrd_arg);
+ }
if(initrd_arg) {
initrd = initramfs_init();
- while((t = strsep(&s, ","))) {
+ while((t = strsep(&initrd_arg, ","))) {
initrd_buf = load_one(t, &initrd_size);
if(!initrd_buf) {
diff --git a/com32/gplinclude/acpi/acpi.h b/com32/gplinclude/acpi/acpi.h
index 94589f35..bf3ffdb7 100644
--- a/com32/gplinclude/acpi/acpi.h
+++ b/com32/gplinclude/acpi/acpi.h
@@ -95,4 +95,5 @@ void parse_madt(s_acpi * acpi);
int search_rsdp(s_acpi *acpi);
void get_acpi_description_header(uint8_t *q, s_acpi_description_header * adh);
bool parse_header(uint64_t *address, s_acpi *acpi);
+char *flags_to_string(char *buffer, uint16_t flags);
#endif
diff --git a/com32/gplinclude/cpuid.h b/com32/gplinclude/cpuid.h
index 53a08085..6a33e9cb 100644
--- a/com32/gplinclude/cpuid.h
+++ b/com32/gplinclude/cpuid.h
@@ -18,9 +18,11 @@
#include <stdbool.h>
#include <stdint.h>
+#include <stdio.h>
#include <cpufeature.h>
#include <sys/bitops.h>
#include <sys/cpu.h>
+#include <sys/io.h>
#include <klibc/compiler.h>
#define PAGE_SIZE 4096
@@ -28,99 +30,112 @@
#define CPU_MODEL_SIZE 48
#define CPU_VENDOR_SIZE 48
+#define CPU_FLAGS(m_) \
+m_(bool, fpu, /* Onboard FPU */) \
+m_(bool, vme, /* Virtual Mode Extensions */) \
+m_(bool, de, /* Debugging Extensions */) \
+m_(bool, pse, /* Page Size Extensions */) \
+m_(bool, tsc, /* Time Stamp Counter */) \
+m_(bool, msr, /* Model-Specific Registers, RDMSR, WRMSR */) \
+m_(bool, pae, /* Physical Address Extensions */) \
+m_(bool, mce, /* Machine Check Architecture */) \
+m_(bool, cx8, /* CMPXCHG8 instruction */) \
+m_(bool, apic, /* Onboard APIC */) \
+m_(bool, sep, /* SYSENTER/SYSEXIT */) \
+m_(bool, mtrr, /* Memory Type Range Registers */) \
+m_(bool, pge, /* Page Global Enable */) \
+m_(bool, mca, /* Machine Check Architecture */) \
+m_(bool, cmov, /* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */) \
+m_(bool, pat, /* Page Attribute Table */) \
+m_(bool, pse_36, /* 36-bit PSEs */) \
+m_(bool, psn, /* Processor serial number */) \
+m_(bool, clflsh, /* Supports the CLFLUSH instruction */) \
+m_(bool, dts, /* Debug Trace Store */) \
+m_(bool, acpi, /* ACPI via MSR */) \
+m_(bool, pbe, /* Pending Break Enable */) \
+m_(bool, mmx, /* Multimedia Extensions */) \
+m_(bool, fxsr, /* FXSAVE and FXRSTOR instructions (fast save and restore of FPU context), and CR4.OSFXSR available */) \
+m_(bool, sse, /* Streaming SIMD Extensions */) \
+m_(bool, sse2, /* Streaming SIMD Extensions 2 */) \
+m_(bool, ss, /* CPU self snoop */) \
+m_(bool, htt, /* Hyper-Threading */) \
+m_(bool, acc, /* Automatic clock control */) \
+m_(bool, syscall, /* SYSCALL/SYSRET */) \
+m_(bool, mp, /* MP Capable. */) \
+m_(bool, nx, /* Execute Disable */) \
+m_(bool, mmxext, /* AMD MMX extensions */) \
+m_(bool, fxsr_opt, /* FXSAVE/FXRSTOR optimizations */) \
+m_(bool, gbpages, /* "pdpe1gb" GB pages */) \
+m_(bool, rdtscp, /* RDTSCP */) \
+m_(bool, lm, /* Long Mode (x86-64) */) \
+m_(bool, nowext, /* AMD 3DNow! extensions */) \
+m_(bool, now, /* 3DNow! */) \
+m_(bool, smp, /* A smp configuration has been found */) \
+m_(bool, pni, /* Streaming SIMD Extensions-3 */) \
+m_(bool, pclmulqd, /* PCLMULQDQ instruction */) \
+m_(bool, dtes64, /* 64-bit Debug Store */) \
+m_(bool, vmx, /* Hardware virtualization */) \
+m_(bool, smx, /* Safer Mode */) \
+m_(bool, est, /* Enhanced SpeedStep */) \
+m_(bool, tm2, /* Thermal Monitor 2 */) \
+m_(bool, sse3, /* Supplemental SSE-3 */) \
+m_(bool, cid, /* Context ID */) \
+m_(bool, fma, /* Fused multiply-add */) \
+m_(bool, cx16, /* CMPXCHG16B */) \
+m_(bool, xtpr, /* Send Task Priority Messages */) \
+m_(bool, pdcm, /* Performance Capabilities */) \
+m_(bool, dca, /* Direct Cache Access */) \
+m_(bool, xmm4_1, /* "sse4_1" SSE-4.1 */) \
+m_(bool, xmm4_2, /* "sse4_2" SSE-4.2 */) \
+m_(bool, x2apic, /* x2APIC */) \
+m_(bool, movbe, /* MOVBE instruction */) \
+m_(bool, popcnt, /* POPCNT instruction */) \
+m_(bool, aes, /* AES Instruction */) \
+m_(bool, xsave, /* XSAVE/XRSTOR/XSETBV/XGETBV */) \
+m_(bool, osxsave, /* XSAVE enabled in the OS */) \
+m_(bool, avx, /* Advanced Vector Extensions */) \
+m_(bool, hypervisor, /* Running on a hypervisor */) \
+m_(bool, ace2, /* Advanced Cryptography Engine v2 */) \
+m_(bool, ace2_en, /* ACE v2 enabled */) \
+m_(bool, phe, /* PadLock Hash Engine */) \
+m_(bool, phe_en, /* PadLock Hash Engine Enabled */) \
+m_(bool, pmm, /* PadLock Montgomery Multiplier */) \
+m_(bool, pmm_en, /* PadLock Montgomery Multiplier enabled */) \
+m_(bool, svm, /* Secure virtual machine */) \
+m_(bool, extapic, /* Extended APIC space */) \
+m_(bool, cr8_legacy, /* CR8 in 32-bit mode */) \
+m_(bool, abm, /* Advanced bit manipulation */) \
+m_(bool, sse4a, /* SSE4-A */) \
+m_(bool, misalignsse, /* Misaligned SSE mode */) \
+m_(bool, nowprefetch, /* 3DNow prefetch instructions */) \
+m_(bool, osvw, /* OS Visible Workaround */) \
+m_(bool, ibs, /* Instruction Based Sampling */) \
+m_(bool, sse5, /* SSE5 */) \
+m_(bool, skinit, /* SKINIT/STGI instructions */) \
+m_(bool, wdt, /* Watchdog Timer */) \
+m_(bool, ida, /* Intel Dynamic Acceleration */) \
+m_(bool, arat, /* Always Running APIC Timer */) \
+m_(bool, tpr_shadow, /* Intel TPR Shadow */) \
+m_(bool, vnmi, /* Intel Virtual NMI */) \
+m_(bool, flexpriority, /* Intel FlexPriority */) \
+m_(bool, ept, /* Intel Extended Page Table */) \
+m_(bool, vpid, /* Intel Virtual Processor ID */)
+
+#define STRUCT_MEMBERS(type_, name_, comment_) type_ name_;
+
+#define STRUCT_MEMBER_NAMES(type_, name_, comment_) #name_ ,
+
+#define STRUCTURE_MEMBER_OFFSETS(type_, name_, comment_) \
+ offsetof(s_cpu_flags, name_),
+
typedef struct {
- bool fpu; /* Onboard FPU */
- bool vme; /* Virtual Mode Extensions */
- bool de; /* Debugging Extensions */
- bool pse; /* Page Size Extensions */
- bool tsc; /* Time Stamp Counter */
- bool msr; /* Model-Specific Registers, RDMSR, WRMSR */
- bool pae; /* Physical Address Extensions */
- bool mce; /* Machine Check Architecture */
- bool cx8; /* CMPXCHG8 instruction */
- bool apic; /* Onboard APIC */
- bool sep; /* SYSENTER/SYSEXIT */
- bool mtrr; /* Memory Type Range Registers */
- bool pge; /* Page Global Enable */
- bool mca; /* Machine Check Architecture */
- bool cmov; /* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */
- bool pat; /* Page Attribute Table */
- bool pse_36; /* 36-bit PSEs */
- bool psn; /* Processor serial number */
- bool clflsh; /* Supports the CLFLUSH instruction */
- bool dts; /* Debug Trace Store */
- bool acpi; /* ACPI via MSR */
- bool pbe; /* Pending Break Enable */
- bool mmx; /* Multimedia Extensions */
- bool fxsr; /* FXSAVE and FXRSTOR instructions (fast save and restore */
- /* of FPU context), and CR4.OSFXSR available */
- bool sse; /* Streaming SIMD Extensions */
- bool sse2; /* Streaming SIMD Extensions 2 */
- bool ss; /* CPU self snoop */
- bool htt; /* Hyper-Threading */
- bool acc; /* Automatic clock control */
- bool syscall; /* SYSCALL/SYSRET */
- bool mp; /* MP Capable. */
- bool nx; /* Execute Disable */
- bool mmxext; /* AMD MMX extensions */
- bool fxsr_opt; /* FXSAVE/FXRSTOR optimizations */
- bool gbpages; /* "pdpe1gb" GB pages */
- bool rdtscp; /* RDTSCP */
- bool lm; /* Long Mode (x86-64) */
- bool nowext; /* AMD 3DNow! extensions */
- bool now; /* 3DNow! */
- bool smp; /* A smp configuration has been found */
- bool pni; /* Streaming SIMD Extensions-3 */
- bool pclmulqd; /* PCLMULQDQ instruction */
- bool dtes64; /* 64-bit Debug Store */
- bool vmx; /* Hardware virtualization */
- bool smx; /* Safer Mode */
- bool est; /* Enhanced SpeedStep */
- bool tm2; /* Thermal Monitor 2 */
- bool sse3; /* Supplemental SSE-3 */
- bool cid; /* Context ID */
- bool fma; /* Fused multiply-add */
- bool cx16; /* CMPXCHG16B */
- bool xtpr; /* Send Task Priority Messages */
- bool pdcm; /* Performance Capabilities */
- bool dca; /* Direct Cache Access */
- bool xmm4_1; /* "sse4_1" SSE-4.1 */
- bool xmm4_2; /* "sse4_2" SSE-4.2 */
- bool x2apic; /* x2APIC */
- bool movbe; /* MOVBE instruction */
- bool popcnt; /* POPCNT instruction */
- bool aes; /* AES Instruction */
- bool xsave; /* XSAVE/XRSTOR/XSETBV/XGETBV */
- bool osxsave; /* XSAVE enabled in the OS */
- bool avx; /* Advanced Vector Extensions */
- bool hypervisor; /* Running on a hypervisor */
- bool ace2; /* Advanced Cryptography Engine v2 */
- bool ace2_en; /* ACE v2 enabled */
- bool phe; /* PadLock Hash Engine */
- bool phe_en; /* PadLock Hash Engine Enabled */
- bool pmm; /* PadLock Montgomery Multiplier */
- bool pmm_en; /* PadLock Montgomery Multiplier enabled */
- bool svm; /* Secure virtual machine */
- bool extapic; /* Extended APIC space */
- bool cr8_legacy; /* CR8 in 32-bit mode */
- bool abm; /* Advanced bit manipulation */
- bool sse4a; /* SSE4-A */
- bool misalignsse; /* Misaligned SSE mode */
- bool nowprefetch; /* 3DNow prefetch instructions */
- bool osvw; /* OS Visible Workaround */
- bool ibs; /* Instruction Based Sampling */
- bool sse5; /* SSE5 */
- bool skinit; /* SKINIT/STGI instructions */
- bool wdt; /* Watchdog Timer */
- bool ida; /* Intel Dynamic Acceleration */
- bool arat; /* Always Running APIC Timer */
- bool tpr_shadow; /* Intel TPR Shadow */
- bool vnmi; /* Intel Virtual NMI */
- bool flexpriority; /* Intel FlexPriority */
- bool ept; /* Intel Extended Page Table */
- bool vpid; /* Intel Virtual Processor ID */
+ CPU_FLAGS(STRUCT_MEMBERS)
} s_cpu_flags;
+extern size_t cpu_flags_offset[];
+extern const char *cpu_flags_names[];
+extern size_t cpu_flags_count;
+
typedef struct {
char vendor[CPU_VENDOR_SIZE];
uint8_t vendor_id;
@@ -135,6 +150,7 @@ typedef struct {
s_cpu_flags flags;
} s_cpu;
+extern bool get_cpu_flag_value_from_name(s_cpu *cpu, const char * flag);
/**********************************************************************************/
/**********************************************************************************/
/* From this point this is some internal stuff mainly taken from the linux kernel */
@@ -171,11 +187,37 @@ typedef struct {
#define X86_VENDOR_RISE 6
#define X86_VENDOR_TRANSMETA 7
#define X86_VENDOR_NSC 8
-#define X86_VENDOR_NUM 9
-#define X86_VENDOR_UNKNOWN 0xff
+#define X86_VENDOR_UNKNOWN 9
+#define X86_VENDOR_NUM 10
#define cpu_has(c, bit) test_bit(bit, (c)->x86_capability)
+// Taken from asm/processor-flags.h
+// NSC/Cyrix CPU configuration register indexes
+#define CX86_CCR2 0xc2
+#define CX86_CCR3 0xc3
+#define CX86_DIR0 0xfe
+#define CX86_DIR1 0xff
+
+static const char Cx86_model[][9] = {
+ "Cx486", "Cx486", "5x86 ", "6x86", "MediaGX ", "6x86MX ",
+ "M II ", "Unknown"
+};
+
+static const char Cx486_name[][5] = {
+ "SLC", "DLC", "SLC2", "DLC2", "SRx", "DRx",
+ "SRx2", "DRx2"
+};
+
+static const char Cx486S_name[][4] = {
+ "S", "S2", "Se", "S2e"
+};
+
+static const char Cx486D_name[][4] = {
+ "DX", "DX2", "?", "?", "?", "DX4"
+};
+
+
/*
* CPU type and hardware bug flags. Kept separately for each CPU.
* Members of this structure are referenced in head.S, so think twice
@@ -260,6 +302,16 @@ struct intel_mp_floating {
uint8_t mpf_feature5; /* Unused (0) */
};
+static inline uint8_t getCx86(uint8_t reg) {
+ outb(reg, 0x22);
+ return inb(0x23);
+}
+
+static inline void setCx86(uint8_t reg, uint8_t data) {
+ outb(reg, 0x22);
+ outb(data, 0x23);
+}
+
extern void get_cpu_vendor(struct cpuinfo_x86 *c);
extern void detect_cpu(s_cpu * cpu);
#endif
diff --git a/com32/gplinclude/zzjson/zzjson.h b/com32/gplinclude/zzjson/zzjson.h
new file mode 100644
index 00000000..d4b32e12
--- /dev/null
+++ b/com32/gplinclude/zzjson/zzjson.h
@@ -0,0 +1,116 @@
+/* ZZJSON - Copyright (C) 2008 by Ivo van Poorten
+ * License: GNU Lesser General Public License version 2.1
+ */
+#ifndef ZZJSON_H
+#define ZZJSON_H
+
+#include <stdlib.h>
+
+/* Version: */
+
+#define ZZJSON_VERSION_MAJOR 1
+#define ZZJSON_VERSION_MINOR 1
+#define ZZJSON_VERSION_MICRO 0
+#define ZZJSON_VERSION_INT ( 1<<16 | 1<<8 | 0 )
+#define ZZJSON_IDENT "zzjson 1.1.0"
+
+/* Defines: */
+
+#define ZZJSON_ALLOW_EXTRA_COMMA 1
+#define ZZJSON_ALLOW_ILLEGAL_ESCAPE 2
+#define ZZJSON_ALLOW_CONTROL_CHARS 4
+#define ZZJSON_ALLOW_GARBAGE_AT_END 8
+#define ZZJSON_ALLOW_COMMENTS 16
+
+#define ZZJSON_VERY_LOOSE (-1)
+#define ZZJSON_VERY_STRICT 0
+
+/* Types: */
+
+/* needed by: pa = parser, pr = printer, f = free, q = query, c = create */
+typedef struct ZZJSON_CONFIG {
+ int strictness; // pa
+ void *ihandle; // pa
+ int (*getchar)(void *ihandle); // pa
+ int (*ungetchar)(int c, void *ihandle); // pa
+ void *(*malloc)(size_t size); // pa c
+ void *(*calloc)(size_t nmemb, size_t size); // pa c
+ void (*free)(void *ptr); // pa f c
+ void *(*realloc)(void *ptr, size_t size); // pa
+ void *ehandle; // pa pr c
+ void (*error)(void *ehandle, const char *format, ...); // pa pr c
+ void *ohandle; // pr
+ int (*print)(void *ohandle, const char *format, ...); // pr
+ int (*putchar)(int c, void *handle); // pr
+} ZZJSON_CONFIG;
+
+typedef enum ZZJSON_TYPE {
+ ZZJSON_NONE = 0,
+ ZZJSON_OBJECT,
+ ZZJSON_ARRAY,
+ ZZJSON_STRING,
+ ZZJSON_NUMBER_NEGINT,
+ ZZJSON_NUMBER_POSINT,
+ ZZJSON_NUMBER_DOUBLE,
+ ZZJSON_NULL,
+ ZZJSON_TRUE,
+ ZZJSON_FALSE
+} ZZJSON_TYPE;
+
+typedef struct ZZJSON {
+ ZZJSON_TYPE type;
+ union {
+ struct {
+ char *label;
+ struct ZZJSON *val;
+ } object;
+ struct {
+ struct ZZJSON *val;
+ } array;
+ struct {
+ char *string;
+ } string;
+ struct {
+ union {
+ unsigned long long ival;
+ double dval;
+ } val;
+ } number;
+ } value;
+ struct ZZJSON *next;
+} ZZJSON;
+
+/* Functions: */
+
+ZZJSON *zzjson_parse(ZZJSON_CONFIG *config);
+void zzjson_free(ZZJSON_CONFIG *config, ZZJSON *zzjson);
+int zzjson_print(ZZJSON_CONFIG *config, ZZJSON *zzjson);
+
+ZZJSON *zzjson_object_find_label(ZZJSON *zzjson, char *label);
+ZZJSON *zzjson_object_find_labels(ZZJSON *zzjson, ...); // end with , NULL
+unsigned int zzjson_object_count(ZZJSON *zzjson);
+unsigned int zzjson_array_count(ZZJSON *zzjson);
+
+ZZJSON *zzjson_create_true(ZZJSON_CONFIG *config);
+ZZJSON *zzjson_create_false(ZZJSON_CONFIG *config);
+ZZJSON *zzjson_create_null(ZZJSON_CONFIG *config);
+ZZJSON *zzjson_create_number_d(ZZJSON_CONFIG *config, double d);
+ZZJSON *zzjson_create_number_i(ZZJSON_CONFIG *config, long long i);
+ZZJSON *zzjson_create_string(ZZJSON_CONFIG *config, char *s);
+
+/* list of ZZJSON *'s and end with , NULL */
+ZZJSON *zzjson_create_array(ZZJSON_CONFIG *config, ...);
+
+/* list of char*,ZZJSON* pairs, end with , NULL */
+ZZJSON *zzjson_create_object(ZZJSON_CONFIG *config, ...);
+
+ZZJSON *zzjson_array_prepend(ZZJSON_CONFIG *config, ZZJSON *array,
+ ZZJSON *val);
+ZZJSON *zzjson_array_append (ZZJSON_CONFIG *config, ZZJSON *array,
+ ZZJSON *val);
+
+ZZJSON *zzjson_object_prepend(ZZJSON_CONFIG *config, ZZJSON *object,
+ char *label, ZZJSON *val);
+ZZJSON *zzjson_object_append (ZZJSON_CONFIG *config, ZZJSON *object,
+ char *label, ZZJSON *val);
+#endif
diff --git a/com32/gpllib/Makefile b/com32/gpllib/Makefile
index a1740610..4b7b8468 100644
--- a/com32/gpllib/Makefile
+++ b/com32/gpllib/Makefile
@@ -4,11 +4,12 @@
# Include configuration rules
topdir = ../..
-include ../lib/MCONFIG
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/lib.mk
-REQFLAGS += -I../gplinclude
+REQFLAGS += -I../gplinclude -I../gplinclude/zzjson
-GPLDIRS := . disk dmi vpd acpi
+GPLDIRS := . disk dmi vpd acpi zzjson
LIBOBJS := $(foreach dir,$(GPLDIRS),$(patsubst %.c,%.o,$(wildcard $(dir)/*.c)))
BINDIR = /usr/bin
diff --git a/com32/gpllib/acpi/acpi.c b/com32/gpllib/acpi/acpi.c
index 8e5ee29c..d2bf29e5 100644
--- a/com32/gpllib/acpi/acpi.c
+++ b/com32/gpllib/acpi/acpi.c
@@ -32,6 +32,25 @@
#include <memory.h>
#include "acpi/acpi.h"
+/* M1PS flags have to be interpreted as strings */
+char *flags_to_string(char *buffer, uint16_t flags)
+{
+ memset(buffer, 0, sizeof(buffer));
+ strcpy(buffer, "default");
+ if ((flags & POLARITY_ACTIVE_HIGH) == POLARITY_ACTIVE_HIGH)
+ strcpy(buffer, "high");
+ else if ((flags & POLARITY_ACTIVE_LOW) == POLARITY_ACTIVE_LOW)
+ strcpy(buffer, "low");
+ if ((flags & TRIGGER_EDGE) == TRIGGER_EDGE)
+ strncat(buffer, " edge", 5);
+ else if ((flags & TRIGGER_LEVEL) == TRIGGER_LEVEL)
+ strncat(buffer, " level", 6);
+ else
+ strncat(buffer, " default", 8);
+
+ return buffer;
+}
+
void dbg_printf(const char *fmt, ...)
{
va_list args;
diff --git a/com32/gpllib/cpuid.c b/com32/gpllib/cpuid.c
index 2d5b5ce9..2abd0bda 100644
--- a/com32/gpllib/cpuid.c
+++ b/com32/gpllib/cpuid.c
@@ -20,8 +20,31 @@
#include <string.h>
#include "cpuid.h"
+const char *cpu_flags_names[] = {
+ CPU_FLAGS(STRUCT_MEMBER_NAMES)
+};
+
+size_t cpu_flags_offset[] = {
+ CPU_FLAGS(STRUCTURE_MEMBER_OFFSETS)
+};
+
+size_t cpu_flags_count = sizeof cpu_flags_names / sizeof *cpu_flags_names;
+
struct cpu_dev *cpu_devs[X86_VENDOR_NUM] = { };
+bool get_cpu_flag_value_from_name(s_cpu *cpu, const char * flag_name) {
+ size_t i;
+ bool cpu_flag_present=false, *flag_value = &cpu_flag_present;
+
+ for (i = 0; i < cpu_flags_count; i++) {
+ if (strcmp(cpu_flags_names[i],flag_name) == 0) {
+ flag_value = (bool *)((char *)&cpu->flags + cpu_flags_offset[i]);
+ }
+ }
+ return *flag_value;
+}
+
+
/*
* CPUID functions returning a single datum
*/
@@ -73,6 +96,48 @@ static struct cpu_dev transmeta_cpu_dev = {
.c_ident = {"GenuineTMx86", "TransmetaCPU"}
};
+static struct cpu_dev nsc_cpu_dev = {
+ .c_vendor = "National Semiconductor",
+ .c_ident = {"Geode by NSC"}
+};
+
+static struct cpu_dev unknown_cpu_dev = {
+ .c_vendor = "Unknown Vendor",
+ .c_ident = {"Unknown CPU"}
+};
+
+/*
+ * Read NSC/Cyrix DEVID registers (DIR) to get more detailed info. about the CPU
+ */
+void do_cyrix_devid(unsigned char *dir0, unsigned char *dir1)
+{
+ unsigned char ccr2, ccr3;
+
+ /* we test for DEVID by checking whether CCR3 is writable */
+ ccr3 = getCx86(CX86_CCR3);
+ setCx86(CX86_CCR3, ccr3 ^ 0x80);
+ getCx86(0xc0); /* dummy to change bus */
+
+ if (getCx86(CX86_CCR3) == ccr3) { /* no DEVID regs. */
+ ccr2 = getCx86(CX86_CCR2);
+ setCx86(CX86_CCR2, ccr2 ^ 0x04);
+ getCx86(0xc0); /* dummy */
+
+ if (getCx86(CX86_CCR2) == ccr2) /* old Cx486SLC/DLC */
+ *dir0 = 0xfd;
+ else { /* Cx486S A step */
+ setCx86(CX86_CCR2, ccr2);
+ *dir0 = 0xfe;
+ }
+ } else {
+ setCx86(CX86_CCR3, ccr3); /* restore CCR3 */
+
+ /* read DIR0 and DIR1 CPU registers */
+ *dir0 = getCx86(CX86_DIR0);
+ *dir1 = getCx86(CX86_DIR1);
+ }
+}
+
void init_cpu_devs(void)
{
cpu_devs[X86_VENDOR_INTEL] = &intel_cpu_dev;
@@ -83,6 +148,8 @@ void init_cpu_devs(void)
cpu_devs[X86_VENDOR_CENTAUR] = &centaur_cpu_dev;
cpu_devs[X86_VENDOR_RISE] = &rise_cpu_dev;
cpu_devs[X86_VENDOR_TRANSMETA] = &transmeta_cpu_dev;
+ cpu_devs[X86_VENDOR_NSC] = &nsc_cpu_dev;
+ cpu_devs[X86_VENDOR_UNKNOWN] = &unknown_cpu_dev;
}
void get_cpu_vendor(struct cpuinfo_x86 *c)
@@ -90,7 +157,7 @@ void get_cpu_vendor(struct cpuinfo_x86 *c)
char *v = c->x86_vendor_id;
int i;
init_cpu_devs();
- for (i = 0; i < X86_VENDOR_NUM; i++) {
+ for (i = 0; i < X86_VENDOR_NUM-1; i++) {
if (cpu_devs[i]) {
if (!strcmp(v, cpu_devs[i]->c_ident[0]) ||
(cpu_devs[i]->c_ident[1] &&
@@ -177,6 +244,96 @@ void detect_cache(uint32_t xlvl, struct cpuinfo_x86 *c)
c->x86_l2_cache_size = l2size;
}
+void detect_cyrix(struct cpuinfo_x86 *c) {
+ unsigned char dir0, dir0_msn, dir0_lsn, dir1 = 0;
+ char *buf = c->x86_model_id;
+ char Cx86_cb[] = "?.5x Core/Bus Clock";
+ const char cyrix_model_mult1[] = "12??43";
+ const char cyrix_model_mult2[] = "12233445";
+ const char *p = NULL;
+
+ do_cyrix_devid(&dir0, &dir1);
+ dir0_msn = dir0 >> 4; /* identifies CPU "family" */
+ dir0_lsn = dir0 & 0xf; /* model or clock multiplier */
+ c->x86_model = (dir1 >> 4) + 1;
+ c->x86_mask = dir1 & 0xf;
+ switch (dir0_msn) {
+ unsigned char tmp;
+
+ case 0: /* Cx486SLC/DLC/SRx/DRx */
+ p = Cx486_name[dir0_lsn & 7];
+ break;
+
+ case 1: /* Cx486S/DX/DX2/DX4 */
+ p = (dir0_lsn & 8) ? Cx486D_name[dir0_lsn & 5] : Cx486S_name[dir0_lsn & 3];
+ break;
+
+ case 2: /* 5x86 */
+ Cx86_cb[2] = cyrix_model_mult1[dir0_lsn & 5];
+ p = Cx86_cb+2;
+ break;
+
+ case 3: /* 6x86/6x86L */
+ Cx86_cb[1] = ' ';
+ Cx86_cb[2] = cyrix_model_mult1[dir0_lsn & 5];
+ if (dir1 > 0x21) { /* 686L */
+ Cx86_cb[0] = 'L';
+ p = Cx86_cb;
+ (c->x86_model)++;
+ } else /* 686 */
+ p = Cx86_cb+1;
+
+ c->coma_bug = 1;
+ break;
+ case 4:
+ c->x86_l1_data_cache_size = 16; /* Yep 16K integrated cache thats it */
+ if (c->cpuid_level != 2) { /* Media GX */
+ Cx86_cb[2] = (dir0_lsn & 1) ? '3' : '4';
+ p = Cx86_cb+2;
+ }
+ break;
+
+ case 5: /* 6x86MX/M II */
+ if (dir1 > 7) {
+ dir0_msn++; /* M II */
+ } else {
+ c->coma_bug = 1; /* 6x86MX, it has the bug. */
+ }
+
+ tmp = (!(dir0_lsn & 7) || dir0_lsn & 1) ? 2 : 0;
+ Cx86_cb[tmp] = cyrix_model_mult2[dir0_lsn & 7];
+ p = Cx86_cb+tmp;
+ if (((dir1 & 0x0f) > 4) || ((dir1 & 0xf0) == 0x20))
+ (c->x86_model)++;
+ break;
+
+ case 0xf: /* Cyrix 486 without DEVID registers */
+ switch (dir0_lsn) {
+ case 0xd: /* either a 486SLC or DLC w/o DEVID */
+ dir0_msn = 0;
+ p = Cx486_name[(c->hard_math) ? 1 : 0];
+ break;
+
+ case 0xe: /* a 486S A step */
+ dir0_msn = 0;
+ p = Cx486S_name[0];
+ break;
+ }
+ break;
+
+ default:
+ dir0_msn = 7;
+ break;
+ }
+
+ /* If the processor is unknown, we keep the model name we got
+ * from the generic call */
+ if (dir0_msn < 7) {
+ strcpy(buf, Cx86_model[dir0_msn & 7]);
+ if (p) strcat(buf, p);
+ }
+}
+
void generic_identify(struct cpuinfo_x86 *c)
{
uint32_t tfms, xlvl;
@@ -222,6 +379,13 @@ void generic_identify(struct cpuinfo_x86 *c)
get_model_name(c); /* Default name */
}
+ /* Specific detection code */
+ switch (c->x86_vendor) {
+ case X86_VENDOR_CYRIX:
+ case X86_VENDOR_NSC: detect_cyrix(c); break;
+ default: break;
+ }
+
/* Detecting the number of cores */
switch (c->x86_vendor) {
case X86_VENDOR_AMD:
@@ -435,17 +599,12 @@ void set_generic_info(struct cpuinfo_x86 *c, s_cpu * cpu)
void detect_cpu(s_cpu * cpu)
{
struct cpuinfo_x86 c;
+ memset(&c,0,sizeof(c));
c.x86_clflush_size = 32;
- c.x86_l1_data_cache_size = 0;
- c.x86_l1_instruction_cache_size = 0;
- c.x86_l2_cache_size = 0;
c.x86_vendor = X86_VENDOR_UNKNOWN;
c.cpuid_level = -1; /* CPUID not detected */
- c.x86_model = c.x86_mask = 0; /* So far unknown... */
c.x86_num_cores = 1;
- memset(&c.x86_capability, 0, sizeof(c.x86_capability));
- memset(&c.x86_vendor_id, 0, sizeof(c.x86_vendor_id));
- memset(&c.x86_model_id, 0, sizeof(c.x86_model_id));
+ memset(&cpu->flags, 0, sizeof(s_cpu_flags));
if (!have_cpuid_p())
return;
diff --git a/com32/gpllib/zzjson/zzjson_create.c b/com32/gpllib/zzjson/zzjson_create.c
new file mode 100644
index 00000000..7e6bd5bd
--- /dev/null
+++ b/com32/gpllib/zzjson/zzjson_create.c
@@ -0,0 +1,240 @@
+/* JSON Create ZZJSON structures
+ * ZZJSON - Copyright (C) 2008 by Ivo van Poorten
+ * License: GNU Lesser General Public License version 2.1
+ */
+
+#include "zzjson.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#ifdef CONFIG_NO_ERROR_MESSAGES
+#define ERROR(x...)
+#else
+#define ERROR(x...) config->error(config->ehandle, ##x)
+#endif
+#define MEMERROR() ERROR("out of memory")
+
+static ZZJSON *zzjson_create_templ(ZZJSON_CONFIG *config, ZZJSON_TYPE type) {
+ ZZJSON *zzjson = config->calloc(1, sizeof(ZZJSON));
+ if (!zzjson) MEMERROR();
+ else zzjson->type = type;
+ return zzjson;
+}
+
+ZZJSON *zzjson_create_true(ZZJSON_CONFIG *config) {
+ return zzjson_create_templ(config, ZZJSON_TRUE);
+}
+
+ZZJSON *zzjson_create_false(ZZJSON_CONFIG *config) {
+ return zzjson_create_templ(config, ZZJSON_FALSE);
+}
+
+ZZJSON *zzjson_create_null(ZZJSON_CONFIG *config) {
+ return zzjson_create_templ(config, ZZJSON_NULL);
+}
+
+ZZJSON *zzjson_create_number_d(ZZJSON_CONFIG *config, double d) {
+ ZZJSON *zzjson = zzjson_create_templ(config, ZZJSON_NUMBER_DOUBLE);
+ if (zzjson)
+ zzjson->value.number.val.dval = d;
+ return zzjson;
+}
+
+ZZJSON *zzjson_create_number_i(ZZJSON_CONFIG *config, long long i) {
+ ZZJSON *zzjson = zzjson_create_templ(config, ZZJSON_NUMBER_NEGINT);
+ if (zzjson) {
+ zzjson->type = i<0LL ? ZZJSON_NUMBER_NEGINT : ZZJSON_NUMBER_POSINT;
+ zzjson->value.number.val.ival = llabs(i);
+ }
+ return zzjson;
+}
+
+/* sdup mimics strdup, but avoids having another function pointer in config */
+static char *sdup(ZZJSON_CONFIG *config, char *s) {
+ size_t slen = strlen(s)+1;
+ char *scopy = config->malloc(slen);
+
+ if (!scopy) MEMERROR();
+ else memcpy(scopy, s, slen);
+ return scopy;
+}
+
+ZZJSON *zzjson_create_string(ZZJSON_CONFIG *config, char *s) {
+ ZZJSON *zzjson = NULL;
+ char *scopy;
+
+ if (!(scopy = sdup(config,s))) return zzjson;
+
+ if ((zzjson = zzjson_create_templ(config, ZZJSON_STRING)))
+ zzjson->value.string.string = scopy;
+ else
+ config->free(scopy);
+
+ return zzjson;
+}
+
+ZZJSON *zzjson_create_array(ZZJSON_CONFIG *config, ...) {
+ ZZJSON *zzjson, *retval, *val;
+ va_list ap;
+
+ if (!(zzjson = zzjson_create_templ(config, ZZJSON_ARRAY))) return zzjson;
+ retval = zzjson;
+
+ va_start(ap, config);
+ val = va_arg(ap, ZZJSON *);
+ while (val) {
+ zzjson->value.array.val = val;
+ val = va_arg(ap, ZZJSON *);
+
+ if (val) {
+ ZZJSON *next = zzjson_create_templ(config, ZZJSON_ARRAY);
+ if (!next) {
+ while (retval) {
+ next = retval->next;
+ config->free(retval);
+ retval = next;
+ }
+ break;
+ }
+ zzjson->next = next;
+ zzjson = next;
+ }
+ }
+ va_end(ap);
+ return retval;
+}
+
+ZZJSON *zzjson_create_object(ZZJSON_CONFIG *config, ...) {
+ ZZJSON *zzjson, *retval, *val;
+ char *label, *labelcopy;
+ va_list ap;
+
+ if (!(zzjson = zzjson_create_templ(config, ZZJSON_OBJECT))) return zzjson;
+ retval = zzjson;
+
+ va_start(ap, config);
+ label = va_arg(ap, char *);
+ while (label) {
+ val = va_arg(ap, ZZJSON *);
+ labelcopy = sdup(config, label);
+
+ if (!labelcopy) {
+ zzjson_free(config, retval);
+ retval = NULL;
+ break;
+ }
+
+ zzjson->value.object.label = labelcopy;
+ zzjson->value.object.val = val;
+
+ label = va_arg(ap, char *);
+
+ if (label) {
+ ZZJSON *next = zzjson_create_templ(config, ZZJSON_OBJECT);
+ if (!next) {
+ while (retval) {
+ next = retval->next;
+ config->free(retval->value.object.label);
+ config->free(retval);
+ retval = next;
+ }
+ break;
+ }
+ zzjson->next = next;
+ zzjson = next;
+ }
+ }
+ va_end(ap);
+ return retval;
+}
+
+ZZJSON *zzjson_array_prepend(ZZJSON_CONFIG *config, ZZJSON *array,
+ ZZJSON *val) {
+ ZZJSON *zzjson;
+
+ if (!array->value.array.val) { /* empty array */
+ array->value.array.val = val;
+ return array;
+ }
+
+ zzjson = zzjson_create_templ(config, ZZJSON_ARRAY);
+ if (zzjson) {
+ zzjson->value.array.val = val;
+ zzjson->next = array;
+ }
+ return zzjson;
+}
+
+ZZJSON *zzjson_array_append(ZZJSON_CONFIG *config, ZZJSON *array,
+ ZZJSON *val) {
+ ZZJSON *retval = array, *zzjson;
+
+ if (!array->value.array.val) { /* empty array */
+ array->value.array.val = val;
+ return array;
+ }
+
+ zzjson = zzjson_create_templ(config, ZZJSON_ARRAY);
+ if (!zzjson) return NULL;
+
+ while (array->next) array = array->next;
+
+ zzjson->value.array.val = val;
+ array->next = zzjson;
+
+ return retval;
+}
+
+ZZJSON *zzjson_object_prepend(ZZJSON_CONFIG *config, ZZJSON *object,
+ char *label, ZZJSON *val) {
+ ZZJSON *zzjson = NULL;
+ char *labelcopy = sdup(config, label);
+
+ if (!labelcopy) return zzjson;
+
+ if (!object->value.object.label) { /* empty object */
+ object->value.object.label = labelcopy;
+ object->value.object.val = val;
+ return object;
+ }
+
+ zzjson = zzjson_create_templ(config, ZZJSON_OBJECT);
+ if (zzjson) {
+ zzjson->value.object.label = labelcopy;
+ zzjson->value.object.val = val;
+ zzjson->next = object;
+ } else {
+ config->free(labelcopy);
+ }
+ return zzjson;
+}
+
+ZZJSON *zzjson_object_append(ZZJSON_CONFIG *config, ZZJSON *object,
+ char *label, ZZJSON *val) {
+ ZZJSON *retval = object, *zzjson = NULL;
+ char *labelcopy = sdup(config, label);
+
+ if (!labelcopy) return zzjson;
+
+ if (!object->value.object.label) { /* empty object */
+ object->value.object.label = labelcopy;
+ object->value.object.val = val;
+ return object;
+ }
+
+ zzjson = zzjson_create_templ(config, ZZJSON_OBJECT);
+ if (!zzjson) {
+ config->free(labelcopy);
+ return NULL;
+ }
+
+ while (object->next) object = object->next;
+
+ zzjson->value.object.label = labelcopy;
+ zzjson->value.object.val = val;
+ object->next = zzjson;
+
+ return retval;
+}
+
diff --git a/com32/gpllib/zzjson/zzjson_free.c b/com32/gpllib/zzjson/zzjson_free.c
new file mode 100644
index 00000000..01dfd242
--- /dev/null
+++ b/com32/gpllib/zzjson/zzjson_free.c
@@ -0,0 +1,29 @@
+/* JSON free
+ * ZZJSON - Copyright (C) 2008 by Ivo van Poorten
+ * License: GNU Lesser General Public License version 2.1
+ */
+
+#include "zzjson.h"
+
+void zzjson_free(ZZJSON_CONFIG *config, ZZJSON *zzjson) {
+ while (zzjson) {
+ ZZJSON *next;
+ switch(zzjson->type) {
+ case ZZJSON_OBJECT:
+ config->free(zzjson->value.object.label);
+ zzjson_free(config, zzjson->value.object.val);
+ break;
+ case ZZJSON_ARRAY:
+ zzjson_free(config, zzjson->value.array.val);
+ break;
+ case ZZJSON_STRING:
+ config->free(zzjson->value.string.string);
+ break;
+ default:
+ break;
+ }
+ next = zzjson->next;
+ config->free(zzjson);
+ zzjson = next;
+ }
+}
diff --git a/com32/gpllib/zzjson/zzjson_parse.c b/com32/gpllib/zzjson/zzjson_parse.c
new file mode 100644
index 00000000..ecb6f61e
--- /dev/null
+++ b/com32/gpllib/zzjson/zzjson_parse.c
@@ -0,0 +1,490 @@
+/* JSON Parser
+ * ZZJSON - Copyright (C) 2008-2009 by Ivo van Poorten
+ * License: GNU Lesser General Public License version 2.1
+ */
+
+#include "zzjson.h"
+#include <ctype.h>
+#include <string.h>
+#include <math.h>
+#include <stdio.h>
+
+#define GETC() config->getchar(config->ihandle)
+#define UNGETC(c) config->ungetchar(c, config->ihandle)
+#define SKIPWS() skipws(config)
+#ifdef CONFIG_NO_ERROR_MESSAGES
+#define ERROR(x...)
+#else
+#define ERROR(x...) config->error(config->ehandle, ##x)
+#endif
+#define MEMERROR() ERROR("out of memory")
+
+#define ALLOW_EXTRA_COMMA (config->strictness & ZZJSON_ALLOW_EXTRA_COMMA)
+#define ALLOW_ILLEGAL_ESCAPE (config->strictness & ZZJSON_ALLOW_ILLEGAL_ESCAPE)
+#define ALLOW_CONTROL_CHARS (config->strictness & ZZJSON_ALLOW_CONTROL_CHARS)
+#define ALLOW_GARBAGE_AT_END (config->strictness & ZZJSON_ALLOW_GARBAGE_AT_END)
+#define ALLOW_COMMENTS (config->strictness & ZZJSON_ALLOW_COMMENTS)
+
+static ZZJSON *parse_array(ZZJSON_CONFIG *config);
+static ZZJSON *parse_object(ZZJSON_CONFIG *config);
+
+static void skipws(ZZJSON_CONFIG *config) {
+ int d, c = GETC();
+morews:
+ while (isspace(c)) c = GETC();
+ if (!ALLOW_COMMENTS) goto endws;
+ if (c != '/') goto endws;
+ d = GETC();
+ if (d != '*') goto endws; /* pushing back c will generate a parse error */
+ c = GETC();
+morecomments:
+ while (c != '*') {
+ if (c == EOF) goto endws;
+ c = GETC();
+ }
+ c = GETC();
+ if (c != '/') goto morecomments;
+ c = GETC();
+ if (isspace(c) || c == '/') goto morews;
+endws:
+ UNGETC(c);
+}
+
+static char *parse_string(ZZJSON_CONFIG *config) {
+ unsigned int len = 16, pos = 0;
+ int c;
+ char *str = NULL;
+
+ SKIPWS();
+ c = GETC();
+ if (c != '"') {
+ ERROR("string: expected \" at the start");
+ return NULL;
+ }
+
+ str = config->malloc(len);
+ if (!str) {
+ MEMERROR();
+ return NULL;
+ }
+ c = GETC();
+ while (c > 0 && c != '"') {
+ if (!ALLOW_CONTROL_CHARS && c >= 0 && c <= 31) {
+ ERROR("string: control characters not allowed");
+ goto errout;
+ }
+ if (c == '\\') {
+ c = GETC();
+ switch (c) {
+ case 'b': c = '\b'; break;
+ case 'f': c = '\f'; break;
+ case 'n': c = '\n'; break;
+ case 'r': c = '\r'; break;
+ case 't': c = '\t'; break;
+ case 'u': {
+ UNGETC(c); /* ignore \uHHHH, copy verbatim */
+ c = '\\';
+ break;
+ }
+ case '\\': case '/': case '"':
+ break;
+ default:
+ if (!ALLOW_ILLEGAL_ESCAPE) {
+ ERROR("string: illegal escape character");
+ goto errout;
+ }
+ }
+ }
+ str[pos++] = c;
+ if (pos == len-1) {
+ void *tmp = str;
+ len *= 2;
+ str = config->realloc(str, len);
+ if (!str) {
+ MEMERROR();
+ str = tmp;
+ goto errout;
+ }
+ }
+ c = GETC();
+ }
+ if (c != '"') {
+ ERROR("string: expected \" at the end");
+ goto errout;
+ }
+ str[pos] = 0;
+ return str;
+
+errout:
+ config->free(str);
+ return NULL;
+}
+
+static ZZJSON *parse_string2(ZZJSON_CONFIG *config) {
+ ZZJSON *zzjson = NULL;
+ char *str;
+
+ str = parse_string(config);
+ if (str) {
+ zzjson = config->calloc(1, sizeof(ZZJSON));
+ if (!zzjson) {
+ MEMERROR();
+ config->free(str);
+ return NULL;
+ }
+ zzjson->type = ZZJSON_STRING;
+ zzjson->value.string.string = str;
+ }
+ return zzjson;
+}
+
+static ZZJSON *parse_number(ZZJSON_CONFIG *config) {
+ ZZJSON *zzjson;
+ unsigned long long ival = 0, expo = 0;
+ double dval = 0.0, frac = 0.0, fracshft = 10.0;
+ int c, dbl = 0, sign = 1, signexpo = 1;
+
+ SKIPWS();
+ c = GETC();
+ if (c == '-') {
+ sign = -1;
+ c = GETC();
+ }
+ if (c == '0') {
+ c = GETC();
+ goto skip;
+ }
+
+ if (!isdigit(c)) {
+ ERROR("number: digit expected");
+ return NULL;
+ }
+
+ while (isdigit(c)) {
+ ival *= 10;
+ ival += c - '0';
+ c = GETC();
+ }
+
+skip:
+ if (c != '.') goto skipfrac;
+
+ dbl = 1;
+
+ c = GETC();
+ if (!isdigit(c)) {
+ ERROR("number: digit expected");
+ return NULL;
+ }
+
+ while (isdigit(c)) {
+ frac += (double)(c - '0') / fracshft;
+ fracshft *= 10.0;
+ c = GETC();
+ }
+
+skipfrac:
+ if (c != 'e' && c != 'E') goto skipexpo;
+
+ dbl = 1;
+
+ c = GETC();
+ if (c == '+')
+ c = GETC();
+ else if (c == '-') {
+ signexpo = -1;
+ c = GETC();
+ }
+
+ if (!isdigit(c)) {
+ ERROR("number: digit expected");
+ return NULL;
+ }
+
+ while (isdigit(c)) {
+ expo *= 10;
+ expo += c - '0';
+ c = GETC();
+ }
+
+skipexpo:
+ UNGETC(c);
+
+ if (dbl) {
+ dval = sign * (long long) ival;
+ dval += sign * frac;
+ dval *= pow(10.0, (double) signexpo * expo);
+ }
+
+ zzjson = config->calloc(1, sizeof(ZZJSON));
+ if (!zzjson) {
+ MEMERROR();
+ return NULL;
+ }
+ if (dbl) {
+ zzjson->type = ZZJSON_NUMBER_DOUBLE;
+ zzjson->value.number.val.dval = dval;
+ } else {
+ zzjson->type = sign < 0 ? ZZJSON_NUMBER_NEGINT : ZZJSON_NUMBER_POSINT;
+ zzjson->value.number.val.ival = ival;
+ }
+
+ return zzjson;
+}
+
+static ZZJSON *parse_literal(ZZJSON_CONFIG *config, char *s, ZZJSON_TYPE t) {
+ char b[strlen(s)+1];
+ unsigned int i;
+
+ for (i=0; i<strlen(s); i++) b[i] = GETC();
+ b[i] = 0;
+
+ if (!strcmp(b,s)) {
+ ZZJSON *zzjson;
+ zzjson = config->calloc(1, sizeof(ZZJSON));
+ if (!zzjson) {
+ MEMERROR();
+ return NULL;
+ }
+ zzjson->type = t;
+ return zzjson;
+ }
+ ERROR("literal: expected %s", s);
+ return NULL;
+}
+
+static ZZJSON *parse_true(ZZJSON_CONFIG *config) {
+ return parse_literal(config, (char *)"true", ZZJSON_TRUE);
+}
+
+static ZZJSON *parse_false(ZZJSON_CONFIG *config) {
+ return parse_literal(config, (char *)"false", ZZJSON_FALSE);
+}
+
+static ZZJSON *parse_null(ZZJSON_CONFIG *config) {
+ return parse_literal(config, (char *)"null", ZZJSON_NULL);
+}
+
+static ZZJSON *parse_value(ZZJSON_CONFIG *config) {
+ ZZJSON *retval = NULL;
+ int c;
+
+ SKIPWS();
+ c = GETC();
+ UNGETC(c);
+ switch (c) {
+ case '"': retval = parse_string2(config); break;
+ case '0': case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9': case '-':
+ retval = parse_number(config); break;
+ case '{': retval = parse_object(config); break;
+ case '[': retval = parse_array(config); break;
+ case 't': retval = parse_true(config); break;
+ case 'f': retval = parse_false(config); break;
+ case 'n': retval = parse_null(config); break;
+ }
+
+ if (!retval) {
+ ERROR("value: invalid value");
+ return retval;
+ }
+
+ return retval;
+}
+
+static ZZJSON *parse_array(ZZJSON_CONFIG *config) {
+ ZZJSON *retval = NULL, **next = &retval;
+ int c;
+
+ SKIPWS();
+ c = GETC();
+ if (c != '[') {
+ ERROR("array: expected '['");
+ return NULL;
+ }
+
+ SKIPWS();
+ c = GETC();
+ while (c > 0 && c != ']') {
+ ZZJSON *zzjson = NULL, *val = NULL;
+
+ UNGETC(c);
+
+ SKIPWS();
+ val = parse_value(config);
+ if (!val) {
+ ERROR("array: value expected");
+ goto errout;
+ }
+
+ SKIPWS();
+ c = GETC();
+ if (c != ',' && c != ']') {
+ ERROR("array: expected ',' or ']'");
+errout_with_val:
+ zzjson_free(config, val);
+ goto errout;
+ }
+ if (c == ',') {
+ SKIPWS();
+ c = GETC();
+ if (c == ']' && !ALLOW_EXTRA_COMMA) {
+ ERROR("array: expected value after ','");
+ goto errout_with_val;
+ }
+ }
+ UNGETC(c);
+
+ zzjson = config->calloc(1, sizeof(ZZJSON));
+ if (!zzjson) {
+ MEMERROR();
+ zzjson_free(config, val);
+ goto errout_with_val;
+ }
+ zzjson->type = ZZJSON_ARRAY;
+ zzjson->value.array.val = val;
+ *next = zzjson;
+ next = &zzjson->next;
+
+ c = GETC();
+ }
+
+ if (c != ']') {
+ ERROR("array: expected ']'");
+ goto errout;
+ }
+
+ if (!retval) { /* empty array, [ ] */
+ retval = config->calloc(1, sizeof(ZZJSON));
+ if (!retval) {
+ MEMERROR();
+ return NULL;
+ }
+ retval->type = ZZJSON_ARRAY;
+ }
+
+ return retval;
+
+errout:
+ zzjson_free(config, retval);
+ return NULL;
+}
+
+static ZZJSON *parse_object(ZZJSON_CONFIG *config) {
+ ZZJSON *retval = NULL;
+ int c;
+ ZZJSON **next = &retval;
+
+ SKIPWS();
+ c = GETC();
+ if (c != '{') {
+ ERROR("object: expected '{'");
+ return NULL;
+ }
+
+ SKIPWS();
+ c = GETC();
+ while (c > 0 && c != '}') {
+ ZZJSON *zzjson = NULL, *val = NULL;
+ char *str;
+
+ UNGETC(c);
+
+ str = parse_string(config);
+ if (!str) {
+ ERROR("object: expected string");
+errout_with_str:
+ config->free(str);
+ goto errout;
+ }
+
+ SKIPWS();
+ c = GETC();
+ if (c != ':') {
+ ERROR("object: expected ':'");
+ goto errout_with_str;
+ }
+
+ SKIPWS();
+ val = parse_value(config);
+ if (!val) {
+ ERROR("object: value expected");
+ goto errout_with_str;
+ }
+
+ SKIPWS();
+ c = GETC();
+ if (c != ',' && c != '}') {
+ ERROR("object: expected ',' or '}'");
+errout_with_str_and_val:
+ zzjson_free(config, val);
+ goto errout_with_str;
+ }
+ if (c == ',') {
+ SKIPWS();
+ c = GETC();
+ if (c == '}' && !ALLOW_EXTRA_COMMA) {
+ ERROR("object: expected pair after ','");
+ goto errout_with_str_and_val;
+ }
+ }
+ UNGETC(c);
+
+ zzjson = config->calloc(1, sizeof(ZZJSON));
+ if (!zzjson) {
+ MEMERROR();
+ goto errout_with_str_and_val;
+ }
+ zzjson->type = ZZJSON_OBJECT;
+ zzjson->value.object.label = str;
+ zzjson->value.object.val = val;
+ *next = zzjson;
+ next = &zzjson->next;
+
+ c = GETC();
+ }
+
+ if (c != '}') {
+ ERROR("object: expected '}'");
+ goto errout;
+ }
+
+ if (!retval) { /* empty object, { } */
+ retval = config->calloc(1, sizeof(ZZJSON));
+ if (!retval) {
+ MEMERROR();
+ return NULL;
+ }
+ retval->type = ZZJSON_OBJECT;
+ }
+
+ return retval;
+
+errout:
+ zzjson_free(config, retval);
+ return NULL;
+}
+
+ZZJSON *zzjson_parse(ZZJSON_CONFIG *config) {
+ ZZJSON *retval;
+ int c;
+
+ SKIPWS();
+ c = GETC();
+ UNGETC(c);
+ if (c == '[') retval = parse_array(config);
+ else if (c == '{') retval = parse_object(config);
+ else { ERROR("expected '[' or '{'"); return NULL; }
+
+ if (!retval) return NULL;
+
+ SKIPWS();
+ c = GETC();
+ if (c >= 0 && !ALLOW_GARBAGE_AT_END) {
+ ERROR("parse: garbage at end of file");
+ zzjson_free(config, retval);
+ return NULL;
+ }
+
+ return retval;
+}
diff --git a/com32/gpllib/zzjson/zzjson_print.c b/com32/gpllib/zzjson/zzjson_print.c
new file mode 100644
index 00000000..a59b3b09
--- /dev/null
+++ b/com32/gpllib/zzjson/zzjson_print.c
@@ -0,0 +1,110 @@
+/* JSON Printer
+ * ZZJSON - Copyright (C) 2008 by Ivo van Poorten
+ * License: GNU Lesser General Public License version 2.1
+ */
+
+#include "zzjson.h"
+
+#define PRINT(fmt...) if (config->print(config->ohandle, ##fmt) < 0) return -1;
+//#define PUTC(c) if (config->putchar(c, config->ohandle) < 0) return -1;
+#define PUTC(c) PRINT("%c",c)
+#define INC 4
+
+static int print_string(ZZJSON_CONFIG *config, char *s) {
+ int c, bs;
+ if (!s) return 0;
+ while ((c = *s++)) {
+ bs = 1;
+ switch (c) {
+// case '/': // useless escape of forward slash
+ case '\\':
+ if (*s == 'u') bs = 0; // copy \uHHHH verbatim
+ break;
+ case '"': break;
+ case '\b': c = 'b'; break;
+ case '\f': c = 'f'; break;
+ case '\n': c = 'n'; break;
+ case '\r': c = 'r'; break;
+ case '\t': c = 't'; break;
+ default: bs = 0; break;
+ }
+ if (bs) PUTC('\\');
+ PUTC(c);
+ }
+ return 0;
+}
+
+static int zzjson_print2(ZZJSON_CONFIG *config, ZZJSON *zzjson,
+ unsigned int indent, unsigned int objval) {
+ char c = 0, d = 0;
+ if (!zzjson) return -1;
+
+ switch(zzjson->type) {
+ case ZZJSON_OBJECT: c = '{'; d = '}'; break;
+ case ZZJSON_ARRAY: c = '['; d = ']'; break;
+ default: break;
+ }
+
+ if (c) PRINT("%s%*s%c", indent ? "\n" : "", indent, "", c);
+
+ while (zzjson) {
+ switch(zzjson->type) {
+ case ZZJSON_OBJECT:
+ if (zzjson->value.object.val) {
+ PRINT("\n%*s\"", indent+INC, "");
+ if (print_string(config, zzjson->value.object.label) < 0)
+ return -1;
+ PRINT("\" :");
+ if (zzjson_print2(config, zzjson->value.object.val,
+ indent+INC, 1) < 0) return -1;
+ }
+ break;
+ case ZZJSON_ARRAY:
+ if (zzjson->value.array.val)
+ if (zzjson_print2(config, zzjson->value.array.val,
+ indent+INC, 0) < 0) return -1;
+ break;
+ case ZZJSON_STRING:
+ PRINT(objval ? " \"" : "\n%*s\"", indent, "");
+ if (print_string(config, zzjson->value.string.string)<0) return -1;
+ PUTC('"');
+ break;
+ case ZZJSON_FALSE:
+ PRINT(objval ? " false" : "\n%*sfalse", indent, "");
+ break;
+ case ZZJSON_NULL:
+ PRINT(objval ? " null" : "\n%*snull", indent, "");
+ break;
+ case ZZJSON_TRUE:
+ PRINT(objval ? " true" : "\n%*strue", indent, "");
+ break;
+ case ZZJSON_NUMBER_NEGINT:
+ case ZZJSON_NUMBER_POSINT:
+ case ZZJSON_NUMBER_DOUBLE:
+ PRINT(objval ? " " : "\n%*s", indent, "");
+ if (zzjson->type == ZZJSON_NUMBER_DOUBLE) {
+ PRINT("%16.16e", zzjson->value.number.val.dval);
+ } else {
+ if (zzjson->type == ZZJSON_NUMBER_NEGINT) PUTC('-');
+ PRINT("%llu", zzjson->value.number.val.ival);
+ }
+ default:
+ break;
+ }
+ zzjson = zzjson->next;
+ if (zzjson) PUTC(',');
+ }
+
+ if (d) PRINT("\n%*s%c", indent, "", d);
+
+ return 0;
+}
+
+int zzjson_print(ZZJSON_CONFIG *config, ZZJSON *zzjson) {
+ int retval = zzjson_print2(config, zzjson, 0, 0);
+// if (retval >= 0) retval = config->putchar('\n', config->ohandle);
+#ifndef CONFIG_NO_ERROR_MESSAGES
+ if (retval < 0) config->error(config->ehandle, "print: unable to print");
+#endif
+ return retval;
+}
diff --git a/com32/gpllib/zzjson/zzjson_query.c b/com32/gpllib/zzjson/zzjson_query.c
new file mode 100644
index 00000000..35ba7b79
--- /dev/null
+++ b/com32/gpllib/zzjson/zzjson_query.c
@@ -0,0 +1,63 @@
+/* JSON query
+ * ZZJSON - Copyright (C) 2008 by Ivo van Poorten
+ * License: GNU Lesser General Public License version 2.1
+ */
+
+#include "zzjson.h"
+#include <string.h>
+#include <stdarg.h>
+
+ZZJSON *zzjson_object_find_label(ZZJSON *zzjson, char *label) {
+ if (zzjson->type != ZZJSON_OBJECT) return NULL;
+
+ while (zzjson) {
+ char *string = zzjson->value.object.label;
+
+ if (zzjson->type != ZZJSON_OBJECT) return NULL;
+ if (!string) return NULL;
+
+ if (!strcmp(string, label))
+ return zzjson->value.object.val;
+ zzjson = zzjson->next;
+ }
+ return NULL;
+}
+
+ZZJSON *zzjson_object_find_labels(ZZJSON *zzjson, ...) {
+ va_list ap;
+ char *lbl;
+
+ va_start(ap, zzjson);
+ lbl = va_arg(ap, char *);
+ while (lbl) {
+ zzjson = zzjson_object_find_label(zzjson, lbl);
+ if (!zzjson) break;
+ lbl = va_arg(ap, char *);
+ }
+ va_end(ap);
+
+ return zzjson;
+}
+
+unsigned int zzjson_object_count(ZZJSON *zzjson) {
+ unsigned int count = 1;
+
+ if (zzjson->type != ZZJSON_OBJECT) return 0;
+ if (!zzjson->value.object.label) return 0; /* empty { } */
+
+ while ((zzjson = zzjson->next)) count++;
+
+ return count;
+}
+
+unsigned int zzjson_array_count(ZZJSON *zzjson) {
+ unsigned int count = 1;
+
+ if (zzjson->type != ZZJSON_ARRAY) return 0;
+ if (!zzjson->value.array.val) return 0; /* empty [ ] */
+
+ while ((zzjson = zzjson->next)) count++;
+
+ return count;
+}
+
diff --git a/com32/hdt/Makefile b/com32/hdt/Makefile
index 40ea3ac4..f1873465 100644
--- a/com32/hdt/Makefile
+++ b/com32/hdt/Makefile
@@ -16,11 +16,11 @@
##
topdir = ../..
-include ../MCONFIG
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/com32.mk
-LIBS = ../cmenu/libmenu/libmenu.a ../libutil/libutil_com.a \
- ../lib/libcom32.a $(LIBGCC)
-CFLAGS += -I$(com32)/cmenu/libmenu
+LIBS = ../cmenu/libmenu/libmenu.a ../libupload/libcom32upload.a
+CFLAGS += -I$(com32)/cmenu/libmenu -I$(com32)
MODULES = hdt.c32
TESTFILES =
@@ -28,7 +28,8 @@ TESTFILES =
OBJS = $(patsubst %.c,%.o,$(wildcard *.c))
VERSION = $(shell $(SED) -n 's/\#define VERSION \"\(.*\)\"/\1/p' hdt.h)
CODENAME = $(shell $(SED) -n 's/\#define CODENAME \"\(.*\)\"/\1/p' hdt.h)
-VERSION_C32 = $(shell echo $(VERSION) | $(SED) -e 's/-/_/g' | $(SED) -e 's/\./_/g')
+NODASH_VERSION = $(shell echo $(VERSION) | $(SED) -e 's/-/_/g' | $(SED) -e 's/\./_/g')
+SUM_FILE = hdt-$(VERSION).checksums
MEMTEST_URL = http://memtest.org/download/4.20/memtest86+-4.20.bin
MEMTEST = memtest.bin
@@ -44,6 +45,7 @@ FLOPPY_DIR ?= floppy
PCI_IDS_FILE ?= $(PWD)/$(FLOPPY_DIR)/pci.ids
GZ_PCI_IDS_FILE ?= $(PCI_IDS_FILE).gz
MENU_COM32 ?= $(com32)/menu/menu.c32
+CHAIN_COM32 ?= $(com32)/modules/chain.c32
ART_DIR ?= art/
QEMU ?= qemu-kvm
@@ -55,11 +57,11 @@ hdt.elf : $(OBJS) $(LIBS) $(C_LIBS)
memtest:
-[ ! -f $(FLOPPY_DIR)/$(MEMTEST) ] && $(WGET) $(MEMTEST_URL) -O $(FLOPPY_DIR)/$(MEMTEST)
-hdt.img: hdt.c32 $(FLOPPY_DIR)/hdt.cfg $(FLOPPY_DIR)/mtools.conf $(topdir)/mtools/syslinux $(MENU_COM32) memtest
+hdt.img: hdt.c32 $(FLOPPY_DIR)/hdt.cfg $(FLOPPY_DIR)/mtools.conf $(topdir)/mtools/syslinux $(MENU_COM32) memtest $(CHAIN_COM32)
rm -f hdt*.img
$(SED) -e 's/%VERSION%/$(VERSION)/g' $(FLOPPY_DIR)/hdt.cfg |\
$(SED) -e 's/%CODENAME%/$(CODENAME)/g' > $(FLOPPY_DIR)/syslinux.cfg
- MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MFORMAT) -v HDT_$(VERSION) -f 1440 -C a:
+ MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MFORMAT) -v HDT_$(NODASH_VERSION) -f 1440 -C a:
$(topdir)/mtools/syslinux hdt.img
-[ ! -f $(GZ_PCI_IDS_FILE) ] && cp /usr/share/hwdata/pci.ids $(PCI_IDS_FILE) && $(GZIPPROG) $(PCI_IDS_FILE)
-[ ! -f $(GZ_PCI_IDS_FILE) ] && cp /usr/share/pci.ids $(PCI_IDS_FILE) && $(GZIPPROG) $(PCI_IDS_FILE)
@@ -67,6 +69,7 @@ hdt.img: hdt.c32 $(FLOPPY_DIR)/hdt.cfg $(FLOPPY_DIR)/mtools.conf $(topdir)/mtool
-[ -f $(MODULES_PCIMAP_FILE) ] && cat $(MODULES_PCIMAP_FILE) | $(GZIPPROG) - -f | MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) - a:modules.pcimap
MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) hdt.c32 a:
MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(MENU_COM32) a:
+ MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(CHAIN_COM32) a:
@ [ -f $(GZ_PCI_IDS_FILE) ] && MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(GZ_PCI_IDS_FILE) a:pci.ids || printf "\nThe $(GZ_PCI_IDS_FILE) file is missing and can be downloaded from http://pciids.sourceforge.net and gzipped in\nthe ./com32/hdt/$(FLOPPY_DIR) directory of the extracted Syslinux source.\n\n"
MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(FLOPPY_DIR)/syslinux.cfg a:
MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(FLOPPY_DIR)/$(MEMTEST) a:
@@ -89,6 +92,7 @@ hdt.iso: hdt.c32 $(topdir)/core/isolinux.bin $(FLOPPY_DIR)/hdt.cfg memtest
cp hdt.c32 $(ISO_DIR)/$(ISOLINUX_DIR)
cp $(FLOPPY_DIR)/$(MEMTEST) $(ISO_DIR)/$(ISOLINUX_DIR)
cp $(MENU_COM32) $(ISO_DIR)/$(ISOLINUX_DIR)
+ cp $(CHAIN_COM32) $(ISO_DIR)/$(ISOLINUX_DIR)
cp -av $(ART_DIR)/backgnd.png $(ISO_DIR)/$(ISOLINUX_DIR)
-[ ! -f $(GZ_PCI_IDS_FILE) ] && cp /usr/share/hwdata/pci.ids $(PCI_IDS_FILE) && $(GZIPPROG) $(PCI_IDS_FILE)
-[ ! -f $(GZ_PCI_IDS_FILE) ] && cp /usr/share/pci.ids $(PCI_IDS_FILE) && $(GZIPPROG) $(PCI_IDS_FILE)
@@ -107,7 +111,11 @@ hdt.iso: hdt.c32 $(topdir)/core/isolinux.bin $(FLOPPY_DIR)/hdt.cfg memtest
ln -sf hdt-$(VERSION).iso hdt.iso
release: spotless hdt.c32 hdt.img hdt.img.gz hdt.iso
- mv hdt.c32 hdt_$(VERSION_C32).c32
+ mv hdt.c32 hdt_$(NODASH_VERSION).c32
+ md5sum hdt_$(NODASH_VERSION).c32 >$(SUM_FILE)
+ md5sum hdt-$(VERSION).iso >>$(SUM_FILE)
+ md5sum hdt-$(VERSION).img >>$(SUM_FILE)
+ md5sum hdt-$(VERSION).img.gz >>$(SUM_FILE)
test: hdt.img
$(QEMU) -fda hdt.img
@@ -123,6 +131,7 @@ spotless: clean
rm -rf $(ISO_DIR)
rm -rf $(FLOPPY_DIR)/$(MEMTEST)
rm -rf $(FLOPPY_DIR)/pci.ids*
+ rm -rf hdt-*checksums
rm -f *~ \#*
install:
diff --git a/com32/hdt/floppy/hdt.cfg b/com32/hdt/floppy/hdt.cfg
index f72a2134..c876d239 100644
--- a/com32/hdt/floppy/hdt.cfg
+++ b/com32/hdt/floppy/hdt.cfg
@@ -77,6 +77,15 @@ ENDTEXT
COM32 hdt.c32
APPEND modules_pcimap=modules.pcimap modules_alias=modules.alias pciids=pci.ids verbose nomenu
+LABEL dump
+MENU LABEL Dump hardware config to TFTP server
+TEXT HELP
+ Starts HDT using the Command Line Interface (CLI) and run 'dump'
+ VESA mode is enabled
+ENDTEXT
+COM32 hdt.c32
+APPEND modules_pcimap=modules.pcimap modules_alias=modules.alias pciids=pci.ids quiet vesa nomenu auto='dump'
+
MENU SEPARATOR
LABEL memtest
diff --git a/com32/hdt/hdt-cli-acpi.c b/com32/hdt/hdt-cli-acpi.c
index 1b608c26..a978bb36 100644
--- a/com32/hdt/hdt-cli-acpi.c
+++ b/com32/hdt/hdt-cli-acpi.c
@@ -37,7 +37,7 @@
/* Print ACPI's table header in a defined formating */
static void show_header(void *address, s_acpi_description_header * h)
{
- more_printf("%-4s v%03x %-6s %-7s 0x%08x %-4s 0x%08x @ 0x%p\n",
+ more_printf("%-4s v%03x %-6s %-8s 0x%08x %-7s 0x%08x @ 0x%p\n",
h->signature, h->revision, h->oem_id, h->oem_table_id,
h->oem_revision, h->creator_id, h->creator_revision, address)
}
@@ -158,25 +158,6 @@ static void show_local_apic(s_madt * madt)
}
}
-/* M1PS flags have to be interpreted as strings */
-static char *flags_to_string(char *buffer, uint16_t flags)
-{
- memset(buffer, 0, sizeof(buffer));
- strcpy(buffer, "default");
- if ((flags & POLARITY_ACTIVE_HIGH) == POLARITY_ACTIVE_HIGH)
- strcpy(buffer, "high");
- else if ((flags & POLARITY_ACTIVE_LOW) == POLARITY_ACTIVE_LOW)
- strcpy(buffer, "low");
- if ((flags & TRIGGER_EDGE) == TRIGGER_EDGE)
- strncat(buffer, " edge", 5);
- else if ((flags & TRIGGER_LEVEL) == TRIGGER_LEVEL)
- strncat(buffer, " level", 6);
- else
- strncat(buffer, " default", 8);
-
- return buffer;
-}
-
/* Display the local apic NMI configuration */
static void show_local_apic_nmi(s_madt * madt)
{
@@ -225,7 +206,7 @@ static void show_io_apic(s_madt * madt)
break;
}
- more_printf("IO_APIC[%d] : apic_id[0x%02x] adress[0x%08x] %s\n",
+ more_printf("IO_APIC[%d] : apic_id[0x%02x] address[0x%08x] %s\n",
i, sio->io_apic_id, sio->io_apic_address, buffer);
}
}
diff --git a/com32/hdt/hdt-cli-hdt.c b/com32/hdt/hdt-cli-hdt.c
index 65068232..e9752612 100644
--- a/com32/hdt/hdt-cli-hdt.c
+++ b/com32/hdt/hdt-cli-hdt.c
@@ -250,6 +250,15 @@ static void do_reboot(int argc __unused, char **argv __unused,
syslinux_reboot(1);
}
+/**
+ * do_dump - dump info
+ **/
+static void do_dump(int argc __unused, char **argv __unused,
+ struct s_hardware *hardware)
+{
+ dump(hardware);
+}
+
/* Default hdt mode */
struct cli_callback_descr list_hdt_default_modules[] = {
{
@@ -277,6 +286,10 @@ struct cli_callback_descr list_hdt_default_modules[] = {
.exec = print_history,
},
{
+ .name = CLI_DUMP,
+ .exec = do_dump,
+ },
+ {
.name = NULL,
.exec = NULL},
};
diff --git a/com32/hdt/hdt-cli.c b/com32/hdt/hdt-cli.c
index 8b5335eb..330f93c4 100644
--- a/com32/hdt/hdt-cli.c
+++ b/com32/hdt/hdt-cli.c
@@ -738,8 +738,7 @@ void start_auto_mode(struct s_hardware *hardware)
int nb_commands = 0;
char *commands[MAX_NB_AUTO_COMMANDS];
- if (!quiet)
- more_printf("\nEntering Auto mode\n");
+ more_printf("\nEntering Auto mode\n");
/* Protecting the auto_label from the strtok modifications */
char *temp = strdup(hardware->auto_label);
diff --git a/com32/hdt/hdt-cli.h b/com32/hdt/hdt-cli.h
index 13291092..68b33158 100644
--- a/com32/hdt/hdt-cli.h
+++ b/com32/hdt/hdt-cli.h
@@ -65,6 +65,7 @@
#define CLI_ACPI "acpi"
#define CLI_ENABLE "enable"
#define CLI_DISABLE "disable"
+#define CLI_DUMP "dump"
typedef enum {
INVALID_MODE,
diff --git a/com32/hdt/hdt-common.c b/com32/hdt/hdt-common.c
index f1557b86..aac50eb9 100644
--- a/com32/hdt/hdt-common.c
+++ b/com32/hdt/hdt-common.c
@@ -106,6 +106,12 @@ void detect_parameters(const int argc, const char *argv[],
max_console_lines = MAX_CLI_LINES;
} else if (!strncmp(argv[i], "nomenu", 6)) {
menumode = false;
+ } else if (!strncmp(argv[i], "dump_path=", 10)) {
+ strlcpy(hardware->dump_path, argv[i] + 10,
+ sizeof(hardware->dump_path));
+ } else if (!strncmp(argv[i], "tftp_ip=", 8)) {
+ strlcpy(hardware->tftp_ip, argv[i] + 8,
+ sizeof(hardware->tftp_ip));
} else if (!strncmp(argv[i], "auto=", 5)) {
/* The auto= parameter is separated in several argv[]
* as it can contains spaces.
@@ -115,25 +121,19 @@ void detect_parameters(const int argc, const char *argv[],
*/
automode=true;
+ char *argument = (char*)argv[i]+6;
/* Extracting the first parameter */
- strcpy(hardware->auto_label, argv[i] + 6);
- strcat(hardware->auto_label, " ");
- char *pos;
- i++;
+ strcpy(hardware->auto_label, argument);
/* While we can't find the other AUTO_DELIMITER, let's process the argv[] */
- while (((pos = strstr(argv[i], AUTO_DELIMITER)) == NULL)
- && (i < argc)) {
- strcat(hardware->auto_label, argv[i]);
- strcat(hardware->auto_label, " ");
+ while ((strchr(argument, AUTO_DELIMITER) == NULL) && (i+1<argc)) {
i++;
- }
+ argument = (char *)argv[i];
+ strcat(hardware->auto_label, " ");
+ strcat(hardware->auto_label, argument);
+ }
- /* If we didn't reach the end of the line, let's grab the last item */
- if (i < argc) {
- strcat(hardware->auto_label, argv[i]);
- hardware->auto_label[strlen(hardware->auto_label) - 1] = 0;
- }
+ hardware->auto_label[strlen(hardware->auto_label) - 1] = 0;
}
}
}
@@ -203,7 +203,10 @@ void init_hardware(struct s_hardware *hardware)
sizeof hardware->modules_alias_path);
memset(hardware->memtest_label, 0, sizeof hardware->memtest_label);
memset(hardware->auto_label, 0, sizeof hardware->auto_label);
+ memset(hardware->dump_path, 0, sizeof hardware->dump_path);
memset(hardware->vesa_background, 0, sizeof hardware->vesa_background);
+ memset(hardware->tftp_ip, 0, sizeof hardware->tftp_ip);
+ strcat(hardware->dump_path, "hdt");
strcat(hardware->pciids_path, "pci.ids");
strcat(hardware->modules_pcimap_path, "modules.pcimap");
strcat(hardware->modules_alias_path, "modules.alias");
@@ -652,7 +655,7 @@ char *del_multi_spaces(char *p)
* As we search for a double spacing
* we have to be sure then string is
* long enough to be processed */
- while (*p && *p + 1) {
+ while (*p && *(p + 1)) {
/* If we have two consecutive spaces */
if ((*p == ' ') && (*(p + 1) == ' ')) {
diff --git a/com32/hdt/hdt-common.h b/com32/hdt/hdt-common.h
index df7d2c98..d37fcc8a 100644
--- a/com32/hdt/hdt-common.h
+++ b/com32/hdt/hdt-common.h
@@ -48,16 +48,18 @@
#include "cpuid.h"
#include "dmi/dmi.h"
#include "hdt-ata.h"
-#include "../lib/sys/vesa/vesa.h"
+#include <lib/sys/vesa/vesa.h>
#include <vpd/vpd.h>
#include <libansi.h>
#include <acpi/acpi.h>
+#include <libupload/upload_backend.h>
/* Declare a variable or data structure as unused. */
#define __unused __attribute__ (( unused ))
/* This two values are used for switching for the menu to the CLI mode */
#define HDT_SWITCH_TO_CLI "hdt_switch_to_cli"
+#define HDT_DUMP "hdt_dump"
#define HDT_RETURN_TO_CLI 100
#define MAX_VESA_MODES 255
@@ -71,7 +73,7 @@
/* The char that separate two commands */
#define AUTO_SEPARATOR ";"
/* The char that surround the list of commands */
-#define AUTO_DELIMITER "'"
+#define AUTO_DELIMITER '\''
/* Graphic to load in background when using the vesa mode */
#define CLI_DEFAULT_BACKGROUND "backgnd.png"
@@ -80,6 +82,8 @@
#define MAX_CLI_LINES 20
#define MAX_VESA_CLI_LINES 24
+struct upload_backend *upload;
+
/* Defines if the cli is quiet*/
bool quiet;
@@ -209,6 +213,8 @@ struct s_hardware {
char modules_pcimap_path[255];
char modules_alias_path[255];
char pciids_path[255];
+ char dump_path[255]; /* Dump path on the tftp server */
+ char tftp_ip[255]; /* IP address of tftp server (dump mode) */
char memtest_label[255];
char auto_label[AUTO_COMMAND_SIZE];
char vesa_background[255];
@@ -236,4 +242,5 @@ int detect_vesa(struct s_hardware *hardware);
void detect_memory(struct s_hardware *hardware);
void init_console(struct s_hardware *hardware);
void detect_hardware(struct s_hardware *hardware);
+void dump(struct s_hardware *hardware);
#endif
diff --git a/com32/hdt/hdt-dump-acpi.c b/com32/hdt/hdt-dump-acpi.c
new file mode 100644
index 00000000..4cbaf66f
--- /dev/null
+++ b/com32/hdt/hdt-dump-acpi.c
@@ -0,0 +1,600 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-common.h"
+#include "hdt-dump.h"
+
+void show_header(char *name, void *address, s_acpi_description_header *h, ZZJSON_CONFIG *config, ZZJSON **item)
+{
+ char signature[10]={0};
+ char revision[10]={0};
+ char s_address[16]={0};
+ char oem_id[16]={0};
+ char oem_table_id[16]={0};
+ char oem_revision[16]={0};
+ char creator_revision[16]={0};
+ char creator_id[16]={0};
+ snprintf(signature,sizeof(signature),"%s",h->signature);
+ snprintf(revision,sizeof(revision),"0x%03x",h->revision);
+ snprintf(oem_id,sizeof(oem_id),"%s",h->oem_id);
+ snprintf(oem_table_id,sizeof(oem_table_id),"%s",h->oem_table_id);
+ snprintf(creator_id,sizeof(creator_id),"%s",h->creator_id);
+ snprintf(oem_revision,sizeof(oem_revision),"0x%08x",h->oem_revision);
+ snprintf(creator_revision,sizeof(creator_revision),"0x%08x",h->creator_revision);
+ snprintf(s_address,sizeof(s_address),"%p",address);
+
+ char address_name[32]={0};
+ char signature_name[32]={0};
+ char revision_name[32]={0};
+ char oem_id_name[32]={0};
+ char oem_table_id_name[32]={0};
+ char oem_revision_name[32]={0};
+ char creator_revision_name[32]={0};
+ char creator_id_name[32]={0};
+ snprintf(signature_name,sizeof(signature_name),"acpi.%s.signature",name);
+ snprintf(revision_name,sizeof(revision_name),"acpi.%s.revision",name);
+ snprintf(address_name,sizeof(address_name),"acpi.%s.address",name);
+ snprintf(oem_id_name,sizeof(oem_id_name),"acpi.%s.oem_id",name);
+ snprintf(oem_table_id_name,sizeof(oem_table_id_name),"acpi.%s.oem_table_id",name);
+ snprintf(oem_revision_name,sizeof(oem_revision_name),"acpi.%s.oem_revision",name);
+ snprintf(creator_revision_name,sizeof(creator_revision_name),"acpi.%s.creator_revision",name);
+ snprintf(creator_id_name,sizeof(creator_id_name),"acpi.%s.creator_id",name);
+
+ APPEND_ARRAY
+ add_as(signature_name,signature)
+ add_as(revision_name,revision)
+ add_as(oem_id_name,oem_id)
+ add_as(oem_table_id_name,oem_table_id)
+ add_as(oem_revision_name,oem_revision)
+ add_as(creator_id_name,creator_id)
+ add_as(creator_revision_name,creator_revision)
+ add_as(address_name,s_address)
+ END_OF_APPEND;
+
+ FLUSH_OBJECT;
+
+}
+
+void dump_rsdt(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+ char valid[8]={0};
+ snprintf(valid,sizeof(valid),"%s","false");
+ if (acpi->rsdt.valid) {
+ snprintf(valid,sizeof(valid),"%s","true");
+ }
+ CREATE_ARRAY
+ add_as("acpi.item","rsdt")
+ add_as("acpi.rsdt.is_valid",valid)
+ END_OF_ARRAY;
+
+ if (acpi->rsdt.valid==false) {
+ FLUSH_OBJECT;
+ return;
+ }
+
+ show_header("rsdt",acpi->rsdt.address, &acpi->rsdt.header, config, item);
+}
+
+void dump_xsdt(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+ char valid[8]={0};
+ snprintf(valid,sizeof(valid),"%s","false");
+ if (acpi->xsdt.valid) {
+ snprintf(valid,sizeof(valid),"%s","true");
+ }
+ CREATE_ARRAY
+ add_as("acpi.item","xsdt")
+ add_as("acpi.xsdt.is_valid",valid)
+ END_OF_ARRAY;
+
+ if (acpi->xsdt.valid==false) {
+ FLUSH_OBJECT;
+ return;
+ }
+
+ show_header("xsdt",acpi->xsdt.address, &acpi->xsdt.header, config, item);
+}
+
+void dump_fadt(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+ char valid[8]={0};
+ snprintf(valid,sizeof(valid),"%s","false");
+ if (acpi->rsdt.valid) {
+ snprintf(valid,sizeof(valid),"%s","true");
+ }
+ CREATE_ARRAY
+ add_as("acpi.item","fadt")
+ add_as("acpi.fadt.is_valid",valid)
+ END_OF_ARRAY;
+
+ if (acpi->fadt.valid==false) {
+ FLUSH_OBJECT;
+ return;
+ }
+
+ show_header("fadt",acpi->fadt.address, &acpi->fadt.header, config, item);
+}
+
+void dump_dsdt(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+ char valid[8]={0};
+ snprintf(valid,sizeof(valid),"%s","false");
+ if (acpi->dsdt.valid) {
+ snprintf(valid,sizeof(valid),"%s","true");
+ }
+ CREATE_ARRAY
+ add_as("acpi.item","dsdt")
+ add_as("acpi.dsdt.is_valid",valid)
+ END_OF_ARRAY;
+
+ if (acpi->dsdt.valid==false) {
+ FLUSH_OBJECT;
+ return;
+ }
+
+ show_header("dsdt",acpi->dsdt.address, &acpi->dsdt.header, config, item);
+}
+
+void dump_sbst(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+ char valid[8]={0};
+ snprintf(valid,sizeof(valid),"%s","false");
+ if (acpi->sbst.valid) {
+ snprintf(valid,sizeof(valid),"%s","true");
+ }
+ CREATE_ARRAY
+ add_as("acpi.item","sbst")
+ add_as("acpi.sbst.is_valid",valid)
+ END_OF_ARRAY;
+
+ if (acpi->sbst.valid==false) {
+ FLUSH_OBJECT;
+ return;
+ }
+
+ show_header("sbst",acpi->sbst.address, &acpi->sbst.header, config, item);
+}
+
+void dump_ecdt(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+ char valid[8]={0};
+ snprintf(valid,sizeof(valid),"%s","false");
+ if (acpi->ecdt.valid) {
+ snprintf(valid,sizeof(valid),"%s","true");
+ }
+ CREATE_ARRAY
+ add_as("acpi.item","ecdt")
+ add_as("acpi.ecdt.is_valid",valid)
+ END_OF_ARRAY;
+
+ if (acpi->ecdt.valid==false) {
+ FLUSH_OBJECT;
+ return;
+ }
+
+ show_header("ecdt",acpi->ecdt.address, &acpi->ecdt.header, config, item);
+}
+
+void dump_hpet(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+ char valid[8]={0};
+ snprintf(valid,sizeof(valid),"%s","false");
+ if (acpi->hpet.valid) {
+ snprintf(valid,sizeof(valid),"%s","true");
+ }
+ CREATE_ARRAY
+ add_as("acpi.item","hpet")
+ add_as("acpi.hpet.is_valid",valid)
+ END_OF_ARRAY;
+
+ if (acpi->hpet.valid==false) {
+ FLUSH_OBJECT;
+ return;
+ }
+
+ show_header("hpet",acpi->hpet.address, &acpi->hpet.header, config, item);
+}
+
+void dump_tcpa(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+ char valid[8]={0};
+ snprintf(valid,sizeof(valid),"%s","false");
+ if (acpi->tcpa.valid) {
+ snprintf(valid,sizeof(valid),"%s","true");
+ }
+ CREATE_ARRAY
+ add_as("acpi.item","tcpa")
+ add_as("acpi.tcpa.is_valid",valid)
+ END_OF_ARRAY;
+
+ if (acpi->tcpa.valid==false) {
+ FLUSH_OBJECT;
+ return;
+ }
+
+ show_header("tcpa",acpi->tcpa.address, &acpi->tcpa.header, config, item);
+}
+
+void dump_mcfg(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+ char valid[8]={0};
+ snprintf(valid,sizeof(valid),"%s","false");
+ if (acpi->mcfg.valid) {
+ snprintf(valid,sizeof(valid),"%s","true");
+ }
+ CREATE_ARRAY
+ add_as("acpi.item","mcfg")
+ add_as("acpi.mcfg.is_valid",valid)
+ END_OF_ARRAY;
+
+ if (acpi->mcfg.valid==false) {
+ FLUSH_OBJECT;
+ return;
+ }
+
+ show_header("mcfg",acpi->mcfg.address, &acpi->mcfg.header, config, item);
+}
+
+void dump_slic(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+ char valid[8]={0};
+ snprintf(valid,sizeof(valid),"%s","false");
+ if (acpi->slic.valid) {
+ snprintf(valid,sizeof(valid),"%s","true");
+ }
+ CREATE_ARRAY
+ add_as("acpi.item","slic")
+ add_as("acpi.slic.is_valid",valid)
+ END_OF_ARRAY;
+
+ if (acpi->slic.valid==false) {
+ FLUSH_OBJECT;
+ return;
+ }
+
+ show_header("slic",acpi->slic.address, &acpi->slic.header, config, item);
+}
+
+
+void dump_boot(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+ char valid[8]={0};
+ snprintf(valid,sizeof(valid),"%s","false");
+ if (acpi->boot.valid) {
+ snprintf(valid,sizeof(valid),"%s","true");
+ }
+ CREATE_ARRAY
+ add_as("acpi.item","boot")
+ add_as("acpi.boot.is_valid",valid)
+ END_OF_ARRAY;
+
+ if (acpi->boot.valid==false) {
+ FLUSH_OBJECT;
+ return;
+ }
+
+ show_header("boot",acpi->boot.address, &acpi->boot.header, config, item);
+}
+
+void dump_madt(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+ char valid[8]={0};
+ snprintf(valid,sizeof(valid),"%s","false");
+ if (acpi->madt.valid) {
+ snprintf(valid,sizeof(valid),"%s","true");
+ }
+ CREATE_ARRAY
+ add_as("acpi.item","madt")
+ add_as("acpi.madt.is_valid",valid)
+ END_OF_ARRAY;
+
+ if (acpi->madt.valid==false) {
+ FLUSH_OBJECT;
+ return;
+ }
+
+ show_header("madt",acpi->madt.address, &acpi->madt.header, config, item);
+}
+
+void dump_ssdt(s_ssdt *ssdt, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+ char valid[8]={0};
+ snprintf(valid,sizeof(valid),"%s","false");
+ if (ssdt->valid) {
+ snprintf(valid,sizeof(valid),"%s","true");
+ }
+ CREATE_ARRAY
+ add_as("acpi.item","ssdt")
+ add_as("acpi.ssdt.is_valid",valid)
+ END_OF_ARRAY;
+
+ if (ssdt->valid==false) {
+ FLUSH_OBJECT;
+ return;
+ }
+
+ show_header("ssdt",ssdt->address, &ssdt->header, config, item);
+}
+
+void dump_rsdp(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+ char valid[8]={0};
+ snprintf(valid,sizeof(valid),"%s","false");
+ if (acpi->rsdp.valid) {
+ snprintf(valid,sizeof(valid),"%s","true");
+ }
+ CREATE_ARRAY
+ add_as("acpi.item","rsdp")
+ add_as("acpi.rsdp.is_valid",valid)
+ END_OF_ARRAY;
+
+ if (acpi->rsdp.valid==false) {
+ FLUSH_OBJECT;
+ return;
+ }
+
+ s_rsdp *r = &acpi->rsdp;
+ char revision[10]={0};
+ char address[16]={0};
+ char oem_id[16]={0};
+ snprintf(revision,sizeof(revision),"0x%03x",r->revision);
+ snprintf(address,sizeof(address),"%p",r->address);
+ snprintf(oem_id,sizeof(oem_id),"%s",r->oem_id);
+ APPEND_ARRAY
+ add_as("acpi.rsdp.revision",revision)
+ add_as("acpi.rsdp.oem_id",oem_id)
+ add_as("acpi.rsdp.address",address)
+ END_OF_APPEND;
+
+ FLUSH_OBJECT;
+
+}
+
+void dump_facs(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+ char valid[8]={0};
+ snprintf(valid,sizeof(valid),"%s","false");
+ if (acpi->facs.valid) {
+ snprintf(valid,sizeof(valid),"%s","true");
+ }
+ CREATE_ARRAY
+ add_as("acpi.item","facs")
+ add_as("acpi.facs.is_valid",valid)
+ END_OF_ARRAY;
+
+ if (acpi->facs.valid==false) {
+ FLUSH_OBJECT;
+ return;
+ }
+
+ s_facs *fa = &acpi->facs;
+ char address[16]={0};
+ snprintf(address,sizeof(address),"%p",fa->address);
+ APPEND_ARRAY
+ add_as("acpi.facs.address",address)
+ END_OF_APPEND;
+
+ FLUSH_OBJECT;
+
+}
+
+void dump_interrupt_source_override(s_madt * madt, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+ CREATE_ARRAY
+ add_as("acpi.item","interrupt_source_override")
+ add_ai("acpi.interrupt_source_override.count", madt->interrupt_source_override_count)
+ END_OF_ARRAY;
+
+ if (madt->interrupt_source_override_count == 0) {
+ FLUSH_OBJECT;
+ return;
+ }
+
+ /* Let's process each interrupt source override */
+ for (int i = 0; i < madt->interrupt_source_override_count; i++) {
+ s_interrupt_source_override *siso = &madt->interrupt_source_override[i];
+ char buffer[20] = {0};
+ char bus_type[10]= {0};
+
+ /* Spec report bus type 0 as ISA */
+ if (siso->bus == 0)
+ strcpy(bus_type, "ISA");
+ else
+ strcpy(bus_type, "unknown");
+
+ APPEND_ARRAY
+ add_as("acpi.interrupt_source_override.bus_type",bus_type)
+ add_ai("acpi.interrupt_source_override.bus",siso->bus)
+ add_ai("acpi.interrupt_source_override.bus_irq",siso->source)
+ add_ai("acpi.interrupt_source_override.global_irq",siso->global_system_interrupt)
+ add_as("acpi.interrupt_source_override.flags",flags_to_string(buffer,siso->flags))
+ END_OF_APPEND;
+ }
+ FLUSH_OBJECT;
+}
+
+void dump_io_apic(s_madt * madt, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+ CREATE_ARRAY
+ add_as("acpi.item","io_apic")
+ add_ai("acpi.io_apic.count", madt->io_apic_count)
+ END_OF_ARRAY;
+
+ if (madt->io_apic_count == 0) {
+ FLUSH_OBJECT;
+ return;
+ }
+
+ /* For all IO APICS */
+ for (int i = 0; i < madt->io_apic_count; i++) {
+ s_io_apic *sio = &madt->io_apic[i];
+ char buffer[15]={0};
+ memset(buffer, 0, sizeof(buffer));
+ /* GSI base reports the GSI configuration
+ * Let's interpret it as string */
+ switch (sio->global_system_interrupt_base) {
+ case 0:
+ strcpy(buffer, "0-23");
+ break;
+ case 24:
+ strcpy(buffer,"24-39");
+ break;
+ case 40:
+ strcpy(buffer, "40-55");
+ break;
+ default:
+ strcpy(buffer,"Unknown");
+ break;
+ }
+
+ char apic_id[16] = { 0 };
+ char address[16] = { 0 };
+ snprintf(apic_id,sizeof(apic_id),"0x%02x",sio->io_apic_id);
+ snprintf(address,sizeof(address),"0x%08x",sio->io_apic_address);
+ APPEND_ARRAY
+ add_ai("acpi.io_apic.number",i)
+ add_as("acpi.io_apic.apic_id",apic_id)
+ add_as("acpi.io_apic.adress",address)
+ add_as("acpi.io_apic.gsi",buffer)
+ END_OF_APPEND;
+ }
+ FLUSH_OBJECT;
+}
+
+void dump_local_apic_nmi(s_madt * madt, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+ CREATE_ARRAY
+ add_as("acpi.item","local_apic_nmi")
+ add_ai("acpi.local_apic_nmi.count", madt->local_apic_nmi_count)
+ END_OF_ARRAY;
+
+ if (madt->local_apic_nmi_count == 0) {
+ FLUSH_OBJECT;
+ return;
+ }
+
+ for (int i = 0; i < madt->local_apic_nmi_count; i++) {
+ s_local_apic_nmi *slan = &madt->local_apic_nmi[i];
+ char buffer[20]={0};
+ char acpi_id[16] = { 0 };
+ char local_apic_lint[16] = { 0 };
+ snprintf(acpi_id, sizeof(acpi_id), "0x%02x", slan->acpi_processor_id);
+ snprintf(local_apic_lint, sizeof(local_apic_lint), "0x%02x", slan->local_apic_lint);
+ APPEND_ARRAY
+ add_as("acpi.processor_id", acpi_id)
+ add_as("acpi.local_apic_nmi.flags", flags_to_string(buffer,slan->flags))
+ add_as("acpi.local_apic_nmi.lint",local_apic_lint)
+ END_OF_APPEND;
+ }
+
+ FLUSH_OBJECT;
+}
+
+void dump_local_apic(s_madt * madt, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+ char buffer[16] = { 0 };
+ snprintf(buffer, sizeof(buffer), "0x%08x", madt->local_apic_address);
+
+ CREATE_ARRAY
+ add_as("acpi.item","local_apic")
+ add_as("acpi.local_apic.address", buffer)
+ add_ai("acpi.processor_local_apic.count", madt->processor_local_apic_count)
+ END_OF_ARRAY;
+
+ if (madt->processor_local_apic_count ==0) {
+ FLUSH_OBJECT;
+ return;
+ }
+
+ /* For all detected logical CPU */
+ for (int i = 0; i < madt->processor_local_apic_count; i++) {
+ s_processor_local_apic *sla = &madt->processor_local_apic[i];
+ char lapic_status[16] = { 0 };
+ char acpi_id[16] = { 0 };
+ char apic_id[16] = { 0 };
+
+ snprintf(lapic_status,sizeof(lapic_status),"%s","disabled");
+ /* Let's check if the flags reports the cpu as enabled */
+ if ((sla->flags & PROCESSOR_LOCAL_APIC_ENABLE) ==
+ PROCESSOR_LOCAL_APIC_ENABLE)
+ snprintf(lapic_status,sizeof(lapic_status),"%s","enabled");
+ snprintf(acpi_id, sizeof(acpi_id), "0x%02x", sla->acpi_id);
+ snprintf(apic_id, sizeof(apic_id), "0x%02x", sla->apic_id);
+ APPEND_ARRAY
+ add_ai("acpi.cpu.apic_id", sla->apic_id)
+ add_as("acpi.cpu.apic_id (hex)", apic_id)
+ add_as("acpi.cpu.acpi_id (hex)", acpi_id)
+ add_as("acpi.lapic.enabled", lapic_status)
+ END_OF_APPEND;
+ }
+ FLUSH_OBJECT;
+}
+
+void dump_acpi(struct s_hardware *hardware, ZZJSON_CONFIG * config,
+ ZZJSON ** item)
+{
+ CREATE_NEW_OBJECT;
+ add_hb(is_acpi_valid);
+ if (hardware->is_acpi_valid == false)
+ goto exit;
+
+ s_madt *madt = &hardware->acpi.madt;
+ add_b("acpi.apic.detected", madt->valid);
+ if (madt->valid == false) {
+ goto exit;
+ }
+
+ FLUSH_OBJECT;
+
+ dump_local_apic(madt, config, item);
+ dump_local_apic_nmi(madt, config, item);
+ dump_io_apic(madt, config, item);
+ dump_interrupt_source_override(madt, config, item);
+
+ dump_rsdp(&hardware->acpi,config,item);
+ dump_rsdt(&hardware->acpi,config,item);
+ dump_xsdt(&hardware->acpi,config,item);
+ dump_fadt(&hardware->acpi,config,item);
+ dump_dsdt(&hardware->acpi,config,item);
+ dump_sbst(&hardware->acpi,config,item);
+ dump_ecdt(&hardware->acpi,config,item);
+ dump_hpet(&hardware->acpi,config,item);
+ dump_tcpa(&hardware->acpi,config,item);
+ dump_mcfg(&hardware->acpi,config,item);
+ dump_slic(&hardware->acpi,config,item);
+ dump_boot(&hardware->acpi,config,item);
+ dump_madt(&hardware->acpi,config,item);
+ for (int i = 0; i < hardware->acpi.ssdt_count; i++) {
+ if ((hardware->acpi.ssdt[i] != NULL) && (hardware->acpi.ssdt[i]->valid))
+ dump_ssdt(hardware->acpi.ssdt[i], config, item);
+ }
+ dump_facs(&hardware->acpi,config,item);
+
+exit:
+ to_cpio("acpi");
+}
diff --git a/com32/hdt/hdt-dump-cpu.c b/com32/hdt/hdt-dump-cpu.c
new file mode 100644
index 00000000..33d561c8
--- /dev/null
+++ b/com32/hdt/hdt-dump-cpu.c
@@ -0,0 +1,53 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-common.h"
+#include "hdt-dump.h"
+
+void dump_cpu(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+ CREATE_NEW_OBJECT;
+ add_hs(cpu.vendor);
+ add_hs(cpu.model);
+ add_hi(cpu.vendor_id);
+ add_hi(cpu.family);
+ add_hi(cpu.model_id);
+ add_hi(cpu.stepping);
+ add_hi(cpu.num_cores);
+ add_hi(cpu.l1_data_cache_size);
+ add_hi(cpu.l1_instruction_cache_size);
+ add_hi(cpu.l2_cache_size);
+ size_t i;
+ for (i = 0; i < cpu_flags_count; i++) {
+ char temp[128]={0};
+ snprintf(temp,sizeof(temp),"cpu.flags.%s",cpu_flags_names[i]);
+ add_b(temp,get_cpu_flag_value_from_name(&hardware->cpu,cpu_flags_names[i]));
+ }
+ FLUSH_OBJECT;
+ to_cpio("cpu");
+}
diff --git a/com32/hdt/hdt-dump-disks.c b/com32/hdt/hdt-dump-disks.c
new file mode 100644
index 00000000..dcbcaa9e
--- /dev/null
+++ b/com32/hdt/hdt-dump-disks.c
@@ -0,0 +1,137 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-common.h"
+#include "hdt-dump.h"
+#include "hdt-util.h"
+
+ZZJSON_CONFIG *config;
+ZZJSON **item;
+
+static void show_partition_information(struct driveinfo *drive_info,
+ struct part_entry *ptab,
+ int partition_offset,
+ int nb_partitions_seen) {
+ char size[11] = {0};
+ char bootloader_name[9] = {0};
+ char ostype[64]={0};
+ char *parttype;
+ unsigned int start, end;
+
+ int i = nb_partitions_seen;
+ start = partition_offset;
+ end = start + ptab->length - 1;
+
+ if (ptab->length > 0)
+ sectors_to_size(ptab->length, size);
+
+ get_label(ptab->ostype, &parttype);
+ get_bootloader_string(drive_info, ptab, bootloader_name, 9);
+
+ snprintf(ostype,sizeof(ostype),"%02X",ptab->ostype);
+
+ APPEND_ARRAY
+ add_ai("partition->number",i)
+ add_ai("partition->sector_start",start)
+ add_ai("partition->sector_end",end)
+ add_as("partition->size",size)
+ add_as("partition->type",parttype)
+ add_as("partition->os_type",ostype)
+ END_OF_APPEND;
+ free(parttype);
+}
+
+
+
+void show_disk(struct s_hardware *hardware, ZZJSON_CONFIG *conf, ZZJSON **it, int drive) {
+ config=conf;
+ item=it;
+ int i = drive - 0x80;
+ struct driveinfo *d = &hardware->disk_info[i];
+ char mbr_name[50]={0};
+ char disk_size[11]={0};
+
+ get_mbr_string(hardware->mbr_ids[i], &mbr_name,sizeof(mbr_name));
+ if ((int)d->edd_params.sectors > 0)
+ sectors_to_size((int)d->edd_params.sectors, disk_size);
+
+ char disk[5]={0};
+ char edd_version[5]={0};
+ snprintf(disk,sizeof(disk),"0x%X",d->disk);
+ snprintf(edd_version,sizeof(edd_version),"%X",d->edd_version);
+ zzjson_print(config, *item);
+ zzjson_free(config, *item);
+
+ CREATE_ARRAY
+ add_as("disk->number",disk)
+ add_ai("disk->cylinders",d->legacy_max_cylinder +1)
+ add_ai("disk->heads",d->legacy_max_head +1)
+ add_ai("disk->sectors_per_track",d->legacy_sectors_per_track)
+ add_as("disk->edd_version",edd_version)
+ add_as("disk->size",disk_size)
+ add_ai("disk->bytes_per_sector",(int)d->edd_params.bytes_per_sector)
+ add_ai("disk->sectors_per_track",(int)d->edd_params.sectors_per_track)
+ add_as("disk->host_bus",remove_spaces((char *)d->edd_params.host_bus_type))
+ add_as("disk->interface_type",remove_spaces((char *)d->edd_params.interface_type))
+ add_as("disk->mbr_name",mbr_name)
+ add_ai("disk->mbr_id",hardware->mbr_ids[i])
+ END_OF_ARRAY;
+
+ if (parse_partition_table(d, &show_partition_information)) {
+ if (errno_disk) {
+ APPEND_ARRAY
+ add_as("disk->error", "IO Error")
+ END_OF_APPEND;
+ } else {
+ APPEND_ARRAY
+ add_as("disk->error", "Unrecognized Partition Layout")
+ END_OF_APPEND;
+ }
+ }
+}
+
+void dump_disks(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+ bool found=false;
+ for (int drive = 0x80; drive < 0xff; drive++) {
+ if (hardware->disk_info[drive - 0x80].cbios) {
+ if (found==false) {
+ CREATE_NEW_OBJECT;
+ add_b("disks->is_valid",true);
+ found=true;
+ }
+ show_disk(hardware, config, item, drive);
+ }
+ }
+
+ if (found==false) {
+ CREATE_NEW_OBJECT;
+ add_b("disks->is_valid",false);
+ FLUSH_OBJECT;
+ }
+ to_cpio("disks");
+}
diff --git a/com32/hdt/hdt-dump-dmi.c b/com32/hdt/hdt-dump-dmi.c
new file mode 100644
index 00000000..6e5c1ce8
--- /dev/null
+++ b/com32/hdt/hdt-dump-dmi.c
@@ -0,0 +1,447 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-common.h"
+#include "hdt-dump.h"
+
+void dump_hardware_security(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+ if (!hardware->dmi.hardware_security.filled) {
+ CREATE_NEW_OBJECT;
+ add_s("dmi.warning","No hardware security structure found");
+ FLUSH_OBJECT;
+ return;
+ }
+
+ CREATE_NEW_OBJECT;
+ add_s("dmi.item","hardware_security");
+ add_hs(dmi.hardware_security.power_on_passwd_status);
+ add_hs(dmi.hardware_security.keyboard_passwd_status);
+ add_hs(dmi.hardware_security.administrator_passwd_status);
+ add_hs(dmi.hardware_security.front_panel_reset_status);
+ FLUSH_OBJECT;
+}
+
+void dump_oem_strings(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+ if (strlen(hardware->dmi.oem_strings) == 0) {
+ CREATE_NEW_OBJECT;
+ add_s("dmi.warning","No OEM structure found");
+ FLUSH_OBJECT;
+ return;
+ }
+ CREATE_NEW_OBJECT;
+ add_s("dmi.item","OEM");
+ add_hs(dmi.oem_strings);
+ FLUSH_OBJECT;
+}
+
+void dump_memory_size(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+ CREATE_NEW_OBJECT;
+ add_s("dmi.item","memory size");
+ add_i("dmi.memory_size (KB)",hardware->detected_memory_size);
+ add_i("dmi.memory_size (MB)",(hardware->detected_memory_size + (1 << 9)) >> 10);
+ FLUSH_OBJECT;
+}
+
+void dump_memory_modules(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+ if (hardware->dmi.memory_module_count == 0) {
+ CREATE_NEW_OBJECT;
+ add_s("dmi.warning","No memory module structure found");
+ FLUSH_OBJECT;
+ return;
+ }
+
+ for (int module=0; module<hardware->dmi.memory_module_count;module++) {
+ if (hardware->dmi.memory_module[module].filled == false) {
+ char msg[64]={0};
+ snprintf(msg,sizeof(msg),"Module %d doesn't contain any information", module);
+
+ CREATE_NEW_OBJECT;
+ add_s("dmi.warning",msg);
+ FLUSH_OBJECT;
+ continue;
+ }
+
+ CREATE_NEW_OBJECT;
+ add_i("Memory module", module);
+ add_s("dmi.memory_module.socket_designation", hardware->dmi.memory_module[module].socket_designation);
+ add_s("dmi.memory_module.bank_connections", hardware->dmi.memory_module[module].bank_connections);
+ add_s("dmi.memory_module.speed", hardware->dmi.memory_module[module].speed);
+ add_s("dmi.memory_module.type", hardware->dmi.memory_module[module].type);
+ add_s("dmi.memory_module.installed_size", hardware->dmi.memory_module[module].installed_size);
+ add_s("dmi.memory_module.enabled_size", hardware->dmi.memory_module[module].enabled_size);
+ add_s("dmi.memory_module.error_status", hardware->dmi.memory_module[module].error_status);
+ FLUSH_OBJECT;
+ }
+}
+
+void dump_cache(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+ if (hardware->dmi.cache_count == 0) {
+ CREATE_NEW_OBJECT;
+ add_s("dmi.warning","No cache structure found");
+ FLUSH_OBJECT;
+ return;
+ }
+
+ for (int cache=0; cache<hardware->dmi.cache_count;cache++) {
+ CREATE_NEW_OBJECT;
+ add_i("Cache", cache);
+ add_s("dmi.cache.socket_designation", hardware->dmi.cache[cache].socket_designation);
+ add_s("dmi.cache.configuration", hardware->dmi.cache[cache].configuration);
+ add_s("dmi.cache.mode", hardware->dmi.cache[cache].mode);
+ add_s("dmi.cache.location", hardware->dmi.cache[cache].location);
+ add_i("dmi.cache.installed_size (KB)", hardware->dmi.cache[cache].installed_size);
+ add_i("dmi.cache.max_size (KB)", hardware->dmi.cache[cache].max_size);
+ add_s("dmi.cache.supported_sram_types", hardware->dmi.cache[cache].supported_sram_types);
+ add_s("dmi.cache.installed_sram_types", hardware->dmi.cache[cache].installed_sram_types);
+ add_i("dmi.cache.speed (ns)", hardware->dmi.cache[cache].speed);
+ add_s("dmi.cache.error_correction_type", hardware->dmi.cache[cache].error_correction_type);
+ add_s("dmi.cache.system_type", hardware->dmi.cache[cache].system_type);
+ add_s("dmi.cache.associativity", hardware->dmi.cache[cache].associativity);
+ FLUSH_OBJECT;
+ }
+}
+void dump_memory_banks(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+ if (hardware->dmi.memory_count == 0) {
+ CREATE_NEW_OBJECT;
+ add_s("dmi.warning","No memory bank structure found");
+ FLUSH_OBJECT;
+ return;
+ }
+
+ for (int bank=0; bank<hardware->dmi.memory_count;bank++) {
+
+ if (hardware->dmi.memory[bank].filled == false) {
+ char msg[64]={0};
+ snprintf(msg,sizeof(msg),"Bank %d doesn't contain any information", bank);
+
+ CREATE_NEW_OBJECT;
+ add_s("dmi.warning",msg);
+ FLUSH_OBJECT;
+ continue;
+ }
+
+ CREATE_NEW_OBJECT;
+ add_i("Memory Bank", bank);
+ add_s("dmi.memory.form_factor", hardware->dmi.memory[bank].form_factor);
+ add_s("dmi.memory.type", hardware->dmi.memory[bank].type);
+ add_s("dmi.memory.type_detail", hardware->dmi.memory[bank].type_detail);
+ add_s("dmi.memory.speed", hardware->dmi.memory[bank].speed);
+ add_s("dmi.memory.size", hardware->dmi.memory[bank].size);
+ add_s("dmi.memory.device_set", hardware->dmi.memory[bank].device_set);
+ add_s("dmi.memory.device_locator", hardware->dmi.memory[bank].device_locator);
+ add_s("dmi.memory.bank_locator", hardware->dmi.memory[bank].bank_locator);
+ add_s("dmi.memory.total_width", hardware->dmi.memory[bank].total_width);
+ add_s("dmi.memory.data_width", hardware->dmi.memory[bank].data_width);
+ add_s("dmi.memory.error", hardware->dmi.memory[bank].error);
+ add_s("dmi.memory.vendor", hardware->dmi.memory[bank].manufacturer);
+ add_s("dmi.memory.serial", hardware->dmi.memory[bank].serial);
+ add_s("dmi.memory.asset_tag", hardware->dmi.memory[bank].asset_tag);
+ add_s("dmi.memory.part_number", hardware->dmi.memory[bank].part_number);
+ FLUSH_OBJECT;
+ }
+}
+
+void dump_processor(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+ if (hardware->dmi.processor.filled == false) {
+ CREATE_NEW_OBJECT;
+ add_s("dmi.warning","no processor structure found");
+ FLUSH_OBJECT;
+ return;
+ }
+
+ char voltage[16]={0};
+ snprintf(voltage,sizeof(voltage),"%d.%02d",
+ hardware->dmi.processor.voltage_mv / 1000,
+ hardware->dmi.processor.voltage_mv - ((hardware->dmi.processor.voltage_mv / 1000) * 1000));
+
+ CREATE_NEW_OBJECT;
+ add_s("dmi.item","processor");
+ add_hs(dmi.processor.socket_designation);
+ add_hs(dmi.processor.type);
+ add_hs(dmi.processor.family);
+ add_hs(dmi.processor.manufacturer);
+ add_hs(dmi.processor.version);
+ add_hi(dmi.processor.external_clock);
+ add_hi(dmi.processor.max_speed);
+ add_hi(dmi.processor.current_speed);
+ add_hi(dmi.processor.signature.type);
+ add_hi(dmi.processor.signature.family);
+ add_hi(dmi.processor.signature.model);
+ add_hi(dmi.processor.signature.stepping);
+ add_hi(dmi.processor.signature.minor_stepping);
+ add_s("dmi.processor.voltage",voltage);
+ add_hs(dmi.processor.status);
+ add_hs(dmi.processor.upgrade);
+ add_hs(dmi.processor.cache1);
+ add_hs(dmi.processor.cache2);
+ add_hs(dmi.processor.cache3);
+ add_hs(dmi.processor.serial);
+ add_hs(dmi.processor.part_number);
+ add_hi(dmi.processor.core_count);
+ add_hi(dmi.processor.core_enabled);
+ add_hi(dmi.processor.thread_count);
+ add_hs(dmi.processor.id);
+ for (int i = 0; i < PROCESSOR_FLAGS_ELEMENTS; i++) {
+ if (((bool *) (&hardware->dmi.processor.cpu_flags))[i] == true) {
+ add_s("dmi.processor.flag",(char *)cpu_flags_strings[i]);
+ }
+ }
+ FLUSH_OBJECT;
+}
+
+void dump_battery(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+ if (hardware->dmi.battery.filled == false) {
+ CREATE_NEW_OBJECT;
+ add_s("dmi.warning","no battery structure found");
+ FLUSH_OBJECT;
+ return;
+ }
+
+ CREATE_NEW_OBJECT;
+ add_s("dmi.item","battery");
+ add_hs(dmi.battery.manufacturer);
+ add_hs(dmi.battery.manufacture_date);
+ add_hs(dmi.battery.serial);
+ add_hs(dmi.battery.name);
+ add_hs(dmi.battery.chemistry);
+ add_hs(dmi.battery.design_capacity);
+ add_hs(dmi.battery.design_voltage);
+ add_hs(dmi.battery.sbds);
+ add_hs(dmi.battery.sbds_manufacture_date);
+ add_hs(dmi.battery.sbds_chemistry);
+ add_hs(dmi.battery.maximum_error);
+ add_hs(dmi.battery.oem_info);
+ FLUSH_OBJECT;
+}
+
+void dump_ipmi(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+ if (hardware->dmi.ipmi.filled == false) {
+ CREATE_NEW_OBJECT;
+ add_s("dmi.warning","no IPMI structure found");
+ FLUSH_OBJECT;
+ return;
+ }
+
+ char spec_ver[16]={0};
+ char i2c[16]={0};
+ char base[16]={0};
+ snprintf(spec_ver,sizeof(spec_ver),"%u.%u",
+ hardware->dmi.ipmi.major_specification_version,
+ hardware->dmi.ipmi.minor_specification_version);
+
+ snprintf(i2c,sizeof(i2c),"0x%02x", hardware->dmi.ipmi.I2C_slave_address);
+ snprintf(base,sizeof(base),"%08X%08X",
+ (uint32_t)(hardware->dmi.ipmi.base_address >> 32),
+ (uint32_t)((hardware->dmi.ipmi.base_address & 0xFFFF) & ~1));
+
+ CREATE_NEW_OBJECT;
+ add_s("dmi.item","ipmi");
+ add_hs(dmi.ipmi.interface_type);
+ add_s("dmi.ipmi.spec_version",spec_ver);
+ add_hi(dmi.ipmi.I2C_slave_address);
+ add_hi(dmi.ipmi.nv_address);
+ add_s("dmi.ipmi.base_address",base);
+ add_hi(dmi.ipmi.irq);
+ FLUSH_OBJECT;
+}
+
+void dump_chassis(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+ if (hardware->dmi.chassis.filled == false) {
+ CREATE_NEW_OBJECT;
+ add_s("dmi.warning","no chassis structure found");
+ FLUSH_OBJECT;
+ return;
+ }
+
+ CREATE_NEW_OBJECT;
+ add_s("dmi.item","bios");
+ add_hs(dmi.chassis.manufacturer);
+ add_hs(dmi.chassis.type);
+ add_hs(dmi.chassis.lock);
+ add_hs(dmi.chassis.version);
+ add_hs(dmi.chassis.serial);
+ add_s("dmi.chassis.asset_tag",del_multi_spaces(hardware->dmi.chassis.asset_tag));
+ add_hs(dmi.chassis.boot_up_state);
+ add_hs(dmi.chassis.power_supply_state);
+ add_hs(dmi.chassis.thermal_state);
+ add_hs(dmi.chassis.security_status);
+ add_hs(dmi.chassis.oem_information);
+ add_hi(dmi.chassis.height);
+ add_hi(dmi.chassis.nb_power_cords);
+ FLUSH_OBJECT;
+}
+
+void dump_bios(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+ if (hardware->dmi.bios.filled == false) {
+ CREATE_NEW_OBJECT;
+ add_s("dmi.warning","no bios structure found");
+ FLUSH_OBJECT;
+ return;
+ }
+ char address[16]={0};
+ char runtime[16]={0};
+ char rom[16]={0};
+ snprintf(address,sizeof(address),"0x%04X0",hardware->dmi.bios.address);
+ snprintf(runtime,sizeof(runtime),"%u %s",hardware->dmi.bios.runtime_size, hardware->dmi.bios.runtime_size_unit);
+ snprintf(rom,sizeof(rom),"%u %s",hardware->dmi.bios.rom_size, hardware->dmi.bios.rom_size_unit);
+
+ CREATE_NEW_OBJECT;
+ add_s("dmi.item","bios");
+ add_hs(dmi.bios.vendor);
+ add_hs(dmi.bios.version);
+ add_hs(dmi.bios.release_date);
+ add_hs(dmi.bios.bios_revision);
+ add_hs(dmi.bios.firmware_revision);
+ add_s("dmi.bios.address",address);
+ add_s("dmi.bios.runtime_size",runtime);
+ add_s("dmi.bios.rom_size",rom);
+ for (int i = 0; i < BIOS_CHAR_NB_ELEMENTS; i++) {
+ if (((bool *) (&hardware->dmi.bios.characteristics))[i] == true) {
+ add_s("dmi.bios.characteristics",(char *)bios_charac_strings[i]);
+ }
+ }
+
+ for (int i = 0; i < BIOS_CHAR_X1_NB_ELEMENTS; i++) {
+ if (((bool *) (&hardware->dmi.bios.characteristics_x1))[i] == true) {
+ add_s("dmi.bios.characteristics",(char *)bios_charac_x1_strings[i]);
+ }
+ }
+
+ for (int i = 0; i < BIOS_CHAR_X2_NB_ELEMENTS; i++) {
+ if (((bool *) (&hardware->dmi.bios.characteristics_x2))[i] == true) {
+ add_s("dmi.bios.characteristics",(char *)bios_charac_x2_strings[i]);
+ }
+ }
+ FLUSH_OBJECT;
+}
+
+void dump_system(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+ if (hardware->dmi.system.filled == false) {
+ CREATE_NEW_OBJECT;
+ add_s("dmi.warning","no system structure found");
+ FLUSH_OBJECT;
+ return;
+ }
+ char system_reset_status[10]={0};
+ char watchdog_timer[15]={0};
+ snprintf(system_reset_status,sizeof(system_reset_status),"%s", (hardware->dmi.system.system_reset.status ? "Enabled" :"Disabled"));
+ snprintf(watchdog_timer,sizeof(watchdog_timer),"%s", (hardware->dmi.system.system_reset.watchdog ? "Present" :"Not Present"));
+
+ CREATE_NEW_OBJECT;
+ add_s("dmi.item","system");
+ add_hs(dmi.system.manufacturer);
+ add_hs(dmi.system.product_name);
+ add_hs(dmi.system.version);
+ add_hs(dmi.system.serial);
+ add_hs(dmi.system.uuid);
+ add_hs(dmi.system.wakeup_type);
+ add_hs(dmi.system.sku_number);
+ add_hs(dmi.system.family);
+ add_hs(dmi.system.configuration_options);
+ add_s("dmi.system.system_reset.status",system_reset_status);
+ add_s("dmi.system.system_reset.watchdog",watchdog_timer);
+ add_hs(dmi.system.system_reset.boot_option);
+ add_hs(dmi.system.system_reset.boot_option_on_limit);
+ add_hs(dmi.system.system_reset.reset_count);
+ add_hs(dmi.system.system_reset.reset_limit);
+ add_hs(dmi.system.system_reset.timer_interval);
+ add_hs(dmi.system.system_reset.timeout);
+ add_hs(dmi.system.system_boot_status);
+ FLUSH_OBJECT;
+}
+
+void dump_base_board(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+ if (hardware->dmi.base_board.filled == false) {
+ CREATE_NEW_OBJECT;
+ add_s("dmi.warning","no base_board structure found");
+ FLUSH_OBJECT;
+ return;
+ }
+
+ CREATE_NEW_OBJECT;
+ add_s("dmi.item","base_board");
+ add_hs(dmi.base_board.manufacturer);
+ add_hs(dmi.base_board.product_name);
+ add_hs(dmi.base_board.version);
+ add_hs(dmi.base_board.serial);
+ add_hs(dmi.base_board.asset_tag);
+ add_hs(dmi.base_board.location);
+ add_hs(dmi.base_board.type);
+ for (int i = 0; i < BASE_BOARD_NB_ELEMENTS; i++) {
+ if (((bool *) (&hardware->dmi.base_board.features))[i] == true) {
+ add_s("dmi.base_board.features",(char *)base_board_features_strings[i]);
+ }
+ }
+
+ for (unsigned int i = 0; i < sizeof hardware->dmi.base_board.devices_information /
+ sizeof *hardware->dmi.base_board.devices_information; i++) {
+ if (strlen(hardware->dmi.base_board.devices_information[i].type)) {
+ add_s("dmi.base_board.devices_information.type", hardware->dmi.base_board.devices_information[i].type);
+ add_i("dmi.base_board.devices_information.status", hardware->dmi.base_board.devices_information[i].status);
+ add_s("dmi.base_board.devices_information.description", hardware->dmi.base_board.devices_information[i].description);
+ }
+ }
+ FLUSH_OBJECT;
+}
+
+void dump_dmi(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+ CREATE_NEW_OBJECT;
+ add_hb(is_dmi_valid);
+
+ if (hardware->is_dmi_valid == false) {
+ FLUSH_OBJECT;
+ goto exit;
+ } else {
+ char buffer[8]={0};
+ snprintf(buffer,sizeof(buffer),"%d.%d",hardware->dmi.dmitable.major_version, hardware->dmi.dmitable.minor_version);
+ add_s("dmi.version",buffer);
+ FLUSH_OBJECT;
+ }
+
+ dump_base_board(hardware,config,item);
+ dump_system(hardware,config,item);
+ dump_bios(hardware,config,item);
+ dump_chassis(hardware,config,item);
+ dump_ipmi(hardware,config,item);
+ dump_battery(hardware,config,item);
+ dump_processor(hardware,config,item);
+ dump_cache(hardware,config,item);
+ dump_memory_banks(hardware,config,item);
+ dump_memory_modules(hardware,config,item);
+ dump_memory_size(hardware,config,item);
+ dump_oem_strings(hardware,config,item);
+ dump_hardware_security(hardware,config,item);
+exit:
+ to_cpio("dmi");
+}
diff --git a/com32/hdt/hdt-dump-hdt.c b/com32/hdt/hdt-dump-hdt.c
new file mode 100644
index 00000000..d081ebdb
--- /dev/null
+++ b/com32/hdt/hdt-dump-hdt.c
@@ -0,0 +1,50 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-common.h"
+#include "hdt-dump.h"
+#include <syslinux/config.h>
+
+void dump_hdt(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+ (void) hardware;
+ CREATE_NEW_OBJECT;
+ add_s("hdt.product_name",PRODUCT_NAME);
+ add_s("hdt.version",VERSION);
+ add_s("hdt.code_name",CODENAME);
+ add_s("hdt.author", AUTHOR);
+ add_s("hdt.core_developer", CORE_DEVELOPER);
+ char *contributors[NB_CONTRIBUTORS] = CONTRIBUTORS;
+ for (int c = 0; c < NB_CONTRIBUTORS; c++) {
+ add_s("hdt.contributor", contributors[c]);
+ }
+ add_s("hdt.website",WEBSITE_URL);
+ add_s("hdt.irc_channel",IRC_CHANNEL);
+ FLUSH_OBJECT
+ to_cpio("hdt");
+}
diff --git a/com32/hdt/hdt-dump-kernel.c b/com32/hdt/hdt-dump-kernel.c
new file mode 100644
index 00000000..e0df8320
--- /dev/null
+++ b/com32/hdt/hdt-dump-kernel.c
@@ -0,0 +1,69 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-common.h"
+#include "hdt-dump.h"
+
+void dump_kernel(struct s_hardware *hardware, ZZJSON_CONFIG * config,
+ ZZJSON ** item)
+{
+ struct pci_device *pci_device = NULL;
+ CREATE_ARRAY
+ add_as("Linux Kernel modules", "")
+ END_OF_ARRAY;
+
+ if (hardware->pci_ids_return_code == -ENOPCIIDS) {
+ APPEND_ARRAY
+ add_as("Error", "No pci.ids file")
+ END_OF_APPEND FLUSH_OBJECT;
+ return;
+ }
+
+ if ((hardware->modules_pcimap_return_code == -ENOMODULESPCIMAP)
+ &&(hardware->modules_pcimap_return_code == -ENOMODULESALIAS)) {
+ APPEND_ARRAY
+ add_as("Error", "No modules.pcimap or modules.alias file")
+ END_OF_APPEND FLUSH_OBJECT;
+ return;
+
+ }
+
+ /* For every detected pci device, compute its submenu */
+ for_each_pci_func(pci_device, hardware->pci_domain) {
+ if (pci_device == NULL)
+ continue;
+ for (int kmod = 0;
+ kmod < pci_device->dev_info->linux_kernel_module_count; kmod++) {
+ APPEND_ARRAY
+ add_as(pci_device->dev_info->category_name, pci_device->dev_info->linux_kernel_module[kmod])
+ END_OF_APPEND;
+ }
+ }
+ FLUSH_OBJECT;
+ to_cpio("kernel");
+}
diff --git a/com32/hdt/hdt-dump-memory.c b/com32/hdt/hdt-dump-memory.c
new file mode 100644
index 00000000..5095d3c2
--- /dev/null
+++ b/com32/hdt/hdt-dump-memory.c
@@ -0,0 +1,133 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <memory.h>
+#include "hdt-common.h"
+#include "hdt-dump.h"
+
+void dump_88(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+ (void) hardware;
+ int mem_size = 0;
+ CREATE_NEW_OBJECT;
+ if (detect_memory_88(&mem_size)) {
+ add_s("memory.error","8800h memory configuration is invalid");
+ FLUSH_OBJECT
+ return;
+ }
+
+ add_s("dmi.item","memory via 88");
+ add_i("memory.size (KiB)", mem_size);
+ add_i("memory.size (MiB)", mem_size >> 10);
+ FLUSH_OBJECT;
+}
+
+void dump_e801(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+ (void) hardware;
+ int mem_low, mem_high = 0;
+ CREATE_NEW_OBJECT;
+ if (detect_memory_e801(&mem_low,&mem_high)) {
+ add_s("memory.error","e801 memory configuration is invalid");
+ FLUSH_OBJECT;
+ return;
+ }
+
+ add_s("dmi.item","memory via e801");
+ add_i("memory.total.size (KiB)", mem_low + (mem_high << 6));
+ add_i("memory.total.size (MiB)", (mem_low >> 10) + (mem_high >> 4));
+ add_i("memory.low.size (KiB)", mem_low );
+ add_i("memory.low.size (MiB)", mem_low >> 10);
+ add_i("memory.high.size (KiB)", mem_high << 6);
+ add_i("memory.high.size (MiB)", mem_high >> 4);
+ FLUSH_OBJECT;
+
+}
+void dump_e820(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+ (void) hardware;
+ struct e820entry map[E820MAX];
+ struct e820entry nm[E820MAX];
+ unsigned long memsize = 0;
+ int count = 0;
+ char type[14] = {0};
+
+ detect_memory_e820(map, E820MAX, &count);
+ memsize = memsize_e820(map, count);
+
+ CREATE_NEW_OBJECT;
+ add_s("dmi.item","memory via e820");
+ add_i("memory.total.size (KiB)", memsize);
+ add_i("memory.total.size (MiB)", (memsize + (1 << 9)) >> 10);
+ FLUSH_OBJECT;
+
+ for (int i = 0; i < count; i++) {
+ get_type(map[i].type, type, sizeof(type));
+ char begin[24]={0};
+ char size[24]={0};
+ char end[24]={0};
+ snprintf(begin,sizeof(begin),"0x%016llx",map[i].addr);
+ snprintf(size,sizeof(size),"0x%016llx",map[i].size);
+ snprintf(end,sizeof(end),"0x%016llx",map[i].addr+map[i].size);
+ CREATE_NEW_OBJECT;
+ add_s("memory.segment.start",begin);
+ add_s("memory.segment.size ",size);
+ add_s("memory.segment.end ",end);
+ add_s("memory.segment.type ",remove_spaces(type));
+ FLUSH_OBJECT;
+ }
+
+ int nr = sanitize_e820_map(map, nm, count);
+ for (int i = 0; i < nr; i++) {
+ get_type(nm[i].type, type, sizeof(type));
+ char begin[24]={0};
+ char size[24]={0};
+ char end[24]={0};
+ snprintf(begin,sizeof(begin),"0x%016llx",nm[i].addr);
+ snprintf(size,sizeof(size),"0x%016llx",nm[i].size);
+ snprintf(end,sizeof(end),"0x%016llx",nm[i].addr+nm[i].size);
+ CREATE_NEW_OBJECT;
+ add_s("sanitized_memory.segment.start",begin);
+ add_s("sanitized_memory.segment.size ",size);
+ add_s("sanitized_memory.segment.end ",end);
+ add_s("sanitized_memory.segment.type ",remove_spaces(type));
+ FLUSH_OBJECT;
+ }
+}
+
+void dump_memory(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+ CREATE_NEW_OBJECT;
+ add_s("Memory configuration","true");
+ FLUSH_OBJECT;
+
+ dump_88(hardware,config,item);
+ dump_e801(hardware,config,item);
+ dump_e820(hardware,config,item);
+ to_cpio("memory");
+}
diff --git a/com32/hdt/hdt-dump-pci.c b/com32/hdt/hdt-dump-pci.c
new file mode 100644
index 00000000..b1f18fdf
--- /dev/null
+++ b/com32/hdt/hdt-dump-pci.c
@@ -0,0 +1,136 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-common.h"
+#include "hdt-dump.h"
+
+void dump_pci(struct s_hardware *hardware, ZZJSON_CONFIG * config,
+ ZZJSON ** item)
+{
+ int i = 1;
+ struct pci_device *pci_device=NULL;
+ char kernel_modules[LINUX_KERNEL_MODULE_SIZE *
+ MAX_KERNEL_MODULES_PER_PCI_DEVICE];
+ bool nopciids = false;
+ bool nomodulespcimap = false;
+ bool nomodulesalias = false;
+ bool nomodulesfile = false;
+ int bus = 0, slot = 0, func = 0;
+
+ if (hardware->pci_ids_return_code == -ENOPCIIDS) {
+ nopciids = true;
+ }
+ if (hardware->modules_pcimap_return_code == -ENOMODULESPCIMAP) {
+ nomodulespcimap = true;
+ }
+ if (hardware->modules_pcimap_return_code == -ENOMODULESALIAS) {
+ nomodulesalias = true;
+ }
+
+ nomodulesfile = nomodulespcimap && nomodulesalias;
+
+ CREATE_NEW_OBJECT;
+
+ add_i("pci_device.count", hardware->nb_pci_devices);
+
+ FLUSH_OBJECT;
+ /* For every detected pci device, compute its submenu */
+ for_each_pci_func(pci_device, hardware->pci_domain) {
+ if (pci_device == NULL)
+ continue;
+ char v[10] = { 0 };
+ char sv[10] = { 0 };
+ char p[10] = { 0 };
+ char sp[10] = { 0 };
+ char c[10] = { 0 };
+ char r[10] = { 0 };
+
+ CREATE_NEW_OBJECT;
+ bus = __pci_bus;
+ slot = __pci_slot;
+ func = __pci_func;
+
+ memset(kernel_modules, 0, sizeof kernel_modules);
+ for (int kmod = 0;
+ kmod < pci_device->dev_info->linux_kernel_module_count; kmod++) {
+ if (kmod > 0) {
+ strncat(kernel_modules, " | ", 3);
+ }
+ strncat(kernel_modules,
+ pci_device->dev_info->linux_kernel_module[kmod],
+ LINUX_KERNEL_MODULE_SIZE - 1);
+ }
+ if (pci_device->dev_info->linux_kernel_module_count == 0)
+ strlcpy(kernel_modules, "unknown", 7);
+
+ add_i("pci_device.number", i);
+ if (nopciids == false) {
+ add_s("pci_device.vendor_name", pci_device->dev_info->vendor_name);
+ add_s("pci_device.product_name",
+ pci_device->dev_info->product_name);
+ }
+ if (nomodulesfile == false) {
+ add_s("pci_device.class_name", pci_device->dev_info->class_name);
+ add_s("pci_device.kernel_module", kernel_modules);
+ }
+
+ snprintf(v, sizeof(v), "%04x", pci_device->vendor);
+ snprintf(p, sizeof(p), "%04x", pci_device->product);
+ snprintf(sv, sizeof(sv), "%04x", pci_device->sub_vendor);
+ snprintf(sp, sizeof(sp), "%04x", pci_device->sub_product);
+ snprintf(c, sizeof(c), "%02x.%02x.%02x",
+ pci_device->class[2],
+ pci_device->class[1], pci_device->class[0]);
+ snprintf(r, sizeof(r), "%02x", pci_device->revision);
+ add_s("pci_device.vendor_id", v);
+ add_s("pci_device.product_id", p);
+ add_s("pci_device.sub_vendor_id", sv);
+ add_s("pci_device.sub_product_id", sp);
+ add_s("pci_device.class_id", c);
+ add_s("pci_device.revision", r);
+ if ((pci_device->dev_info->irq > 0)
+ && (pci_device->dev_info->irq < 255))
+ add_i("pci_device.irq", pci_device->dev_info->irq);
+
+ add_i("pci_device.latency", pci_device->dev_info->latency);
+ add_i("pci_device.bus", bus);
+ add_i("pci_device.slot", slot);
+ add_i("pci_device.func", func);
+
+ if (hardware->is_pxe_valid == true) {
+ if ((hardware->pxe.pci_device != NULL)
+ && (hardware->pxe.pci_device == pci_device)) {
+ add_hs(pxe.mac_addr);
+ add_s("pxe", "Current boot device");
+ }
+ }
+ i++;
+ FLUSH_OBJECT;
+ }
+ to_cpio("pci");
+}
diff --git a/com32/hdt/hdt-dump-pxe.c b/com32/hdt/hdt-dump-pxe.c
new file mode 100644
index 00000000..4e25c943
--- /dev/null
+++ b/com32/hdt/hdt-dump-pxe.c
@@ -0,0 +1,80 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-common.h"
+#include "hdt-dump.h"
+#include <sys/gpxe.h>
+#include <netinet/in.h>
+
+void dump_pxe(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+ struct in_addr in;
+
+ CREATE_NEW_OBJECT;
+ add_hb(is_pxe_valid);
+ if (hardware->is_pxe_valid) {
+ char buffer[32] = {0};
+ snprintf(buffer,sizeof(buffer),"0x%x",hardware->pxe.vendor_id);
+ add_s("pxe.vendor_id",buffer);
+ snprintf(buffer,sizeof(buffer),"0x%x",hardware->pxe.product_id);
+ add_s("pxe.product_id",buffer);
+ snprintf(buffer,sizeof(buffer),"0x%x",hardware->pxe.subvendor_id);
+ add_s("pxe.subvendor_id",buffer);
+ snprintf(buffer,sizeof(buffer),"0x%x",hardware->pxe.subproduct_id);
+ add_s("pxe.subproduct_id",buffer);
+
+ if (hardware->pci_ids_return_code == -ENOPCIIDS || (hardware->pxe.pci_device == NULL)) {
+ add_s("Manufacturer_name","no_pci_ids_file or no device found");
+ add_s("Product_name","no_pci_ids_file or no device found");
+ } else {
+ add_s("Manufacturer_name", hardware->pxe.pci_device->dev_info->vendor_name);
+ add_s("Product_name", hardware->pxe.pci_device->dev_info->product_name);
+ }
+
+ add_hi(pxe.rev);
+ add_hi(pxe.pci_bus);
+ add_hi(pxe.pci_dev);
+ add_hi(pxe.pci_func);
+ add_hi(pxe.base_class);
+ add_hi(pxe.sub_class);
+ add_hi(pxe.prog_intf);
+ add_hi(pxe.nictype);
+ add_hs(pxe.mac_addr);
+
+ in.s_addr = hardware->pxe.dhcpdata.cip;
+ add_s("pxe.client_ip", inet_ntoa(in));
+ in.s_addr = hardware->pxe.dhcpdata.sip;
+ add_s("pxe.next_server_ip",inet_ntoa(in));
+ in.s_addr = hardware->pxe.dhcpdata.gip;
+ add_s("pxe.relay_agent_ip",inet_ntoa(in));
+ memcpy(&in, hardware->pxe.ip_addr, sizeof in);
+ add_s("pxe.ipaddr",inet_ntoa(in));
+ add_b("gpxe_detected",is_gpxe());
+ }
+ FLUSH_OBJECT;
+ to_cpio("pxe");
+}
diff --git a/com32/hdt/hdt-dump-syslinux.c b/com32/hdt/hdt-dump-syslinux.c
new file mode 100644
index 00000000..7cef925f
--- /dev/null
+++ b/com32/hdt/hdt-dump-syslinux.c
@@ -0,0 +1,43 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-common.h"
+#include "hdt-dump.h"
+#include <syslinux/config.h>
+
+void dump_syslinux(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+ CREATE_NEW_OBJECT;
+ add_hs(syslinux_fs);
+ add_hs(sv->version_string);
+ add_hi(sv->version);
+ add_hi(sv->max_api);
+ add_hs(sv->copyright_string);
+ FLUSH_OBJECT
+ to_cpio("syslinux");
+}
diff --git a/com32/hdt/hdt-dump-vesa.c b/com32/hdt/hdt-dump-vesa.c
new file mode 100644
index 00000000..97d56c95
--- /dev/null
+++ b/com32/hdt/hdt-dump-vesa.c
@@ -0,0 +1,67 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-common.h"
+#include "hdt-dump.h"
+#include <syslinux/config.h>
+
+void dump_vesa(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+ CREATE_NEW_OBJECT;
+ add_hb(is_vesa_valid);
+ if (hardware->is_vesa_valid) {
+ char buffer[64]={0};
+ snprintf(buffer,sizeof(buffer),"%d.%d", hardware->vesa.major_version, hardware->vesa.minor_version);
+ add_s("vesa.version",buffer);
+ add_hs(vesa.vendor);
+ add_hs(vesa.product);
+ add_hs(vesa.product_revision);
+ add_hi(vesa.software_rev);
+ memset(buffer,0,sizeof(buffer));
+ snprintf(buffer,sizeof(buffer),"%d KB",hardware->vesa.total_memory*64);
+ add_s("vesa.memory",buffer);
+ add_i("vesa.modes",hardware->vesa.vmi_count);
+ FLUSH_OBJECT;
+ for (int i = 0; i < hardware->vesa.vmi_count; i++) {
+ struct vesa_mode_info *mi = &hardware->vesa.vmi[i].mi;
+ if ((mi->h_res == 0) || (mi->v_res == 0))
+ continue;
+ CREATE_NEW_OBJECT;
+ memset(buffer,0,sizeof(buffer));
+ snprintf(buffer,sizeof(buffer),"0x%04x",hardware->vesa.vmi[i].mode + 0x200);
+ add_s("vesa.kernel_mode",buffer);
+ add_i("vesa.hres",mi->h_res);
+ add_i("vesa.vres",mi->v_res);
+ add_i("vesa.bpp",mi->bpp);
+ FLUSH_OBJECT;
+ }
+ } else {
+ FLUSH_OBJECT;
+ }
+ to_cpio("vesa");
+}
diff --git a/com32/hdt/hdt-dump-vpd.c b/com32/hdt/hdt-dump-vpd.c
new file mode 100644
index 00000000..36451c8a
--- /dev/null
+++ b/com32/hdt/hdt-dump-vpd.c
@@ -0,0 +1,47 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-common.h"
+#include "hdt-dump.h"
+
+void dump_vpd(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+ CREATE_NEW_OBJECT;
+ add_hb(is_vpd_valid);
+ if (hardware->is_vpd_valid) {
+ add_hs(vpd.bios_build_id);
+ add_hs(vpd.bios_release_date);
+ add_hs(vpd.bios_version);
+ add_hs(vpd.default_flash_filename);
+ add_hs(vpd.box_serial_number);
+ add_hs(vpd.motherboard_serial_number);
+ add_hs(vpd.machine_type_model);
+ }
+ FLUSH_OBJECT;
+ to_cpio("vpd");
+}
diff --git a/com32/hdt/hdt-dump.c b/com32/hdt/hdt-dump.c
new file mode 100644
index 00000000..8c221405
--- /dev/null
+++ b/com32/hdt/hdt-dump.c
@@ -0,0 +1,169 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <getkey.h>
+#include <syslinux/config.h>
+#include "hdt-common.h"
+#include "hdt-dump.h"
+
+struct print_buf p_buf;
+
+void compute_filename(struct s_hardware *hardware, char *filename, int size) {
+
+ snprintf(filename,size,"%s/",hardware->dump_path);
+
+ if (hardware->is_pxe_valid) {
+ strncat(filename, hardware->pxe.mac_addr, sizeof(hardware->pxe.mac_addr));
+ strncat(filename, "+", 1);
+ }
+
+ if (hardware->is_dmi_valid) {
+ strncat(filename, remove_spaces(hardware->dmi.system.product_name), sizeof(hardware->dmi.system.manufacturer));
+ strncat(filename, "+", 1);
+ strncat(filename, remove_spaces(hardware->dmi.system.manufacturer), sizeof(hardware->dmi.system.product_name));
+ }
+
+ /* We replace the ":" in the filename by some "-"
+ * This will avoid Microsoft FS turning crazy */
+ chrreplace(filename,':','-');
+
+ /* Avoid space to make filename easier to manipulate */
+ chrreplace(filename,' ','_');
+
+}
+
+int dumpprintf(FILE *p, const char *format, ...) {
+ va_list ap;
+ int rv;
+
+ (void) p;
+ va_start(ap, format);
+ rv = vbufprintf(&p_buf,format, ap);
+ va_end(ap);
+ return rv;
+}
+
+void to_cpio(char *filename) {
+ cpio_writefile(upload,filename,p_buf.buf,p_buf.len);
+ if ((p_buf.buf) && (p_buf.len > 0)){
+ memset(p_buf.buf,0,p_buf.len);
+ free(p_buf.buf);
+ p_buf.buf=NULL;
+ p_buf.size=0;
+ p_buf.len=0;
+ }
+}
+
+void flush (ZZJSON_CONFIG *config, ZZJSON ** item) {
+ zzjson_print(config, *item);
+ zzjson_free(config, *item);
+ *item=NULL;
+}
+
+/**
+ * dump - dump info
+ **/
+void dump(struct s_hardware *hardware)
+{
+ if (hardware->is_pxe_valid==false) {
+ printf("PXE stack was not detected, Dump feature is not available\n");
+ return;
+ }
+
+ const union syslinux_derivative_info *sdi = syslinux_derivative_info();
+ int err=0;
+ ZZJSON *json = NULL;
+ ZZJSON_CONFIG config = { ZZJSON_VERY_STRICT, NULL,
+ (int(*)(void*)) fgetc,
+ NULL,
+ malloc, calloc, free, realloc,
+ stderr, NULL, stdout,
+ (int(*)(void *,const char*,...)) dumpprintf,
+ (int(*)(int,void*)) fputc
+ };
+
+ memset(&p_buf,0,sizeof(p_buf));
+
+ /* By now, we only support TFTP reporting */
+ upload=&upload_tftp;
+ upload->name="tftp";
+
+ /* The following defines the behavior of the reporting */
+ char *arg[64];
+ char filename[512]={0};
+ compute_filename(hardware, filename, sizeof(filename));
+
+ /* The filename */
+ arg[0] = filename;
+ /* The server to upload the file */
+ if (strlen(hardware->tftp_ip) != 0) {
+ arg[1] = hardware->tftp_ip;
+ arg[2] = NULL;
+ } else {
+ arg[1] = NULL;
+ snprintf(hardware->tftp_ip, sizeof(hardware->tftp_ip),
+ "%u.%u.%u.%u",
+ ((uint8_t *)&sdi->pxe.ipinfo->serverip)[0],
+ ((uint8_t *)&sdi->pxe.ipinfo->serverip)[1],
+ ((uint8_t *)&sdi->pxe.ipinfo->serverip)[2],
+ ((uint8_t *)&sdi->pxe.ipinfo->serverip)[3]);
+
+ }
+
+ /* We initiate the cpio to send */
+ cpio_init(upload,(const char **)arg);
+
+ dump_cpu(hardware, &config, &json);
+ dump_pxe(hardware, &config, &json);
+ dump_syslinux(hardware, &config, &json);
+ dump_vpd(hardware, &config, &json);
+ dump_vesa(hardware, &config, &json);
+ dump_disks(hardware, &config, &json);
+ dump_dmi(hardware, &config, &json);
+ dump_memory(hardware, &config, &json);
+ dump_pci(hardware, &config, &json);
+ dump_acpi(hardware, &config, &json);
+ dump_kernel(hardware, &config, &json);
+ dump_hdt(hardware, &config, &json);
+
+ /* We close & flush the file to send */
+ cpio_close(upload);
+
+ if ((err=flush_data(upload)) != TFTP_OK) {
+ /* As we manage a tftp connection, let's display the associated error message */
+ more_printf("Dump failed !\n");
+ more_printf("TFTP ERROR on : %s:/%s \n",hardware->tftp_ip, filename);
+ more_printf("TFTP ERROR msg : %s \n",tftp_string_error_message[-err]);
+ } else {
+ more_printf("Dump file sent at %s:/%s\n",hardware->tftp_ip, filename);
+ }
+}
diff --git a/com32/hdt/hdt-dump.h b/com32/hdt/hdt-dump.h
new file mode 100644
index 00000000..f9669dac
--- /dev/null
+++ b/com32/hdt/hdt-dump.h
@@ -0,0 +1,85 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 20011 Erwan Velu - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <bufprintf.h>
+#include <zzjson/zzjson.h>
+#include "hdt-common.h"
+
+// Macros to manipulate Arrays
+#define APPEND_ARRAY ZZJSON *temp_array; temp_array = zzjson_array_append(config, *item, zzjson_create_object(config,
+#define APPEND_OBJECT_ARRAY(value) ZZJSON *temp_ar; temp_ar = zzjson_array_append(config, *item, value); *item=temp_ar;
+#define CREATE_ARRAY *item = zzjson_create_array(config, zzjson_create_object(config,
+#define add_ai(name,value) name,zzjson_create_number_i(config,value),
+#define add_ahi(value) add_ai(#value,hardware->value)
+#define add_as(name,value) name,zzjson_create_string(config,value),
+#define add_ahs(value) add_as(#value,hardware->value)
+#define END_OF_ARRAY NULL),NULL)
+#define END_OF_APPEND NULL)); *item=temp_array;
+
+// Macros to manipulate objects
+#define CREATE_NEW_OBJECT *item = zzjson_create_object(config, NULL);
+#define FLUSH_OBJECT flush(config, item);
+
+// Macros to manipulate integers as objects
+#define add_i(name,value) *item = zzjson_object_append(config, *item, name, zzjson_create_number_i(config, value))
+#define add_hi(value) add_i(#value,hardware->value)
+
+// Macros to manipulate strings as objects
+#define add_s(name,value) *item = zzjson_object_append(config, *item, name, zzjson_create_string(config, value))
+#define add_hs(value) add_s(#value,(char *)hardware->value)
+
+// Macros to manipulate bool as objects
+#define add_bool_true(name) *item = zzjson_object_append(config, *item, (char *)name, zzjson_create_true(config))
+#define add_bool_false(name) *item = zzjson_object_append(config, *item, (char*)name, zzjson_create_false(config))
+#define add_b(name,value) if (value==true) {add_bool_true(name);} else {add_bool_false(name);}
+#define add_hb(value) add_b(#value,hardware->value)
+
+extern struct print_buf p_buf;
+
+void print_and_flush(ZZJSON_CONFIG *config, ZZJSON **item);
+int dumpprintf(FILE *p, const char *format, ...);
+void flush (ZZJSON_CONFIG *config, ZZJSON ** item);
+void to_cpio(char *filename);
+
+void dump_cpu(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_pxe(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_syslinux(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_vpd(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_vesa(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_disks(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_dmi(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_memory(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_pci(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_acpi(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_kernel(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_hdt(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump(struct s_hardware *hardware);
diff --git a/com32/hdt/hdt-menu-acpi.c b/com32/hdt/hdt-menu-acpi.c
index 16bcf73a..8e0ba18f 100644
--- a/com32/hdt/hdt-menu-acpi.c
+++ b/com32/hdt/hdt-menu-acpi.c
@@ -32,7 +32,7 @@ void compute_table(struct s_my_menu *menu, void *address, s_acpi_description_hea
char buffer[SUBMENULEN + 1] = { 0 };
char statbuffer[STATLEN + 1] = { 0 };
- snprintf(buffer, sizeof buffer, "%-4s v%03x %-6s %-7s %-7s %08x",
+ snprintf(buffer, sizeof buffer, "%-4s v%03x %-6s %-8s %-7s %08x",
h->signature, h->revision, h->oem_id, h->oem_table_id, h->creator_id, h->creator_revision);
snprintf(statbuffer, sizeof statbuffer, "%-4s v%03x %-6s %-7s 0x%08x %-4s 0x%08x @ 0x%p",
h->signature, h->revision, h->oem_id, h->oem_table_id,
@@ -52,7 +52,7 @@ static void compute_acpi_tables(struct s_my_menu *menu,
char buffer[SUBMENULEN + 1] = { 0 };
- snprintf(buffer, sizeof buffer, "%-4s %-4s %-6s %-7s %-7s %-8s",
+ snprintf(buffer, sizeof buffer, "%-4s %-4s %-6s %-8s %-7s %-8s",
"ACPI", "rev", "oem", "table_id", "creator", "creator_rev");
add_item(buffer, "Description", OPT_INACTIVE, NULL, 0);
menu->items_count++;
diff --git a/com32/hdt/hdt-menu-disk.c b/com32/hdt/hdt-menu-disk.c
index b0b4a5ac..0716b435 100644
--- a/com32/hdt/hdt-menu-disk.c
+++ b/com32/hdt/hdt-menu-disk.c
@@ -120,9 +120,9 @@ static void compute_partition_information(struct driveinfo *drive_info,
add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
}
- snprintf(buffer, sizeof buffer, "Bootable : %s",
+ snprintf(buffer, sizeof buffer, "Boot Flag : %s",
(ptab->active_flag == 0x80) ? "Yes" : "No");
- snprintf(statbuffer, sizeof statbuffer, "Bootable: %s",
+ snprintf(statbuffer, sizeof statbuffer, "Boot Flag: %s",
(ptab->active_flag == 0x80) ? "Yes" : "No");
add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
@@ -243,12 +243,12 @@ void compute_disks(struct s_hdt_menu *menu, struct s_hardware *hardware)
if (hardware->disks_count == 0)
return;
- for (int i = 0; i < hardware->disks_count; i++) {
- if (!hardware->disk_info[i].cbios)
+ for (int drive = 0x80; drive < 0xff; drive++) {
+ if (!hardware->disk_info[drive - 0x80].cbios)
continue; /* Invalid geometry */
compute_disk_module
((struct s_my_menu *)&(menu->disk_sub_menu), nb_sub_disk_menu,
- hardware, i);
+ hardware, drive - 0x80);
nb_sub_disk_menu++;
}
diff --git a/com32/hdt/hdt-menu-pxe.c b/com32/hdt/hdt-menu-pxe.c
index 426bfe07..12d8b116 100644
--- a/com32/hdt/hdt-menu-pxe.c
+++ b/com32/hdt/hdt-menu-pxe.c
@@ -34,7 +34,7 @@ void compute_PXE(struct s_my_menu *menu, struct s_hardware *hardware)
{
char buffer[SUBMENULEN + 1];
char infobar[STATLEN + 1];
- char gpxe[4];
+ char gpxe[4]={0};
if (hardware->is_pxe_valid == false)
return;
@@ -113,8 +113,8 @@ void compute_PXE(struct s_my_menu *menu, struct s_hardware *hardware)
add_item(buffer, infobar, OPT_INACTIVE, NULL, 0);
menu->items_count++;
- if (is_gpxe()) strcat(gpxe,"Yes");
- else strcat (gpxe,"No");
+ if (is_gpxe()) snprintf(gpxe,sizeof(gpxe),"%s","Yes");
+ else snprintf (gpxe, sizeof(gpxe), "%s", "No");
snprintf(buffer, sizeof buffer, "gPXE Detected: %s", gpxe);
snprintf(infobar, sizeof infobar, "gPXE Detected: %s", gpxe);
diff --git a/com32/hdt/hdt-menu.c b/com32/hdt/hdt-menu.c
index 0fdee039..50b3eaa8 100644
--- a/com32/hdt/hdt-menu.c
+++ b/com32/hdt/hdt-menu.c
@@ -62,6 +62,12 @@ int start_menu_mode(struct s_hardware *hardware, char *version_string)
(curr->data, HDT_SWITCH_TO_CLI, sizeof(HDT_SWITCH_TO_CLI))) {
return HDT_RETURN_TO_CLI;
}
+ /* Tweak, we want to start the dump mode */
+ if (!strncmp
+ (curr->data, HDT_DUMP, sizeof(HDT_DUMP))) {
+ dump(hardware);
+ return 0;
+ }
if (!strncmp
(curr->data, HDT_REBOOT, sizeof(HDT_REBOOT))) {
syslinux_reboot(1);
@@ -289,6 +295,12 @@ void compute_main_menu(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware)
add_item("S<w>itch to CLI", "Switch to Command Line", OPT_RUN,
HDT_SWITCH_TO_CLI, 0);
+
+ if (hardware->is_pxe_valid == true) {
+ add_item("<D>ump to tftp", "Dump to tftp", OPT_RUN,
+ HDT_DUMP, 0);
+ }
+
add_item("<A>bout", "About Menu", OPT_SUBMENU, NULL,
hdt_menu->about_menu.menu);
add_item("<R>eboot", "Reboot", OPT_RUN, HDT_REBOOT, 0);
diff --git a/com32/hdt/hdt.h b/com32/hdt/hdt.h
index dd489480..7b35236e 100644
--- a/com32/hdt/hdt.h
+++ b/com32/hdt/hdt.h
@@ -33,8 +33,8 @@
#define AUTHOR "Erwan Velu"
#define CORE_DEVELOPER "Pierre-Alexandre Meyer"
#define CONTACT "hdt@zytor.com"
-#define VERSION "0.4.1"
-#define CODENAME "chouffe"
+#define VERSION "0.5.0"
+#define CODENAME "Van De Keizer"
#define NB_CONTRIBUTORS 3
#define CONTRIBUTORS {"Sebastien Gonzalve (Patches)", "Gert Hulselmans (Tests)", "Alexander Andino (Design)"}
#define WEBSITE_URL "http://hdt-project.org"
diff --git a/com32/include/bufprintf.h b/com32/include/bufprintf.h
new file mode 100644
index 00000000..5cbeaa4b
--- /dev/null
+++ b/com32/include/bufprintf.h
@@ -0,0 +1,10 @@
+#define BUFPAD 4096
+
+struct print_buf {
+ char *buf;
+ size_t len;
+ size_t size;
+};
+
+int vbufprintf(struct print_buf *buf, const char *format, va_list ap);
+int bufprintf(struct print_buf *buf, const char *format, ...);
diff --git a/com32/include/cpufeature.h b/com32/include/cpufeature.h
index df9dd3d3..83263c2c 100644
--- a/com32/include/cpufeature.h
+++ b/com32/include/cpufeature.h
@@ -7,7 +7,7 @@
#ifndef __ASM_I386_CPUFEATURE_H
#define __ASM_I386_CPUFEATURE_H
-#define NCAPINTS 7 /* N 32-bit words worth of info */
+#define NCAPINTS 9 /* N 32-bit words worth of info */
/* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */
#define X86_FEATURE_FPU (0*32+ 0) /* Onboard FPU */
diff --git a/com32/include/ctype.h b/com32/include/ctype.h
index 83bbda1c..6e0645ee 100644
--- a/com32/include/ctype.h
+++ b/com32/include/ctype.h
@@ -117,5 +117,6 @@ __ctype_inline int tolower(int __c)
}
__extern char *skipspace(const char *p);
+__extern void chrreplace(char *source, char old, char new);
#endif /* _CTYPE_H */
diff --git a/com32/include/netinet/in.h b/com32/include/netinet/in.h
index ccf04750..d2af351f 100644
--- a/com32/include/netinet/in.h
+++ b/com32/include/netinet/in.h
@@ -5,6 +5,7 @@
#include <stdint.h>
#include <klibc/compiler.h>
+#include <klibc/extern.h>
#define __htons_macro(v) ((uint16_t) \
(((uint16_t)(v) << 8) | \
@@ -53,4 +54,6 @@ struct in_addr {
in_addr_t s_addr;
};
+__extern char *inet_ntoa(struct in_addr);
+
#endif /* _NETINET_IN_H */
diff --git a/com32/include/sys/bitops.h b/com32/include/sys/bitops.h
index 33bb0aa8..40e09fe7 100644
--- a/com32/include/sys/bitops.h
+++ b/com32/include/sys/bitops.h
@@ -54,7 +54,7 @@ static inline int __purefunc test_bit(long __bit, const void *__bitmap)
{
unsigned char __r;
asm("btl %2,%1; setc %0"
- : "=r" (__r)
+ : "=qm" (__r)
: "m" (*(const unsigned char *)__bitmap), "Ir" (__bit));
return __r;
}
diff --git a/com32/lib/Makefile b/com32/lib/Makefile
index 26d90538..22eabbd9 100644
--- a/com32/lib/Makefile
+++ b/com32/lib/Makefile
@@ -4,8 +4,9 @@
# Include configuration rules
NOGPL := 1
-topdir = ../..
-include MCONFIG
+topdir = ../../
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/lib.mk
## OPTIONAL OBJECTS, AVAILABLE AS DYNAMIC LINKED MODULES
# PNG library object files
@@ -126,6 +127,9 @@ LIBOTHER_OBJS = \
asprintf.o vasprintf.o strlcpy.o strlcat.o \
vsscanf.o \
skipspace.o \
+ chrreplace.o \
+ bufprintf.o \
+ inet.o \
\
lmalloc.o lstrdup.o \
\
diff --git a/com32/lib/bufprintf.c b/com32/lib/bufprintf.c
new file mode 100644
index 00000000..939bcec3
--- /dev/null
+++ b/com32/lib/bufprintf.c
@@ -0,0 +1,41 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <bufprintf.h>
+
+int vbufprintf(struct print_buf *buf, const char *format, va_list ap)
+{
+ va_list ap2;
+ int rv;
+
+ va_copy(ap2, ap);
+ rv = vsnprintf(NULL, 0, format, ap);
+
+ /* >= to make sure we have space for terminating null */
+ if (rv + buf->len >= buf->size) {
+ size_t newsize = rv + buf->len + BUFPAD;
+ char *newbuf;
+
+ newbuf = realloc(buf->buf, newsize);
+ if (!newbuf)
+ return -1;
+
+ buf->buf = newbuf;
+ buf->size = newsize;
+ }
+
+ rv = vsnprintf(buf->buf + buf->len, buf->size - buf->len, format, ap2);
+ buf->len += rv;
+ return rv;
+}
+
+int bufprintf(struct print_buf *buf, const char *format, ...)
+{
+ va_list ap;
+ int rv;
+
+ va_start(ap, format);
+ rv = vbufprintf(buf, format, ap);
+ va_end(ap);
+ return rv;
+}
diff --git a/com32/lib/chrreplace.c b/com32/lib/chrreplace.c
new file mode 100644
index 00000000..65786f94
--- /dev/null
+++ b/com32/lib/chrreplace.c
@@ -0,0 +1,11 @@
+#include <ctype.h>
+
+/* Replace char 'old' by char 'new' in source */
+void chrreplace(char *source, char old, char new)
+{
+ while (*source) {
+ source++;
+ if (source[0] == old) source[0]=new;
+ }
+}
+
diff --git a/com32/lib/inet.c b/com32/lib/inet.c
new file mode 100644
index 00000000..133645ed
--- /dev/null
+++ b/com32/lib/inet.c
@@ -0,0 +1,39 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <netinet/in.h>
+
+char *inet_ntoa(struct in_addr addr)
+{
+ static char buf[16];
+ const uint8_t *bytes = (const uint8_t *)&addr.s_addr;
+
+ sprintf(buf, "%u.%u.%u.%u", bytes[0], bytes[1], bytes[2], bytes[3]);
+ return buf;
+}
diff --git a/com32/lib/jpeg/tinyjpeg-internal.h b/com32/lib/jpeg/tinyjpeg-internal.h
index bb5c6707..8e6d4fdf 100644
--- a/com32/lib/jpeg/tinyjpeg-internal.h
+++ b/com32/lib/jpeg/tinyjpeg-internal.h
@@ -152,7 +152,7 @@ enum std_markers {
#define SANITY_CHECK 1
-#if DEBUG
+#if JPEG_DEBUG
#define error(fmt, args...) do { \
snprintf(error_string, sizeof(error_string), fmt, ## args); \
return -1; \
diff --git a/com32/lib/jpeg/tinyjpeg.c b/com32/lib/jpeg/tinyjpeg.c
index 2927b718..47317d00 100644
--- a/com32/lib/jpeg/tinyjpeg.c
+++ b/com32/lib/jpeg/tinyjpeg.c
@@ -440,7 +440,7 @@ static void build_default_huffman_tables(struct jdec_private *priv)
static void print_SOF(const unsigned char *stream)
{
-#if DEBUG
+#if JPEG_DEBUG
int width, height, nr_components, precision;
const char *nr_components_to_string[] = {
"????",
@@ -664,7 +664,7 @@ static int parse_DRI(struct jdec_private *priv, const unsigned char *stream)
priv->restart_interval = be16_to_cpu(stream+2);
-#if DEBUG
+#if JPEG_DEBUG
trace("Restart interval = %d\n", priv->restart_interval);
#endif
diff --git a/com32/lib/pci/scan.c b/com32/lib/pci/scan.c
index c8334b11..4e5635f6 100644
--- a/com32/lib/pci/scan.c
+++ b/com32/lib/pci/scan.c
@@ -66,15 +66,6 @@ static int hex_to_int(char *hexa)
return strtoul(hexa, NULL, 16);
}
-/* Replace char 'old' by char 'new' in source */
-void chr_replace(char *source, char old, char new)
-{
- while (*source) {
- source++;
- if (source[0] == old) source[0]=new;
- }
-}
-
/* Try to match any pci device to the appropriate kernel module */
/* it uses the modules.pcimap from the boot device */
int get_module_name_from_pcimap(struct pci_domain *domain,
@@ -135,7 +126,7 @@ int get_module_name_from_pcimap(struct pci_domain *domain,
* in the module name whereas modules.alias is only using '_'.
* To avoid kernel modules duplication, let's rename all '-' in '_'
* to match what modules.alias provides */
- case 0:chr_replace(result,'-','_');strcpy(module_name,result); break;
+ case 0:chrreplace(result,'-','_');strcpy(module_name,result); break;
case 1:strcpy(vendor_id,result); break;
case 2:strcpy(product_id,result); break;
case 3:strcpy(sub_vendor_id,result); break;
diff --git a/com32/libupload/.gitignore b/com32/libupload/.gitignore
new file mode 100644
index 00000000..e0292b19
--- /dev/null
+++ b/com32/libupload/.gitignore
@@ -0,0 +1,2 @@
+*.o
+*.a
diff --git a/com32/libupload/Makefile b/com32/libupload/Makefile
new file mode 100644
index 00000000..83053350
--- /dev/null
+++ b/com32/libupload/Makefile
@@ -0,0 +1,39 @@
+# Include configuration rules
+topdir = ../..
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/com32.mk
+
+REQFLAGS += -I./
+
+SUBDIRS := .
+LIBOBJS := $(foreach dir,$(SUBDIRS),$(patsubst %.c,%.o,$(wildcard $(dir)/*.c)))
+
+BINDIR = /usr/bin
+LIBDIR = /usr/lib
+DATADIR = /usr/share
+AUXDIR = $(DATADIR)/syslinux
+INCDIR = /usr/include
+COM32DIR = $(AUXDIR)/com32
+
+all: libcom32upload.a
+
+libcom32upload.a : $(LIBOBJS)
+ rm -f $@
+ $(AR) cq $@ $^
+ $(RANLIB) $@
+
+tidy dist clean:
+ find . \( -name \*.o -o -name \*.a -o -name .\*.d -o -name \*.tmp \) -print0 | \
+ xargs -0r rm -f
+
+spotless: clean
+ rm -f *.a
+ rm -f *~ \#* */*~ */\#*
+
+install: all
+ mkdir -m 755 -p $(INSTALLROOT)$(COM32DIR)
+ install -m 644 libcom32upload.a $(INSTALLROOT)$(COM32DIR)
+ mkdir -p $(INSTALLROOT)$(COM32DIR)/include/
+ cp -r *.h $(INSTALLROOT)$(COM32DIR)/include/
+
+-include .*.d */.*.d */*/.*.d
diff --git a/com32/sysdump/cpio.c b/com32/libupload/cpio.c
index 81d0d4be..b3e1eb78 100644
--- a/com32/sysdump/cpio.c
+++ b/com32/libupload/cpio.c
@@ -9,10 +9,10 @@
#include <inttypes.h>
#include <stdbool.h>
#include <zlib.h>
-#include "backend.h"
+#include "upload_backend.h"
#include "ctime.h"
-int cpio_pad(struct backend *be)
+int cpio_pad(struct upload_backend *be)
{
static char pad[4]; /* Up to 4 zero bytes */
if (be->dbytes & 3)
@@ -21,7 +21,7 @@ int cpio_pad(struct backend *be)
return 0;
}
-int cpio_hdr(struct backend *be, uint32_t mode, size_t datalen,
+int cpio_hdr(struct upload_backend *be, uint32_t mode, size_t datalen,
const char *filename)
{
static uint32_t inode = 2;
@@ -52,12 +52,12 @@ int cpio_hdr(struct backend *be, uint32_t mode, size_t datalen,
return rv;
}
-int cpio_mkdir(struct backend *be, const char *filename)
+int cpio_mkdir(struct upload_backend *be, const char *filename)
{
return cpio_hdr(be, MODE_DIR, 0, filename);
}
-int cpio_writefile(struct backend *be, const char *filename,
+int cpio_writefile(struct upload_backend *be, const char *filename,
const void *data, size_t len)
{
int rv;
@@ -69,7 +69,7 @@ int cpio_writefile(struct backend *be, const char *filename,
return rv;
}
-int cpio_close(struct backend *be)
+int cpio_close(struct upload_backend *be)
{
return cpio_hdr(be, 0, 0, "TRAILER!!!");
}
diff --git a/com32/sysdump/ctime.c b/com32/libupload/ctime.c
index 56c8efb6..56c8efb6 100644
--- a/com32/sysdump/ctime.c
+++ b/com32/libupload/ctime.c
diff --git a/com32/sysdump/ctime.h b/com32/libupload/ctime.h
index e6461253..e6461253 100644
--- a/com32/sysdump/ctime.h
+++ b/com32/libupload/ctime.h
diff --git a/com32/sysdump/serial.c b/com32/libupload/serial.c
index a3987531..a3987531 100644
--- a/com32/sysdump/serial.c
+++ b/com32/libupload/serial.c
diff --git a/com32/sysdump/serial.h b/com32/libupload/serial.h
index 356f2cef..356f2cef 100644
--- a/com32/sysdump/serial.h
+++ b/com32/libupload/serial.h
diff --git a/com32/sysdump/srecsend.h b/com32/libupload/srecsend.h
index 667be20d..667be20d 100644
--- a/com32/sysdump/srecsend.h
+++ b/com32/libupload/srecsend.h
diff --git a/com32/libupload/tftp.h b/com32/libupload/tftp.h
new file mode 100644
index 00000000..323dc16a
--- /dev/null
+++ b/com32/libupload/tftp.h
@@ -0,0 +1,22 @@
+#include <stdint.h>
+
+#ifndef UPLOAD_TFTP
+#define UPLOAD_TFTP
+/* TFTP Error codes */
+enum tftp_error_codes {
+TFTP_ERR_UNKNOWN_ERROR = 0, // We have to use the message from the server
+TFTP_ERR_FILE_NOT_FOUND = 1, /**< File not found */
+TFTP_ERR_ACCESS_DENIED = 2, /**< Access violation */
+TFTP_ERR_DISK_FULL = 3, /**< Disk full or allocation exceeded */
+TFTP_ERR_ILLEGAL_OP = 4, /**< Illegal TFTP operation */
+TFTP_ERR_UNKNOWN_TID = 5, /**< Unknown transfer ID */
+TFTP_ERR_FILE_EXISTS = 6, /**< File already exists */
+TFTP_ERR_UNKNOWN_USER = 7, /**< No such user */
+TFTP_ERR_BAD_OPTS = 8, /**< Option negotiation failed */
+TFTP_ERR_UNABLE_TO_RESOLVE = 9, // Not in RFC, internal usage
+TFTP_ERR_UNABLE_TO_CONNECT = 10, // Not in RFC, internal usage
+TFTP_OK = 11, /* Not in RFC */
+};
+
+extern const char *tftp_string_error_message[];
+#endif
diff --git a/com32/libupload/upload_backend.h b/com32/libupload/upload_backend.h
new file mode 100644
index 00000000..7ea03e46
--- /dev/null
+++ b/com32/libupload/upload_backend.h
@@ -0,0 +1,56 @@
+#ifndef BACKEND_H
+#define BACKEND_H
+
+#include <stddef.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <zlib.h>
+#include "serial.h"
+#include "tftp.h"
+
+/* Backend flags */
+#define BE_NEEDLEN 0x01
+
+struct upload_backend {
+ const char *name;
+ const char *helpmsg;
+ int minargs;
+
+ size_t dbytes;
+ size_t zbytes;
+ const char **argv;
+
+ uint32_t now;
+
+ int (*write)(struct upload_backend *);
+
+ z_stream zstream;
+ char *outbuf;
+ size_t alloc;
+};
+
+/* zout.c */
+int init_data(struct upload_backend *be, const char *argv[]);
+int write_data(struct upload_backend *be, const void *buf, size_t len);
+int flush_data(struct upload_backend *be);
+
+/* cpio.c */
+#define cpio_init init_data
+int cpio_hdr(struct upload_backend *be, uint32_t mode, size_t datalen,
+ const char *filename);
+int cpio_mkdir(struct upload_backend *be, const char *filename);
+int cpio_writefile(struct upload_backend *be, const char *filename,
+ const void *data, size_t len);
+int cpio_close(struct upload_backend *be);
+#define MODE_FILE 0100644
+#define MODE_DIR 0040755
+
+/* backends.c */
+struct upload_backend *get_upload_backend(const char *name);
+
+/* backends */
+extern struct upload_backend upload_tftp;
+extern struct upload_backend upload_ymodem;
+extern struct upload_backend upload_srec;
+
+#endif /* BACKEND_H */
diff --git a/com32/sysdump/be_srec.c b/com32/libupload/upload_srec.c
index fc69c886..c1907131 100644
--- a/com32/sysdump/be_srec.c
+++ b/com32/libupload/upload_srec.c
@@ -6,7 +6,7 @@
#include <stdio.h>
#include <inttypes.h>
#include <minmax.h>
-#include "backend.h"
+#include "upload_backend.h"
/* Write a single S-record */
static int write_srecord(unsigned int len, unsigned int alen,
@@ -43,7 +43,7 @@ static int write_srecord(unsigned int len, unsigned int alen,
return 0;
}
-static int be_srec_write(struct backend *be)
+static int upload_srec_write(struct upload_backend *be)
{
char name[33];
const char *buf;
@@ -77,9 +77,9 @@ static int be_srec_write(struct backend *be)
return 0;
}
-struct backend be_srec = {
+struct upload_backend upload_srec = {
.name = "srec",
.helpmsg = "[filename]",
.minargs = 0,
- .write = be_srec_write,
+ .write = upload_srec_write,
};
diff --git a/com32/sysdump/be_tftp.c b/com32/libupload/upload_tftp.c
index 36a91eb8..5e73c1c5 100644
--- a/com32/sysdump/be_tftp.c
+++ b/com32/libupload/upload_tftp.c
@@ -8,8 +8,7 @@
#include <syslinux/config.h>
#include <netinet/in.h>
#include <sys/times.h>
-
-#include "backend.h"
+#include "upload_backend.h"
enum tftp_opcode {
TFTP_RRQ = 1,
@@ -19,6 +18,12 @@ enum tftp_opcode {
TFTP_ERROR = 5,
};
+struct tftp_error {
+ uint16_t opcode;
+ uint16_t errcode;
+ char errmsg[0];
+} __attribute__ (( packed ));
+
struct tftp_state {
uint32_t my_ip;
uint32_t srv_ip;
@@ -28,6 +33,21 @@ struct tftp_state {
uint16_t seq;
};
+const char *tftp_string_error_message[]={
+"",
+"File not found",
+"Access Denied",
+"Disk Full",
+"Illegal Operation",
+"Unknown Transfert ID",
+"File already exists",
+"Unknown User",
+"Negociation failed",
+"Unable to resolve hostname", // not in RFC
+"Unable to connect", // not in RFC
+"No Error",
+};
+
#define RCV_BUF 2048
static int send_ack_packet(struct tftp_state *tftp,
@@ -51,7 +71,7 @@ static int send_ack_packet(struct tftp_state *tftp,
ireg.eax.w[0] = 0x0009;
for (timeout = timeouts ; *timeout ; timeout++) {
- memset(uw, 0, sizeof uw);
+ memset(uw, 0, sizeof *uw);
memcpy(uw+1, pkt, len);
uw->ip = tftp->srv_ip;
uw->gw = tftp->srv_gw;
@@ -69,7 +89,7 @@ static int send_ack_packet(struct tftp_state *tftp,
start = times(NULL);
do {
- memset(ur, 0, sizeof ur);
+ memset(ur, 0, sizeof *ur);
ur->src_ip = tftp->srv_ip;
ur->dest_ip = tftp->my_ip;
ur->s_port = tftp->srv_port;
@@ -91,9 +111,14 @@ static int send_ack_packet(struct tftp_state *tftp,
if (ntohs(xb[0]) == TFTP_ACK &&
ntohs(xb[1]) == tftp->seq) {
tftp->srv_port = ur->s_port;
- err = 0; /* All good! */
+ err = TFTP_OK; /* All good! */
goto done;
- } else if (ntohs(xb[1]) == TFTP_ERROR) {
+ } else if (ntohs(xb[0]) == TFTP_ERROR) {
+ struct tftp_error *te = (struct tftp_error *)(ur+1);
+ if (te->errcode == TFTP_ERR_UNKNOWN_ERROR) {
+ tftp_string_error_message[TFTP_ERR_UNKNOWN_ERROR]=strdup(te->errmsg);
+ }
+ err=-ntohs(te->errcode); // Return the associated error code
goto done;
}
}
@@ -107,12 +132,13 @@ done:
return err;
}
-static int be_tftp_write(struct backend *be)
+static int upload_tftp_write(struct upload_backend *be)
{
static uint16_t local_port = 0x4000;
struct tftp_state tftp;
char buffer[512+4+6];
int nlen;
+ int err=TFTP_OK;
const union syslinux_derivative_info *sdi =
syslinux_derivative_info();
const char *data = be->outbuf;
@@ -129,30 +155,30 @@ static int be_tftp_write(struct backend *be)
if (be->argv[1]) {
tftp.srv_ip = pxe_dns(be->argv[1]);
if (!tftp.srv_ip) {
- printf("\nUnable to resolve hostname: %s\n", be->argv[1]);
- return -1;
+// printf("\nUnable to resolve hostname: %s\n", be->argv[1]);
+ return -TFTP_ERR_UNABLE_TO_RESOLVE;
}
} else {
tftp.srv_ip = sdi->pxe.ipinfo->serverip;
if (!tftp.srv_ip) {
- printf("\nNo server IP address\n");
- return -1;
+// printf("\nNo server IP address\n");
+ return -TFTP_ERR_UNABLE_TO_CONNECT;
}
}
- printf("server %u.%u.%u.%u... ",
+/* printf("server %u.%u.%u.%u... ",
((uint8_t *)&tftp.srv_ip)[0],
((uint8_t *)&tftp.srv_ip)[1],
((uint8_t *)&tftp.srv_ip)[2],
- ((uint8_t *)&tftp.srv_ip)[3]);
+ ((uint8_t *)&tftp.srv_ip)[3]);*/
buffer[0] = 0;
buffer[1] = TFTP_WRQ;
nlen = strlcpy(buffer+2, be->argv[0], 512);
memcpy(buffer+3+nlen, "octet", 6);
- if (send_ack_packet(&tftp, buffer, 2+nlen+1+6))
- return -1;
+ if ((err=send_ack_packet(&tftp, buffer, 2+nlen+1+6))!=TFTP_OK)
+ return err;
do {
chunk = len >= 512 ? 512 : len;
@@ -163,16 +189,16 @@ static int be_tftp_write(struct backend *be)
data += chunk;
len -= chunk;
- if (send_ack_packet(&tftp, buffer, chunk+4))
- return -1;
+ if ((err=send_ack_packet(&tftp, buffer, chunk+4))!=TFTP_OK)
+ return err;
} while (chunk == 512);
- return 0;
+ return TFTP_OK;
}
-struct backend be_tftp = {
+struct upload_backend upload_tftp = {
.name = "tftp",
.helpmsg = "filename [tftp_server]",
.minargs = 1,
- .write = be_tftp_write,
+ .write = upload_tftp_write,
};
diff --git a/com32/sysdump/be_ymodem.c b/com32/libupload/upload_ymodem.c
index 316b3d4e..c42327d8 100644
--- a/com32/sysdump/be_ymodem.c
+++ b/com32/libupload/upload_ymodem.c
@@ -5,7 +5,7 @@
#include <string.h>
#include <stdio.h>
#include <inttypes.h>
-#include "backend.h"
+#include "upload_backend.h"
#include "serial.h"
enum {
@@ -98,7 +98,7 @@ static void send_ack(struct ymodem_state *ym, const uint8_t *blk, size_t bytes)
} while (ack_buf == NAK);
}
-static int be_ymodem_write(struct backend *be)
+static int upload_ymodem_write(struct upload_backend *be)
{
static const uint8_t eot_buf = EOT;
uint8_t ack_buf;
@@ -167,9 +167,9 @@ static int be_ymodem_write(struct backend *be)
return 0;
}
-struct backend be_ymodem = {
+struct upload_backend upload_ymodem = {
.name = "ymodem",
.helpmsg = "filename [port [speed]]",
.minargs = 1,
- .write = be_ymodem_write,
+ .write = upload_ymodem_write,
};
diff --git a/com32/sysdump/ymodem.txt b/com32/libupload/ymodem.txt
index 2264ff78..2264ff78 100644
--- a/com32/sysdump/ymodem.txt
+++ b/com32/libupload/ymodem.txt
diff --git a/com32/sysdump/zout.c b/com32/libupload/zout.c
index ece934cc..47c0d308 100644
--- a/com32/sysdump/zout.c
+++ b/com32/libupload/zout.c
@@ -8,12 +8,12 @@
#include <inttypes.h>
#include <stdbool.h>
#include <zlib.h>
-#include "backend.h"
+#include "upload_backend.h"
#include "ctime.h"
#define ALLOC_CHUNK 65536
-int init_data(struct backend *be, const char *argv[])
+int init_data(struct upload_backend *be, const char *argv[])
{
be->now = posix_time();
be->argv = argv;
@@ -33,7 +33,7 @@ int init_data(struct backend *be, const char *argv[])
return 0;
}
-static int do_deflate(struct backend *be, int flush)
+static int do_deflate(struct upload_backend *be, int flush)
{
int rv;
char *buf;
@@ -55,7 +55,7 @@ static int do_deflate(struct backend *be, int flush)
}
-int write_data(struct backend *be, const void *buf, size_t len)
+int write_data(struct upload_backend *be, const void *buf, size_t len)
{
int rv = Z_OK;
@@ -75,9 +75,10 @@ int write_data(struct backend *be, const void *buf, size_t len)
}
/* Output the data and shut down the stream */
-int flush_data(struct backend *be)
+int flush_data(struct upload_backend *be)
{
int rv = Z_OK;
+ int err=-1;
while (rv != Z_STREAM_END) {
rv = do_deflate(be, Z_FINISH);
@@ -85,15 +86,15 @@ int flush_data(struct backend *be)
return -1;
}
- printf("Uploading data, %u bytes... ", be->zbytes);
+// printf("Uploading data, %u bytes... ", be->zbytes);
- if (be->write(be))
- return -1;
+ if ((err=be->write(be)) != 0)
+ return err;
free(be->outbuf);
be->outbuf = NULL;
be->dbytes = be->zbytes = be->alloc = 0;
- printf("done.\n");
+// printf("done.\n");
return 0;
}
diff --git a/com32/libutil/Makefile b/com32/libutil/Makefile
index 02789ca6..83e23a0a 100644
--- a/com32/libutil/Makefile
+++ b/com32/libutil/Makefile
@@ -30,9 +30,11 @@
##
topdir = ../..
-include ../MCONFIG
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/com32.mk
-LIBOBJS = ansiline.o ansiraw.o get_key.o sha1hash.o unbase64.o \
+LIBOBJS = ansiline.o ansiraw.o get_key.o keyname.o \
+ sha1hash.o unbase64.o \
md5.o crypt-md5.o sha256crypt.o sha512crypt.o base64.o
LNXLIBOBJS = $(patsubst %.o,%.lo,$(LIBOBJS))
diff --git a/com32/libutil/include/getkey.h b/com32/libutil/include/getkey.h
index 52312a25..a46de812 100644
--- a/com32/libutil/include/getkey.h
+++ b/com32/libutil/include/getkey.h
@@ -75,6 +75,10 @@
#define KEY_INSERT 0x0128
#define KEY_DELETE 0x0129
+#define KEY_MAX 0x012a
+
int get_key(FILE *, clock_t);
+int key_name_to_code(const char *);
+const char *key_code_to_name(int);
#endif /* LIBUTIL_GETKEY_H */
diff --git a/com32/libutil/keyname.c b/com32/libutil/keyname.c
new file mode 100644
index 00000000..3b9e6581
--- /dev/null
+++ b/com32/libutil/keyname.c
@@ -0,0 +1,138 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2011 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * keyname.c
+ *
+ * Conversion between strings and get_key() key numbers.
+ */
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/times.h>
+#include <getkey.h>
+#include <libutil.h>
+
+struct keyname {
+ const char *string;
+ int key;
+};
+
+static const struct keyname key_names[] = {
+ { "Backspace", KEY_BACKSPACE },
+ { "Tab", KEY_TAB },
+ { "Enter", KEY_ENTER },
+ { "Esc", KEY_ESC },
+ { "Escape", KEY_ESC },
+ { "Space", ' ' },
+ { "^?", KEY_DEL },
+ { "F1", KEY_F1 },
+ { "F2", KEY_F2},
+ { "F3", KEY_F3 },
+ { "F4", KEY_F4 },
+ { "F5", KEY_F5 },
+ { "F6", KEY_F6 },
+ { "F7", KEY_F7 },
+ { "F8", KEY_F8 },
+ { "F9", KEY_F9 },
+ { "F10", KEY_F10 },
+ { "F11", KEY_F11 },
+ { "F12", KEY_F12 },
+ { "Up", KEY_UP },
+ { "Down", KEY_DOWN },
+ { "Left", KEY_LEFT },
+ { "Right", KEY_RIGHT },
+ { "PgUp", KEY_PGUP },
+ { "PgDn", KEY_PGDN },
+ { "Home", KEY_HOME },
+ { "End", KEY_END },
+ { "Insert", KEY_INSERT },
+ { "Delete", KEY_DELETE },
+ { NULL, KEY_NONE }
+};
+
+int key_name_to_code(const char *code)
+{
+ const struct keyname *name;
+
+ if (code[0] && !code[1]) {
+ /* Single character */
+ return (unsigned char)code[0];
+ } else if (code[0] == '^' && code[1] && !code[2]) {
+ /* Control character */
+ if (code[1] == '?')
+ return 0x7f;
+ else
+ return (unsigned char)code[1] & 0x9f;
+ }
+
+
+ for (name = key_names; name->string; name++) {
+ if (!strcasecmp(name->string, code))
+ break;
+ }
+ return name->key; /* KEY_NONE at end of array */
+}
+
+const char *key_code_to_name(int key)
+{
+ static char buf[4];
+ const struct keyname *name;
+
+ if (key < 0)
+ return NULL;
+
+ if (key > ' ' && key < 0x100) {
+ if (key & 0x60) {
+ buf[0] = key;
+ buf[1] = '\0';
+ } else {
+ buf[0] = '^';
+ buf[1] = key | 0x40;
+ buf[2] = '\0';
+ }
+ return buf;
+ }
+
+ for (name = key_names; name->string; name++) {
+ if (key == name->key)
+ return name->string;
+ }
+
+ if (key < ' ') {
+ buf[0] = '^';
+ buf[1] = key | 0x40;
+ buf[2] = '\0';
+ return buf;
+ }
+
+ return NULL;
+}
diff --git a/com32/lua/src/Makefile b/com32/lua/src/Makefile
index 4081bfe1..14b0e33d 100644
--- a/com32/lua/src/Makefile
+++ b/com32/lua/src/Makefile
@@ -16,9 +16,9 @@
##
topdir = ../../..
-include ../../MCONFIG
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/com32.mk
-LIBS = ../../lib/libcom32.a $(LIBGCC)
LNXLIBS =
# Temporarily allow warnings not being treated as errors
@@ -54,7 +54,7 @@ $(LIBLUA) : $(LIBLUA_OBJS)
$(AR) cq $@ $^
$(RANLIB) $@
-lua.elf : $(OBJS) $(LIBLUA) $(LIBS) $(C_LIBS)
+lua.elf : $(OBJS) $(LIBLUA) $(C_LIBS)
$(LD) $(LDFLAGS) -o $@ $^
tidy dist:
diff --git a/com32/mboot/Makefile b/com32/mboot/Makefile
index 7e6c2e96..b7ee1154 100644
--- a/com32/mboot/Makefile
+++ b/com32/mboot/Makefile
@@ -16,9 +16,9 @@
##
topdir = ../..
-include ../MCONFIG
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/com32.mk
-LIBS = ../libutil/libutil_com.a ../lib/libcom32.a $(LIBGCC)
LNXLIBS = ../libutil/libutil_lnx.a
MODULES = mboot.c32
@@ -28,7 +28,7 @@ OBJS = mboot.o map.o mem.o initvesa.o apm.o solaris.o syslinux.o
all: $(MODULES) $(TESTFILES)
-mboot.elf : $(OBJS) $(LIBS) $(C_LIBS)
+mboot.elf : $(OBJS) $(C_LIBS)
$(LD) $(LDFLAGS) -o $@ $^
tidy dist:
diff --git a/com32/menu/Makefile b/com32/menu/Makefile
index 2a032728..b67b997d 100644
--- a/com32/menu/Makefile
+++ b/com32/menu/Makefile
@@ -15,9 +15,9 @@
##
topdir = ../..
-include ../MCONFIG
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/com32.mk
-LIBS = ../libutil/libutil_com.a ../lib/libcom32.a $(LIBGCC)
LNXLIBS = ../libutil/libutil_lnx.a
MODULES = menu.c32 vesamenu.c32
@@ -28,10 +28,10 @@ COMMONOBJS = menumain.o readconfig.o passwd.o drain.o printmsg.o colors.o \
all: $(MODULES) $(TESTFILES)
-menu.elf : menu.o $(COMMONOBJS) $(LIBS) $(C_LIBS)
+menu.elf : menu.o $(COMMONOBJS) $(C_LIBS)
$(LD) $(LDFLAGS) -o $@ $^
-vesamenu.elf : vesamenu.o $(COMMONOBJS) $(LIBS) $(C_LIBS)
+vesamenu.elf : vesamenu.o $(COMMONOBJS) $(C_LIBS)
$(LD) $(LDFLAGS) -o $@ $^
tidy dist:
diff --git a/com32/menu/menu.h b/com32/menu/menu.h
index 36c5669c..1db4d7c9 100644
--- a/com32/menu/menu.h
+++ b/com32/menu/menu.h
@@ -26,6 +26,7 @@
#include <unistd.h>
#include <colortbl.h>
#include <stdbool.h>
+#include <getkey.h>
#include "refstr.h"
/* #define DEBUG 1 */
@@ -186,6 +187,7 @@ extern int shiftkey;
extern int hiddenmenu;
extern int clearmenu;
extern long long totaltimeout;
+extern const char *hide_key[KEY_MAX];
void parse_configs(char **argv);
int draw_background(const char *filename);
diff --git a/com32/menu/menumain.c b/com32/menu/menumain.c
index 06725f37..5b3f6bd1 100644
--- a/com32/menu/menumain.c
+++ b/com32/menu/menumain.c
@@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
- * Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ * Copyright 2009-2011 Intel Corporation; author: H. Peter Anvin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -726,8 +726,11 @@ static const char *do_hidden_menu(void)
this_timeout = min(timeout_left, CLK_TCK);
key = mygetkey(this_timeout);
- if (key != KEY_NONE)
- return NULL; /* Key pressed */
+ if (key != KEY_NONE) {
+ /* Clear the message from the screen */
+ print_timeout_message(0, HIDDEN_ROW, "");
+ return hide_key[key]; /* NULL if no MENU HIDEKEY in effect */
+ }
timeout_left -= this_timeout;
}
diff --git a/com32/menu/readconfig.c b/com32/menu/readconfig.c
index f3b0f96d..0ac2564a 100644
--- a/com32/menu/readconfig.c
+++ b/com32/menu/readconfig.c
@@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2004-2009 H. Peter Anvin - All Rights Reserved
- * Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ * Copyright 2009-2011 Intel Corporation; author: H. Peter Anvin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -37,6 +37,7 @@ int shiftkey = 0; /* Only display menu if shift key pressed */
int hiddenmenu = 0;
int clearmenu = 0;
long long totaltimeout = 0;
+const char *hide_key[KEY_MAX];
/* Keep track of global default */
static int has_ui = 0; /* DEFAULT only counts if UI is found */
@@ -141,6 +142,22 @@ static char *looking_at(char *line, const char *kwd)
return my_isspace(*p) ? p : NULL; /* Must be EOL or whitespace */
}
+/* Get a single word into a new refstr; advances the input pointer */
+static char *get_word(char *str, char **word)
+{
+ char *p = str;
+ char *q;
+
+ while (*p && !my_isspace(*p))
+ p++;
+
+ *word = q = refstr_alloc(p - str);
+ memcpy(q, str, p - str);
+ /* refstr_alloc() already inserted a terminating NUL */
+
+ return p;
+}
+
static struct menu *new_menu(struct menu *parent,
struct menu_entry *parent_entry, const char *label)
{
@@ -703,6 +720,28 @@ static void parse_config_file(FILE * f)
m->menu_background = refdup_word(&p);
} else if ((ep = looking_at(p, "hidden"))) {
hiddenmenu = 1;
+ } else if (looking_at(p, "hiddenkey")) {
+ char *key_name, *k, *ek;
+ const char *command;
+ int key;
+ p = get_word(skipspace(p + 9), &key_name);
+ command = refstrdup(skipspace(p));
+ k = key_name;
+ for (;;) {
+ ek = strchr(k+1, ',');
+ if (ek)
+ *ek = '\0';
+ key = key_name_to_code(k);
+ if (key >= 0) {
+ refstr_put(hide_key[key]);
+ hide_key[key] = refstr_get(command);
+ }
+ if (!ek)
+ break;
+ k = ek+1;
+ }
+ refstr_put(key_name);
+ refstr_put(command);
} else if ((ep = looking_at(p, "clear"))) {
clearmenu = 1;
} else if ((ep = is_message_name(p, &msgnr))) {
@@ -1036,6 +1075,7 @@ void parse_configs(char **argv)
const char *filename;
struct menu *m;
struct menu_entry *me;
+ int k;
empty_string = refstrdup("");
@@ -1097,4 +1137,10 @@ void parse_configs(char **argv)
if (m->onerror)
m->onerror = unlabel(m->onerror);
}
+
+ /* Final global initialization, with all labels known */
+ for (k = 0; k < KEY_MAX; k++) {
+ if (hide_key[k])
+ hide_key[k] = unlabel(hide_key[k]);
+ }
}
diff --git a/com32/modules/Makefile b/com32/modules/Makefile
index 69bd01bd..e9ce1d1f 100644
--- a/com32/modules/Makefile
+++ b/com32/modules/Makefile
@@ -16,13 +16,14 @@
##
topdir = ../..
-include ../MCONFIG
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/com32.mk
MODULES = chain.c32 config.c32 ethersel.c32 dmitest.c32 cpuidtest.c32 \
disk.c32 pcitest.c32 elf.c32 linux.c32 reboot.c32 pmload.c32 \
meminfo.c32 sdi.c32 sanboot.c32 ifcpu64.c32 vesainfo.c32 \
- kbdmap.c32 cmd.c32 vpdtest.c32 host.c32 dir.c32 gpxecmd.c32 \
- ifcpu.c32 cpuid.c32 cat.c32
+ kbdmap.c32 cmd.c32 vpdtest.c32 host.c32 ls.c32 gpxecmd.c32 \
+ ifcpu.c32 cpuid.c32 cat.c32 pwd.c32 ifplop.c32 zzjson.c32 whichsys.c32
TESTFILES =
diff --git a/com32/modules/zzjson.c b/com32/modules/zzjson.c
new file mode 100644
index 00000000..e2516fa1
--- /dev/null
+++ b/com32/modules/zzjson.c
@@ -0,0 +1,101 @@
+/*
+ * Display directory contents
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <console.h>
+#include <string.h>
+#include <com32.h>
+#include <zzjson/zzjson.h>
+#include <stdarg.h>
+
+static void myerror(void *ehandle, const char *format, ...) {
+ va_list ap;
+ fprintf(ehandle, "error: ");
+ va_start(ap, format);
+ vfprintf(ehandle, format, ap);
+ va_end(ap);
+ fputc('\n', ehandle);
+}
+
+
+int main(int argc, char *argv[])
+{
+ openconsole(&dev_rawcon_r, &dev_stdcon_w);
+ (void) argc;
+ (void) argv;
+ ZZJSON *tmp;
+ ZZJSON_CONFIG config = { ZZJSON_VERY_STRICT, NULL,
+ (int(*)(void*)) fgetc,
+ NULL,
+ malloc, calloc, free, realloc,
+ stderr, myerror, stdout,
+ (int(*)(void*,const char*,...)) fprintf,
+ (int(*)(int,void*)) fputc };
+
+ do {
+ ZZJSON *tmp2;
+
+ tmp = zzjson_create_array(&config,
+ zzjson_create_number_d(&config, 3.14),
+ zzjson_create_number_i(&config, 1234LL),
+ zzjson_create_number_i(&config, -4321LL),
+ zzjson_create_true(&config),
+ zzjson_create_false(&config),
+ zzjson_create_null(&config),
+ zzjson_create_string(&config, "hello, world"),
+ zzjson_create_object(&config,
+ "picard", zzjson_create_string(&config, "jean-luc"),
+ "riker", zzjson_create_string(&config, "william t."),
+ NULL),
+ zzjson_create_object(&config, NULL),
+ zzjson_create_array(&config, NULL),
+ NULL );
+
+ if (!tmp) {
+ fprintf(stderr, "error during creation of json tree\n");
+ break;
+ }
+
+ tmp2 = zzjson_array_prepend(&config, tmp,
+ zzjson_create_string(&config, "prepended string"));
+
+ if (!tmp2) {
+ fprintf(stderr, "error during prepend\n");
+ break;
+ }
+ tmp = tmp2;
+
+ tmp2 = zzjson_array_append(&config, tmp,
+ zzjson_create_string(&config, "appended string (slow)"));
+
+ if (!tmp2) {
+ fprintf(stderr, "error during append\n");
+ break;
+ }
+ tmp = tmp2;
+
+ zzjson_print(&config, tmp);
+ } while(0);
+ if (tmp) zzjson_free(&config, tmp);
+
+ {
+ tmp = zzjson_create_array(&config, NULL); /* empty array */
+ tmp = zzjson_array_prepend(&config, tmp, zzjson_create_true(&config));
+ zzjson_print(&config, tmp);
+ zzjson_free(&config, tmp);
+ }
+
+ {
+ tmp = zzjson_create_object(&config, NULL); /* empty object */
+ tmp = zzjson_object_prepend(&config, tmp, "hello",
+ zzjson_create_string(&config, "world"));
+ tmp = zzjson_object_append(&config, tmp, "goodbye",
+ zzjson_create_string(&config, "cruel world"));
+ zzjson_print(&config, tmp);
+ zzjson_free(&config, tmp);
+ }
+
+ return 0;
+}
+
diff --git a/com32/rosh/Makefile b/com32/rosh/Makefile
index f4b7d866..766f68d5 100644
--- a/com32/rosh/Makefile
+++ b/com32/rosh/Makefile
@@ -17,7 +17,8 @@
##
topdir = ../..
-include MCONFIG
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/rosh.mk
# from com32/sysdump/Makefile
# The DATE is set on the make command line when building binaries for
diff --git a/com32/samples/Makefile b/com32/samples/Makefile
index bee2b992..76986d59 100644
--- a/com32/samples/Makefile
+++ b/com32/samples/Makefile
@@ -15,7 +15,8 @@
##
topdir = ../..
-include ../MCONFIG
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/com32.mk
all: hello.c32 resolv.c32 serialinfo.c32 \
localboot.c32 \
diff --git a/com32/samples/keytest.c b/com32/samples/keytest.c
index b4f8f5b0..09c041a1 100644
--- a/com32/samples/keytest.c
+++ b/com32/samples/keytest.c
@@ -37,13 +37,13 @@ static void cooked_keys(void)
if (key == 0x03) {
printf("[done]\n");
exit(0);
- } else if (key == '?')
+ } else if (key == '!')
return;
if (key >= 0x20 && key < 0x100) {
putchar(key);
} else {
- printf("[%04x]", key);
+ printf("[%s,%04x]", key_code_to_name(key), key);
}
}
}
@@ -63,7 +63,8 @@ static void raw_keys(void)
} else if (key == '!')
return;
- printf("<%02x>", key);
+ if (key != EOF)
+ printf("<%02x>", key);
}
}
@@ -72,7 +73,7 @@ int main(void)
console_ansi_raw();
printf("CLK_TCK = %d\n", (int)CLK_TCK);
- printf("Press keys, end with Ctrl-C...\n");
+ printf("Press keys, end with Ctrl-C, ! changes from cooked to raw\n");
for (;;) {
cooked_keys();
diff --git a/com32/sysdump/Makefile b/com32/sysdump/Makefile
index bffee3a2..98e7f15a 100644
--- a/com32/sysdump/Makefile
+++ b/com32/sysdump/Makefile
@@ -16,12 +16,15 @@
##
topdir = ../..
-include ../MCONFIG
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/com32.mk
-include $(topdir)/version.mk
-LIBS = ../libutil/libutil_com.a ../lib/libcom32.a $(LIBGCC)
+LIBS = ../libupload/libcom32upload.a
LNXLIBS = ../libutil/libutil_lnx.a
+CFLAGS += -I$(com32) -I$(topdir)
+
MODULES = sysdump.c32
TESTFILES =
diff --git a/com32/sysdump/acpi.c b/com32/sysdump/acpi.c
index 8671fc8a..50222335 100644
--- a/com32/sysdump/acpi.c
+++ b/com32/sysdump/acpi.c
@@ -18,7 +18,6 @@
#include <string.h>
#include <stdlib.h>
#include "sysdump.h"
-#include "backend.h"
#include "rbtree.h"
struct acpi_rsdp {
@@ -151,7 +150,7 @@ static const struct acpi_rsdp *find_rsdp(void)
return scan_for_rsdp(0xe0000, 0x100000);
}
-static void dump_table(struct backend *be,
+static void dump_table(struct upload_backend *be,
const char name[], const void *ptr, uint32_t len)
{
char namebuf[64];
@@ -171,7 +170,7 @@ static void dump_table(struct backend *be,
write_data(be, ptr, len);
}
-static void dump_rsdt(struct backend *be, const struct acpi_rsdp *rsdp)
+static void dump_rsdt(struct upload_backend *be, const struct acpi_rsdp *rsdp)
{
const struct acpi_rsdt *rsdt;
uint32_t i, n;
@@ -196,7 +195,7 @@ static void dump_rsdt(struct backend *be, const struct acpi_rsdp *rsdp)
}
}
-static void dump_xsdt(struct backend *be, const struct acpi_rsdp *rsdp)
+static void dump_xsdt(struct upload_backend *be, const struct acpi_rsdp *rsdp)
{
const struct acpi_xsdt *xsdt;
uint32_t rsdp_len = rsdp->rev > 0 ? rsdp->len : 20;
@@ -231,7 +230,7 @@ static void dump_xsdt(struct backend *be, const struct acpi_rsdp *rsdp)
}
}
-void dump_acpi(struct backend *be)
+void dump_acpi(struct upload_backend *be)
{
const struct acpi_rsdp *rsdp;
uint32_t rsdp_len;
diff --git a/com32/sysdump/backend.h b/com32/sysdump/backend.h
deleted file mode 100644
index f2b3bc25..00000000
--- a/com32/sysdump/backend.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef BACKEND_H
-#define BACKEND_H
-
-#include <stddef.h>
-#include <inttypes.h>
-#include <stdbool.h>
-#include <zlib.h>
-#include "serial.h"
-
-/* Backend flags */
-#define BE_NEEDLEN 0x01
-
-struct backend {
- const char *name;
- const char *helpmsg;
- int minargs;
-
- size_t dbytes;
- size_t zbytes;
- const char **argv;
-
- uint32_t now;
-
- int (*write)(struct backend *);
-
- z_stream zstream;
- char *outbuf;
- size_t alloc;
-};
-
-/* zout.c */
-int init_data(struct backend *be, const char *argv[]);
-int write_data(struct backend *be, const void *buf, size_t len);
-int flush_data(struct backend *be);
-
-/* cpio.c */
-#define cpio_init init_data
-int cpio_hdr(struct backend *be, uint32_t mode, size_t datalen,
- const char *filename);
-int cpio_mkdir(struct backend *be, const char *filename);
-int cpio_writefile(struct backend *be, const char *filename,
- const void *data, size_t len);
-int cpio_close(struct backend *be);
-#define MODE_FILE 0100644
-#define MODE_DIR 0040755
-
-/* backends.c */
-struct backend *get_backend(const char *name);
-
-/* backends */
-extern struct backend be_tftp;
-extern struct backend be_ymodem;
-extern struct backend be_srec;
-
-#endif /* BACKEND_H */
diff --git a/com32/sysdump/cpuid.c b/com32/sysdump/cpuid.c
index 372a70db..e7fc5767 100644
--- a/com32/sysdump/cpuid.c
+++ b/com32/sysdump/cpuid.c
@@ -8,7 +8,6 @@
#include <com32.h>
#include <sys/cpu.h>
#include "sysdump.h"
-#include "backend.h"
struct cpuid_data {
uint32_t eax, ebx, ecx, edx;
@@ -29,7 +28,7 @@ static void get_cpuid(uint32_t eax, uint32_t ecx, struct cpuid_data *data)
#define CPUID_CHUNK 128
-void dump_cpuid(struct backend *be)
+void dump_cpuid(struct upload_backend *be)
{
struct cpuid_info *buf = NULL;
int nentry, nalloc;
diff --git a/com32/sysdump/data.h b/com32/sysdump/data.h
deleted file mode 100644
index deacf721..00000000
--- a/com32/sysdump/data.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#ifndef DATA_H
-#define DATA_H
diff --git a/com32/sysdump/dmi.c b/com32/sysdump/dmi.c
index be4cce46..ce25efa4 100644
--- a/com32/sysdump/dmi.c
+++ b/com32/sysdump/dmi.c
@@ -6,7 +6,6 @@
#include <string.h>
#include <stdlib.h>
#include "sysdump.h"
-#include "backend.h"
struct dmi_header {
char signature[5];
@@ -60,7 +59,7 @@ static bool is_smbios(size_t dptr)
is_old_dmi(dptr+16);
}
-static void dump_smbios(struct backend *be, size_t dptr)
+static void dump_smbios(struct upload_backend *be, size_t dptr)
{
const struct smbios_header *smb = (void *)dptr;
struct smbios_header smx = *smb;
@@ -82,7 +81,7 @@ static void dump_smbios(struct backend *be, size_t dptr)
write_data(be, (const void *)smb->dmi.tbladdr, smb->dmi.tbllen);
}
-static void dump_old_dmi(struct backend *be, size_t dptr)
+static void dump_old_dmi(struct upload_backend *be, size_t dptr)
{
const struct dmi_header *dmi = (void *)dptr;
struct fake {
@@ -108,7 +107,7 @@ static void dump_old_dmi(struct backend *be, size_t dptr)
write_data(be, (const void *)dmi->tbladdr, dmi->tbllen);
}
-void dump_dmi(struct backend *be)
+void dump_dmi(struct upload_backend *be)
{
size_t dptr;
diff --git a/com32/sysdump/main.c b/com32/sysdump/main.c
index d0d40a7b..f672585d 100644
--- a/com32/sysdump/main.c
+++ b/com32/sysdump/main.c
@@ -19,8 +19,7 @@
#include <dprintf.h>
#include <console.h>
#include <sys/cpu.h>
-#include "../../version.h"
-#include "backend.h"
+#include <version.h>
#include "sysdump.h"
const char program[] = "sysdump";
@@ -32,7 +31,7 @@ __noreturn die(const char *msg)
exit(1);
}
-static void dump_all(struct backend *be, const char *argv[])
+static void dump_all(struct upload_backend *be, const char *argv[])
{
cpio_init(be, argv);
@@ -50,20 +49,20 @@ static void dump_all(struct backend *be, const char *argv[])
flush_data(be);
}
-static struct backend *backends[] =
+static struct upload_backend *upload_backends[] =
{
- &be_tftp,
- &be_ymodem,
- &be_srec,
+ &upload_tftp,
+ &upload_ymodem,
+ &upload_srec,
NULL
};
__noreturn usage(void)
{
- struct backend **bep, *be;
+ struct upload_backend **bep, *be;
printf("Usage:\n");
- for (bep = backends ; (be = *bep) ; bep++)
+ for (bep = upload_backends ; (be = *bep) ; bep++)
printf(" %s %s %s\n", program, be->name, be->helpmsg);
exit(1);
@@ -71,7 +70,7 @@ __noreturn usage(void)
int main(int argc, char *argv[])
{
- struct backend **bep, *be;
+ struct upload_backend **bep, *be;
openconsole(&dev_null_r, &dev_stdcon_w);
fputs(version, stdout);
@@ -79,7 +78,7 @@ int main(int argc, char *argv[])
if (argc < 2)
usage();
- for (bep = backends ; (be = *bep) ; bep++) {
+ for (bep = upload_backends ; (be = *bep) ; bep++) {
if (!strcmp(be->name, argv[1]))
break;
}
diff --git a/com32/sysdump/memmap.c b/com32/sysdump/memmap.c
index 251107d5..929873fe 100644
--- a/com32/sysdump/memmap.c
+++ b/com32/sysdump/memmap.c
@@ -7,7 +7,6 @@
#include <stdlib.h>
#include <com32.h>
#include "sysdump.h"
-#include "backend.h"
#define E820_CHUNK 128
struct e820_info {
@@ -16,7 +15,7 @@ struct e820_info {
uint8_t data[24];
};
-static void dump_e820(struct backend *be)
+static void dump_e820(struct upload_backend *be)
{
com32sys_t ireg, oreg;
struct e820_info *curr;
@@ -63,7 +62,7 @@ static void dump_e820(struct backend *be)
lfree(curr);
}
-void dump_memory_map(struct backend *be)
+void dump_memory_map(struct upload_backend *be)
{
com32sys_t ireg, oreg;
diff --git a/com32/sysdump/memory.c b/com32/sysdump/memory.c
index 6552e7f3..377f9a99 100644
--- a/com32/sysdump/memory.c
+++ b/com32/sysdump/memory.c
@@ -7,7 +7,6 @@
#include <stdlib.h>
#include <sys/cpu.h>
#include "sysdump.h"
-#include "backend.h"
static char *lowmem;
static size_t lowmem_len;
@@ -29,7 +28,7 @@ void snapshot_lowmem(void)
}
}
-static void dump_memory_range(struct backend *be, const void *where,
+static void dump_memory_range(struct upload_backend *be, const void *where,
const void *addr, size_t len)
{
char filename[32];
@@ -38,7 +37,7 @@ static void dump_memory_range(struct backend *be, const void *where,
cpio_writefile(be, filename, where, len);
}
-void dump_memory(struct backend *be)
+void dump_memory(struct upload_backend *be)
{
printf("Dumping memory... ");
diff --git a/com32/sysdump/pci.c b/com32/sysdump/pci.c
index 1d687279..9c23a841 100644
--- a/com32/sysdump/pci.c
+++ b/com32/sysdump/pci.c
@@ -7,9 +7,8 @@
#include <stdlib.h>
#include <sys/pci.h>
#include "sysdump.h"
-#include "backend.h"
-static void dump_pci_device(struct backend *be, pciaddr_t a, uint8_t hdrtype)
+static void dump_pci_device(struct upload_backend *be, pciaddr_t a, uint8_t hdrtype)
{
unsigned int bus = pci_bus(a);
unsigned int dev = pci_dev(a);
@@ -31,7 +30,7 @@ static void dump_pci_device(struct backend *be, pciaddr_t a, uint8_t hdrtype)
cpio_writefile(be, filename, data, sizeof data);
}
-void dump_pci(struct backend *be)
+void dump_pci(struct upload_backend *be)
{
int cfgtype;
unsigned int nbus, ndev, nfunc, maxfunc;
diff --git a/com32/sysdump/sysdump.h b/com32/sysdump/sysdump.h
index a5b963f8..72e4875e 100644
--- a/com32/sysdump/sysdump.h
+++ b/com32/sysdump/sysdump.h
@@ -1,15 +1,15 @@
#ifndef SYSDUMP_H
#define SYSDUMP_H
-struct backend;
+#include <libupload/upload_backend.h>
-void dump_memory_map(struct backend *);
+void dump_memory_map(struct upload_backend *);
void snapshot_lowmem(void);
-void dump_memory(struct backend *);
-void dump_dmi(struct backend *);
-void dump_acpi(struct backend *);
-void dump_cpuid(struct backend *);
-void dump_pci(struct backend *);
-void dump_vesa_tables(struct backend *);
+void dump_memory(struct upload_backend *);
+void dump_dmi(struct upload_backend *);
+void dump_acpi(struct upload_backend *);
+void dump_cpuid(struct upload_backend *);
+void dump_pci(struct upload_backend *);
+void dump_vesa_tables(struct upload_backend *);
#endif /* SYSDUMP_H */
diff --git a/com32/sysdump/vesa.c b/com32/sysdump/vesa.c
index 017f9e4f..42adc3da 100644
--- a/com32/sysdump/vesa.c
+++ b/com32/sysdump/vesa.c
@@ -1,10 +1,9 @@
#include <string.h>
#include <stdio.h>
-#include "../lib/sys/vesa/vesa.h"
-#include "backend.h"
+#include <lib/sys/vesa/vesa.h>
#include "sysdump.h"
-void dump_vesa_tables(struct backend *be)
+void dump_vesa_tables(struct upload_backend *be)
{
com32sys_t rm;
struct vesa_info *vip;
diff --git a/com32/tools/Makefile b/com32/tools/Makefile
index e34296b4..7badabd2 100644
--- a/com32/tools/Makefile
+++ b/com32/tools/Makefile
@@ -10,8 +10,8 @@
##
## -----------------------------------------------------------------------
-topdir = ../..
-include $(topdir)/MCONFIG.build
+MAKEDIR = ../../mk
+include $(MAKEDIR)/build.mk
BINS = relocs
diff --git a/core/Makefile b/core/Makefile
index f304f04c..96a7b9ff 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -20,7 +20,8 @@ MAKEFLAGS += -r
MAKE += -r
topdir = ..
-include $(topdir)/MCONFIG.embedded
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/embedded.mk
-include $(topdir)/version.mk
OPTFLAGS =
@@ -110,7 +111,7 @@ ldlinux.bss: ldlinux.bin
dd if=$< of=$@ bs=512 count=1
ldlinux.sys: ldlinux.bin
- dd if=$< of=$@ bs=512 skip=1
+ dd if=$< of=$@ bs=512 skip=2
codepage.cp: ../codepage/$(CODEPAGE).cp
cp -f $< $@
diff --git a/core/diskboot.inc b/core/diskboot.inc
index 68672e4a..141986e8 100644
--- a/core/diskboot.inc
+++ b/core/diskboot.inc
@@ -278,7 +278,7 @@ Sect1Ptr1 equ $-4
cmp dword [ldlinux_magic+4],LDLINUX_MAGIC^HEXDATE
jne kaboom
- ; Go for it! This also normalizes CS:IP.
+ ; Go for it!
jmp ldlinux_ent
;
diff --git a/core/diskfs.inc b/core/diskfs.inc
index 838f35d8..ded89b55 100644
--- a/core/diskfs.inc
+++ b/core/diskfs.inc
@@ -30,8 +30,8 @@ LDLINUX_MAGIC equ 0x3eb202fe ; A random number to identify ourselves with
; This indicates the general format of the last few bytes in the boot sector
BS_MAGIC_VER equ 0x1b << 9
-SECTOR_SHIFT equ 9
-SECTOR_SIZE equ (1 << SECTOR_SHIFT)
+MIN_SECTOR_SHIFT equ 9
+MIN_SECTOR_SIZE equ (1 << MIN_SECTOR_SHIFT)
;
; The following structure is used for "virtual kernels"; i.e. LILO-style
diff --git a/core/diskstart.inc b/core/diskstart.inc
index 28fafbf1..e0a710dd 100644
--- a/core/diskstart.inc
+++ b/core/diskstart.inc
@@ -23,6 +23,14 @@ Sect1Ptr1_VAL equ 0xfeedface
%include "diskboot.inc"
; ===========================================================================
+; Padding after the (minimum) 512-byte boot sector so that the rest of
+; the file has aligned sectors, even if they are larger than 512 bytes.
+; ===========================================================================
+
+ section .init
+align_pad zb 512
+
+; ===========================================================================
; Start of LDLINUX.SYS
; ===========================================================================
@@ -76,6 +84,11 @@ Sect1Ptr1Ptr dw Sect1Ptr1 - bootsec
RAIDPatchPtr dw kaboom.again - bootsec ; Patch to INT 18h in RAID mode
;
+; Pointer to the Syslinux banner
+;
+BannerPtr dw syslinux_banner - LDLINUX_SYS
+
+;
; Base directory name and subvolume, if applicable.
;
%define HAVE_CURRENTDIRNAME
@@ -105,13 +118,15 @@ ldlinux_ent:
; Checksum data thus far
;
mov si,ldlinux_sys
- mov cx,SECTOR_SIZE >> 2
+ mov cx,[bsBytesPerSec]
+ shr cx,2
mov edx,-LDLINUX_MAGIC
.checksum:
lodsd
add edx,eax
loop .checksum
mov [CheckSum],edx ; Save intermediate result
+ movzx ebx,si ; Start of the next sector
;
; Tell the user if we're using EBIOS or CBIOS
@@ -127,6 +142,7 @@ print_bios:
call writestr_early
section .earlybss
+ alignb 2
%define HAVE_BIOSNAME 1
BIOSName resw 1
@@ -135,8 +151,9 @@ BIOSName resw 1
; Now we read the rest of LDLINUX.SYS.
;
load_rest:
+ push bx ; LSW of load address
+
lea esi,[SectorPtrs]
- mov ebx,TEXT_START+2*SECTOR_SIZE ; Where we start loading
mov cx,[DataSectors]
dec cx ; Minus this sector
@@ -152,7 +169,7 @@ load_rest:
xor bx,bx
call getlinsec
pop ebx
- shl ebp,SECTOR_SHIFT
+ imul bp,[bsBytesPerSec] ; Will be < 64K
add ebx,ebp
add si,10
jmp .get_chunk
@@ -165,9 +182,11 @@ load_rest:
; by the time we get to the end it should all cancel out.
;
verify_checksum:
- mov si,ldlinux_sys + SECTOR_SIZE
- mov ecx,[LDLDwords]
- sub ecx,SECTOR_SIZE >> 2
+ pop si ; LSW of load address
+ movzx eax,word [bsBytesPerSec]
+ shr ax,2
+ mov ecx,[LDLDwords] ; Total dwords
+ sub ecx,eax ; ... minus one sector
mov eax,[CheckSum]
.checksum:
add eax,[si]
@@ -255,7 +274,7 @@ getlinsec_ebios:
add eax,edi ; Advance sector pointer
adc edx,0
sub bp,di ; Sectors left
- shl di,SECTOR_SHIFT ; 512-byte sectors
+ imul di,[bsBytesPerSec]
add bx,di ; Advance buffer pointer
and bp,bp
jnz .loop
@@ -345,7 +364,7 @@ getlinsec_cbios:
jc .error
.resume:
movzx ecx,al ; ECX <- sectors transferred
- shl ax,SECTOR_SHIFT ; Convert sectors in AL to bytes in AX
+ imul ax,[bsBytesPerSec] ; Convert sectors in AL to bytes in AX
pop bx
add bx,ax
pop bp
@@ -413,10 +432,10 @@ safedumpregs:
rl_checkpt equ $ ; Must be <= 8000h
-rl_checkpt_off equ ($-$$)
+rl_checkpt_off equ $-ldlinux_sys
%ifndef DEPEND
- %if rl_checkpt_off > 3F6h ; Need one extent
- %assign rl_checkpt_overflow rl_checkpt_off - 3F6h
+ %if rl_checkpt_off > 512-10 ; Need minimum one extent
+ %assign rl_checkpt_overflow rl_checkpt_off - (512-10)
%error Sector 1 overflow by rl_checkpt_overflow bytes
%endif
%endif
@@ -429,8 +448,8 @@ rl_checkpt_off equ ($-$$)
;
alignz 2
MaxInitDataSize equ 96 << 10
-MaxLMA equ TEXT_START+SECTOR_SIZE+MaxInitDataSize
-SectorPtrs zb 10*(MaxInitDataSize >> SECTOR_SHIFT)
+MaxLMA equ LDLINUX_SYS+MaxInitDataSize
+SectorPtrs zb 10*(MaxInitDataSize >> MIN_SECTOR_SHIFT)
SectorPtrsEnd equ $
; ----------------------------------------------------------------------------
@@ -495,7 +514,7 @@ SuperInfo resq 16 ; The first 16 bytes expanded 8 times
; Banner information not needed in sector 1
;
section .data16
-syslinux_banner db CR, LF, MY_NAME, ' ', VERSION_STR, ' '
-late_banner db DATE_STR, ' ', 0
+syslinux_banner db CR, LF, MY_NAME, ' ', VERSION_STR
+late_banner db ' ', DATE_STR, 0
section .text16
diff --git a/core/fs/fat/fat.c b/core/fs/fat/fat.c
index c896b5e6..d3079269 100644
--- a/core/fs/fat/fat.c
+++ b/core/fs/fat/fat.c
@@ -254,8 +254,10 @@ static void vfat_mangle_name(char *dst, const char *src)
while (1) {
if (dst == p)
break;
- if (*(dst-1) == '/' && dst-1 == p) /* it's the '/' case */
- break;
+ if (*(dst-1) == '/' && dst-1 == p) /* it's the '/' case */
+ break;
+ if (dst-2 == p && *(dst-2) == '.' && *(dst-1) == '.' ) /* the '..' case */
+ break;
if ((*(dst-1) != '/') && (*(dst-1) != '.'))
break;
diff --git a/core/fs/iso9660/iso9660.c b/core/fs/iso9660/iso9660.c
index 5c04528e..3cd3ac46 100644
--- a/core/fs/iso9660/iso9660.c
+++ b/core/fs/iso9660/iso9660.c
@@ -27,54 +27,6 @@ static inline struct iso_sb_info *ISO_SB(struct fs_info *fs)
return fs->fs_info;
}
-/*
- * Mangle a filename pointed to by src into a buffer pointed
- * to by dst; ends on encountering any whitespace.
- * dst is preserved.
- *
- * This verifies that a filename is < FilENAME_MAX characters,
- * doesn't contain whitespace, zero-pads the output buffer,
- * and removes trailing dots and redumndant slashes, so "repe
- * cmpsb" can do a compare, and the path-searching routine gets
- * a bit of an easier job.
- *
- */
-static void iso_mangle_name(char *dst, const char *src)
-{
- char *p = dst;
- int i = FILENAME_MAX - 1;
-
- while (not_whitespace(*src)) {
- if ( *src == '/' ) {
- if ( *(src+1) == '/' ) {
- i--;
- src++;
- continue;
- }
- }
-
- *dst++ = *src ++;
- i--;
- }
-
- while ( 1 ) {
- if ( dst == p )
- break;
-
- if ( (*(dst-1) != '.') && (*(dst-1) != '/') )
- break;
- if ((dst[-1] == '/') && ((dst - 1) == p))
- break;
-
- dst --;
- i ++;
- }
-
- i ++;
- for (; i > 0; i -- )
- *dst++ = '\0';
-}
-
static size_t iso_convert_name(char *dst, const char *src, int len)
{
char *p = dst;
@@ -340,7 +292,7 @@ const struct fs_ops iso_fs_ops = {
.searchdir = NULL,
.getfssec = generic_getfssec,
.close_file = generic_close_file,
- .mangle_name = iso_mangle_name,
+ .mangle_name = generic_mangle_name,
.load_config = iso_load_config,
.iget_root = iso_iget_root,
.iget = iso_iget,
diff --git a/core/head.inc b/core/head.inc
index 18ce132c..71eb5744 100644
--- a/core/head.inc
+++ b/core/head.inc
@@ -20,8 +20,8 @@
%ifndef _HEAD_INC
%define _HEAD_INC
-%if __NASM_MAJOR__ < 2
- %error "NASM 2.00 or later required to compile correctly"
+%if __NASM_MAJOR__ < 2 || (__NASM_MAJOR__ == 2 && __NASM_MINOR__ < 3)
+ %error "NASM 2.03 or later required to compile correctly"
%endif
%include "macros.inc"
diff --git a/core/isolinux.asm b/core/isolinux.asm
index 8995ce8b..344cb1ee 100644
--- a/core/isolinux.asm
+++ b/core/isolinux.asm
@@ -52,22 +52,6 @@ vk_append: resb max_cmd_len+1 ; Command line
vk_end: equ $ ; Should be <= vk_size
endstruc
-;
-; File structure. This holds the information for each currently open file.
-;
- struc open_file_t
-file_sector resd 1 ; Sector pointer (0 = structure free)
-file_bytesleft resd 1 ; Number of bytes left
-file_left resd 1 ; Number of sectors left
- resd 1 ; Unused
- endstruc
-
-%ifndef DEPEND
-%if (open_file_t_size & (open_file_t_size-1))
-%error "open_file_t is not a power of 2"
-%endif
-%endif
-
; ---------------------------------------------------------------------------
; BEGIN CODE
; ---------------------------------------------------------------------------
@@ -1190,138 +1174,6 @@ ROOT_FS_OPS:
;
%include "ui.inc"
-;
-; Enable disk emulation. The kind of disk we emulate is dependent on the
-; size of the file: 1200K, 1440K or 2880K floppy, otherwise harddisk.
-;
-is_disk_image:
- TRACER CR
- TRACER LF
- TRACER 'D'
- TRACER ':'
-
- mov edx,eax ; File size
- mov di,img_table
- mov cx,img_table_count
- mov eax,[si+file_sector] ; Starting LBA of file
- mov [dsp_lba],eax ; Location of file
- mov byte [dsp_drive], 0 ; 00h floppy, 80h hard disk
-.search_table:
- TRACER 't'
- mov eax,[di+4]
- cmp edx,[di]
- je .type_found
- add di,8
- loop .search_table
-
- ; Hard disk image. Need to examine the partition table
- ; in order to deduce the C/H/S geometry. Sigh.
-.hard_disk_image:
- TRACER 'h'
- cmp edx,512
- jb .bad_image
-
- mov bx,trackbuf
- mov cx,1 ; Load 1 sector
- pm_call getfssec
-
- cmp word [trackbuf+510],0aa55h ; Boot signature
- jne .bad_image ; Image not bootable
-
- mov cx,4 ; 4 partition entries
- mov di,trackbuf+446 ; Start of partition table
-
- xor ax,ax ; Highest sector(al) head(ah)
-
-.part_scan:
- cmp byte [di+4], 0
- jz .part_loop
- lea si,[di+1]
- call .hs_check
- add si,byte 4
- call .hs_check
-.part_loop:
- add di,byte 16
- loop .part_scan
-
- push eax ; H/S
- push edx ; File size
- mov bl,ah
- xor bh,bh
- inc bx ; # of heads in BX
- xor ah,ah ; # of sectors in AX
- cwde ; EAX[31:16] <- 0
- mul bx
- shl eax,9 ; Convert to bytes
- ; Now eax contains the number of bytes per cylinder
- pop ebx ; File size
- xor edx,edx
- div ebx
- and edx,edx
- jz .no_remainder
- inc eax ; Fractional cylinder...
- ; Now (e)ax contains the number of cylinders
-.no_remainder: cmp eax,1024
- jna .ok_cyl
- mov ax,1024 ; Max possible #
-.ok_cyl: dec ax ; Convert to max cylinder no
- pop ebx ; S(bl) H(bh)
- shl ah,6
- or bl,ah
- xchg ax,bx
- shl eax,16
- mov ah,bl
- mov al,4 ; Hard disk boot
- mov byte [dsp_drive], 80h ; Drive 80h = hard disk
-
-.type_found:
- TRACER 'T'
- mov bl,[sp_media]
- and bl,0F0h ; Copy controller info bits
- or al,bl
- mov [dsp_media],al ; Emulation type
- shr eax,8
- mov [dsp_chs],eax ; C/H/S geometry
- mov ax,[sp_devspec] ; Copy device spec
- mov [dsp_devspec],ax
- mov al,[sp_controller] ; Copy controller index
- mov [dsp_controller],al
-
- TRACER 'V'
- call vgaclearmode ; Reset video
-
- mov ax,4C00h ; Enable emulation and boot
- mov si,dspec_packet
- mov dl,[DriveNumber]
- lss sp,[InitStack]
- TRACER 'X'
-
- call int13
-
- ; If this returns, we have problems
-.bad_image:
- mov si,err_disk_image
- call writestr
- jmp enter_command
-
-;
-; Look for the highest seen H/S geometry
-; We compute cylinders separately
-;
-.hs_check:
- mov bl,[si] ; Head #
- cmp bl,ah
- jna .done_track
- mov ah,bl ; New highest head #
-.done_track: mov bl,[si+1]
- and bl,3Fh ; Sector #
- cmp bl,al
- jna .done_sector
- mov al,bl
-.done_sector: ret
-
-
-
; -----------------------------------------------------------------------------
; Common modules
; -----------------------------------------------------------------------------
@@ -1347,33 +1199,8 @@ err_disk_image db 'Cannot load disk image (invalid file)?', CR, LF, 0
;
alignz 4
exten_table: db '.cbt' ; COMBOOT (specific)
- db '.img' ; Disk image
db '.bin' ; CD boot sector
db '.com' ; COMBOOT (same as DOS)
db '.c32' ; COM32
exten_table_end:
dd 0, 0 ; Need 8 null bytes here
-
-;
-; Floppy image table
-;
- alignz 4
-img_table_count equ 3
-img_table:
- dd 1200*1024 ; 1200K floppy
- db 1 ; Emulation type
- db 80-1 ; Max cylinder
- db 15 ; Max sector
- db 2-1 ; Max head
-
- dd 1440*1024 ; 1440K floppy
- db 2 ; Emulation type
- db 80-1 ; Max cylinder
- db 18 ; Max sector
- db 2-1 ; Max head
-
- dd 2880*1024 ; 2880K floppy
- db 3 ; Emulation type
- db 80-1 ; Max cylinder
- db 36 ; Max sector
- db 2-1 ; Max head
diff --git a/core/ui.inc b/core/ui.inc
index ebded5d7..b4b59b8b 100644
--- a/core/ui.inc
+++ b/core/ui.inc
@@ -688,11 +688,8 @@ is_bad_image:
%else
is_bss_sector equ is_bad_image
%endif
-%if IS_ISOLINUX
- ; ok
-%else
-is_disk_image equ is_bad_image
-%endif
+
+is_disk_image equ is_bad_image ; No longer supported
%endif ; start of replacing ui.inc
diff --git a/diag/geodsp/Makefile b/diag/geodsp/Makefile
index 4c8eff6f..b76eb77d 100644
--- a/diag/geodsp/Makefile
+++ b/diag/geodsp/Makefile
@@ -19,10 +19,10 @@
#
topdir = ../..
-# include $(topdir)/MCONFIG.embedded
+# include $(topdir)/mk/embedded.mk
coredir = $(topdir)/core
-BTARGET = geodsp1s.bin geodspms.bin mk-lba-img \
+BTARGET = geodsp1s.bin geodspms.bin \
geodsp1s.img.xz geodspms.img.xz
# lba-1s.img.xz lba-ms.img.xz
# lba-1s.img lba-ms.img
@@ -36,28 +36,23 @@ all: $(BTARGET)
# .PRECIOUS: lba-%.img
# Higher compression levels result in larger files
-%.img.xz: %.img
- xz -k0f $<
+%.img.xz: %.bin mk-lba-img
+ ./mk-lba-img < $< | xz -0f > $@ || ( rm -f $@ ; false )
%.img.gz: %.img
- gzip -9c $< > $@
-
-%.img: %.bin lba.img
- (cp -a lba.img $@ && dd conv=notrunc if=$< of=$@) || rm -f $@
+ ./mk-lba-img < $< | gzip -9 > $@ || ( rm -f $@ ; false )
%.bin: %.asm $(coredir)/writehex.inc $(coredir)/macros.inc $(coredir)/diskboot.inc
nasm $(NASMOPT) -o $@ -l $(@:.bin=.lst) $<
mk-lba-img: mk-lba-img.c
- gcc -o $@ $<
-
-lba.img: mk-lba-img
- ./$< $@
+ gcc -g -O -o $@ $<
tidy dist:
rm -Rf *.img
clean: tidy
- rm -f $(BTARGET) *.lst *.bin *_bin.c
+ rm -f *.lst *.bin *_bin.c mk-lba-img
spotless: clean
+ rm -f $(BTARGET)
diff --git a/diag/geodsp/mk-lba-img.c b/diag/geodsp/mk-lba-img.c
index 795de1a7..eb1c3393 100644
--- a/diag/geodsp/mk-lba-img.c
+++ b/diag/geodsp/mk-lba-img.c
@@ -24,16 +24,18 @@
#define NUM_SECT (256*63+1)
#define BPS (512)
-#define SECT_INT (512 / sizeof(int))
+#define SECT_INT (BPS / sizeof(unsigned int))
typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
-const char DEF_FN[] = "lba.img";
+const char DEF_FN[] = "-";
int main(int argc, char *argv[])
{
- int i, j, b[SECT_INT], rv = 0, one = 0;
+ int i, rv = 0, one = 0;
+ unsigned int lba, b[SECT_INT];
+ int len;
FILE *f;
uint8_t tt = 0;
const char *fn;
@@ -53,23 +55,40 @@ int main(int argc, char *argv[])
fn = DEF_FN;
}
- f = fopen(fn, "w");
+ if (!strcmp(fn, "-"))
+ f = stdout;
+ else
+ f = fopen(fn, "w");
- if (f) {
- for (i = 0; i < NUM_SECT; i++) {
- if (one) {
- b[0] = i;
- } else {
- for (j = 0; j < (512 / sizeof(int)); j++) {
- b[j] = i;
- }
- }
- fwrite(b, 512, 1, f);
+ if (!f) {
+ fprintf(stderr, "%s: %s: unable to open for writing: %s\n",
+ argv[0], fn, strerror(errno));
+ return 1;
+ }
+
+ lba = 0;
+ while ((len = fread(b, 1, BPS, stdin))) {
+ if (len < BPS)
+ memset((char *)b + len, 0, BPS - len);
+ fwrite(b, 1, BPS, f);
+ lba++;
+ }
+
+ memset(b, 0, sizeof b);
+
+ while (lba < NUM_SECT) {
+ if (one) {
+ b[0] = lba;
+ } else {
+ for (i = 0; i < SECT_INT; i++)
+ b[i] = lba;
}
- fclose(f);
- } else {
- puts("Unable to open for writing");
- rv = 1;
+ fwrite(b, 1, BPS, f);
+ lba++;
}
+
+ if (f != stdout)
+ fclose(f);
+
return rv;
}
diff --git a/diag/mbr/Makefile b/diag/mbr/Makefile
index a94253af..79ff9f01 100644
--- a/diag/mbr/Makefile
+++ b/diag/mbr/Makefile
@@ -17,7 +17,8 @@
topdir = ../..
mbrdir = $(topdir)/mbr
-include $(topdir)/MCONFIG.embedded
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/embedded.mk
all: handoff.bin
diff --git a/doc/isolinux.txt b/doc/isolinux.txt
index eca2a974..807c6311 100644
--- a/doc/isolinux.txt
+++ b/doc/isolinux.txt
@@ -100,34 +100,3 @@ The ISO 9660 filesystem is encapsulated in a partition (which starts
at offset zero, which may confuse some systems.) This makes it
possible for the operating system, once booted, to use the remainder
of the device for persistent storage by creating a second partition.
-
-
- ++++ BOOTING DOS (OR OTHER SIMILAR OPERATING SYSTEMS) ++++
-
-WARNING: This feature depends on BIOS functionality which is
-apparently broken in a very large number of BIOSes. Therefore, this
-may not work on any particular system. No workaround is possible; if
-you find that it doesn't work please complain to your vendor and
-indicate that "BIOS INT 13h AX=4C00h fails."
-
-To boot DOS, or other real-mode operating systems (protected-mode
-operating systems may or may not work correctly), using ISOLINUX, you
-need to prepare a disk image (usually a floppy image, but a hard disk
-image can be used on *most* systems) with the relevant operating
-system. This file should be included on the CD-ROM in the /isolinux
-directory, and have a .img extension. The ".img" extension does not
-have to be specified on the command line, but has to be explicitly
-specified if used in a "kernel" statement in isolinux.cfg.
-
-For a floppy image, the size of the image should be exactly one of the
-following:
-
- 1,228,800 bytes - For a 1200K floppy image
- 1,474,560 bytes - For a 1440K floppy image
- 2,949,120 bytes - For a 2880K floppy image
-
-Any other size is assumed to be a hard disk image. In order to work
-on as many systems as possible, a hard disk image should have exactly
-one partition, marked active, that covers the entire size of the disk
-image file. Even so, hard disk images are not supported on all
-BIOSes.
diff --git a/doc/menu.txt b/doc/menu.txt
index e2dd1e1c..620527e6 100644
--- a/doc/menu.txt
+++ b/doc/menu.txt
@@ -48,6 +48,25 @@ MENU HIDDEN
All that is displayed is a timeout message.
+MENU HIDDENKEY key[,key...] command...
+
+ If they key used to interrupt MENU HIDDEN is <key>, then
+ execute the specified command instead of displaying the menu.
+
+ Currently, the following key names are recognized:
+
+ Backspace, Tab, Enter, Esc, Space, F1..F12, Up, Down, Left,
+ Right, PgUp, PgDn, Home, End, Insert, Delete
+
+ ... in addition to all single characters plus the syntax ^X
+ for Ctrl-X. Note that single characters are treated as case
+ sensitive, so a different command can be bound to "A" than
+ "a". One can bind the same command to multiple keys by giving
+ a comma-separated list of keys:
+
+ menu hiddenkey A,a key_a_command
+
+
MENU CLEAR
Clear the screen when exiting the menu, instead of leaving the
diff --git a/dos/Makefile b/dos/Makefile
index 2667de8c..5e5fc63f 100644
--- a/dos/Makefile
+++ b/dos/Makefile
@@ -15,7 +15,8 @@
##
topdir = ..
-include $(topdir)/MCONFIG.embedded
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/embedded.mk
CFLAGS += -D__MSDOS__
# CFLAGS += -DDEBUG
diff --git a/dosutil/Makefile b/dosutil/Makefile
index fc10ff90..5746e86b 100644
--- a/dosutil/Makefile
+++ b/dosutil/Makefile
@@ -2,7 +2,8 @@
# OpenWatcom compile and link utility
#
topdir = ..
-include $(topdir)/MCONFIG
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/syslinux.mk
WCL = wcl
WCLOPT = -6 -osx -mt -bt=DOS -l=COM
diff --git a/extlinux/Makefile b/extlinux/Makefile
index 83cf1a54..5da19e4a 100644
--- a/extlinux/Makefile
+++ b/extlinux/Makefile
@@ -15,7 +15,8 @@
##
topdir = ..
-include $(topdir)/MCONFIG
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/syslinux.mk
OPTFLAGS = -g -Os
INCLUDES = -I. -I.. -I../libinstaller
diff --git a/extlinux/main.c b/extlinux/main.c
index 21369e46..e5212a95 100755
--- a/extlinux/main.c
+++ b/extlinux/main.c
@@ -503,19 +503,6 @@ int install_file(const char *path, int devfd, struct stat *rst)
return 1;
}
-/*
- * SYSLINUX installs the string 'SYSLINUX' at offset 3 in the boot
- * sector; this is consistent with FAT filesystems. Earlier versions
- * would install the string "EXTLINUX" instead, handle both.
- */
-int already_installed(int devfd)
-{
- char buffer[8];
-
- xpread(devfd, buffer, 8, 3);
- return !memcmp(buffer, "SYSLINUX", 8) || !memcmp(buffer, "EXTLINUX", 8);
-}
-
#ifdef __KLIBC__
static char devname_buf[64];
@@ -766,7 +753,7 @@ int install_loader(const char *path, int update_only)
if (devfd < 0)
return 1;
- if (update_only && !already_installed(devfd)) {
+ if (update_only && !syslinux_already_installed(devfd)) {
fprintf(stderr, "%s: no previous syslinux boot sector found\n",
program);
close(devfd);
diff --git a/libinstaller/syslxcom.c b/libinstaller/syslxcom.c
index b176f6d7..1de85aa5 100644
--- a/libinstaller/syslxcom.c
+++ b/libinstaller/syslxcom.c
@@ -284,3 +284,16 @@ int sectmap(int fd, sector_t *sectors, int nsectors)
return sectmap_fib(fd, sectors, nsectors);
}
+
+/*
+ * SYSLINUX installs the string 'SYSLINUX' at offset 3 in the boot
+ * sector; this is consistent with FAT filesystems. Earlier versions
+ * would install the string "EXTLINUX" instead, handle both.
+ */
+int syslinux_already_installed(int dev_fd)
+{
+ char buffer[8];
+
+ xpread(dev_fd, buffer, 8, 3);
+ return !memcmp(buffer, "SYSLINUX", 8) || !memcmp(buffer, "EXTLINUX", 8);
+}
diff --git a/libinstaller/syslxcom.h b/libinstaller/syslxcom.h
index 39ca09d3..bf186ca6 100644
--- a/libinstaller/syslxcom.h
+++ b/libinstaller/syslxcom.h
@@ -18,5 +18,6 @@ ssize_t xpwrite(int fd, const void *buf, size_t count, off_t offset);
void clear_attributes(int fd);
void set_attributes(int fd);
int sectmap(int fd, sector_t *sectors, int nsectors);
+int syslinux_already_installed(int dev_fd);
#endif
diff --git a/libinstaller/syslxmod.c b/libinstaller/syslxmod.c
index b4d78365..d4674917 100644
--- a/libinstaller/syslxmod.c
+++ b/libinstaller/syslxmod.c
@@ -33,26 +33,29 @@
static void generate_extents(struct syslinux_extent *ex, int nptrs,
const sector_t *sectp, int nsect)
{
- uint32_t addr = 0x7c00 + 2*SECTOR_SIZE;
+ uint32_t addr = 0x8000; /* ldlinux.sys starts loading here */
uint32_t base;
sector_t sect, lba;
unsigned int len;
- len = lba = base = 0;
+ base = addr;
+ len = lba = 0;
memset(ex, 0, nptrs * sizeof *ex);
while (nsect) {
sect = *sectp++;
- if (len && sect == lba + len &&
- ((addr ^ (base + len * SECTOR_SIZE)) & 0xffff0000) == 0) {
- /* We can add to the current extent */
- len++;
- goto next;
- }
-
if (len) {
+ uint32_t xbytes = (len + 1) * SECTOR_SIZE;
+
+ if (sect == lba + len && xbytes < 65536 &&
+ ((addr ^ (base + xbytes - 1)) & 0xffff0000) == 0) {
+ /* We can add to the current extent */
+ len++;
+ goto next;
+ }
+
set_64_sl(&ex->lba, lba);
set_16_sl(&ex->len, len);
ex++;
diff --git a/linux/Makefile b/linux/Makefile
index ffe22728..b9dac179 100644
--- a/linux/Makefile
+++ b/linux/Makefile
@@ -15,7 +15,8 @@
##
topdir = ..
-include $(topdir)/MCONFIG
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/syslinux.mk
OPTFLAGS = -g -O0 -Dalloca=malloc
INCLUDES = -I. -I.. -I../libinstaller
diff --git a/linux/syslinux.c b/linux/syslinux.c
index 97b6a306..c7a9ecc4 100755
--- a/linux/syslinux.c
+++ b/linux/syslinux.c
@@ -382,6 +382,10 @@ int main(int argc, char *argv[])
sync();
rmdir(mntpath);
exit(0);
+ } else if (opt.update_only && !syslinux_already_installed(dev_fd)) {
+ fprintf(stderr, "%s: no previous syslinux boot sector found\n",
+ argv[0]);
+ exit(1);
} else {
fprintf(stderr, "%s: please specify --install or --update for the future\n", argv[0]);
opt.update_only = 0;
diff --git a/lzo/Makefile b/lzo/Makefile
index d88279dd..cf8f985a 100644
--- a/lzo/Makefile
+++ b/lzo/Makefile
@@ -11,7 +11,8 @@
## -----------------------------------------------------------------------
topdir = ..
-include $(topdir)/MCONFIG.build
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/build.mk
INCLUDES += -I./include
diff --git a/mbr/Makefile b/mbr/Makefile
index c3eb97a7..993bb100 100644
--- a/mbr/Makefile
+++ b/mbr/Makefile
@@ -16,7 +16,8 @@
#
topdir = ..
-include $(topdir)/MCONFIG.embedded
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/embedded.mk
all: mbr.bin altmbr.bin gptmbr.bin isohdpfx.bin isohdppx.bin \
mbr_c.bin altmbr_c.bin gptmbr_c.bin isohdpfx_c.bin isohdppx_c.bin \
diff --git a/memdisk/Makefile b/memdisk/Makefile
index 92f565a4..5475b44d 100644
--- a/memdisk/Makefile
+++ b/memdisk/Makefile
@@ -12,7 +12,8 @@
## -----------------------------------------------------------------------
topdir = ..
-include $(topdir)/MCONFIG.embedded
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/embedded.mk
-include $(topdir)/version.mk
INCLUDES = -I$(topdir)/com32/include
diff --git a/memdump/Makefile b/memdump/Makefile
index e56c7bd4..6a30431a 100644
--- a/memdump/Makefile
+++ b/memdump/Makefile
@@ -15,7 +15,8 @@
##
topdir = ..
-include $(topdir)/MCONFIG.embedded
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/embedded.mk
OPTFLAGS =
INCLUDES = -include code16.h -I.
diff --git a/MCONFIG.build b/mk/build.mk
index d1abff2a..0ca82bea 100644
--- a/MCONFIG.build
+++ b/mk/build.mk
@@ -14,7 +14,7 @@
## Right now we don't distinguish between "build" system and the "host"
## system, although we really should...
##
-include $(topdir)/MCONFIG
+include $(MAKEDIR)/syslinux.mk
OPTFLAGS = -g -Os
INCLUDES =
diff --git a/com32/MCONFIG b/mk/com32.mk
index 6216f0d7..531459ed 100644
--- a/com32/MCONFIG
+++ b/mk/com32.mk
@@ -15,7 +15,7 @@
## COM32 common configurables
##
-include $(topdir)/MCONFIG
+include $(MAKEDIR)/syslinux.mk
GCCOPT := $(call gcc_ok,-std=gnu99,)
GCCOPT += $(call gcc_ok,-m32,)
diff --git a/MCONFIG.devel b/mk/devel.mk
index c05d76e8..c05d76e8 100644
--- a/MCONFIG.devel
+++ b/mk/devel.mk
diff --git a/MCONFIG.embedded b/mk/embedded.mk
index 9f5846d7..e8f3ae30 100644
--- a/MCONFIG.embedded
+++ b/mk/embedded.mk
@@ -14,7 +14,7 @@
## Make configuration for embedded directories
##
-include $(topdir)/MCONFIG
+include $(MAKEDIR)/syslinux.mk
GCCOPT := $(call gcc_ok,-m32,)
GCCOPT += $(call gcc_ok,-ffreestanding,)
diff --git a/com32/lib/MCONFIG b/mk/lib.mk
index c441c9c1..33440274 100644
--- a/com32/lib/MCONFIG
+++ b/mk/lib.mk
@@ -1,6 +1,6 @@
# -*- makefile -*-
-include $(topdir)/MCONFIG
+include $(MAKEDIR)/syslinux.mk
GCCOPT := $(call gcc_ok,-std=gnu99,)
GCCOPT += $(call gcc_ok,-m32,)
diff --git a/com32/rosh/MCONFIG b/mk/rosh.mk
index 25c41396..7fdba0f1 100644
--- a/com32/rosh/MCONFIG
+++ b/mk/rosh.mk
@@ -15,7 +15,7 @@
##
## Include the COM32 common configurables
-include ../MCONFIG
+include $(MAKEDIR)/com32.mk
# CFLAGS = $(GCCOPT) $(GCCWARN) -march=i386 \
# -fomit-frame-pointer -D__COM32__ \
diff --git a/MCONFIG b/mk/syslinux.mk
index a2a87a51..966ca87a 100644
--- a/MCONFIG
+++ b/mk/syslinux.mk
@@ -78,7 +78,7 @@ UMAKEDEPS = -Wp,-MT,$@,-MMD,$(dir $@).$(notdir $@).d
# Items that are only appropriate during development; this file is
# removed when tarballs are generated.
--include $(topdir)/MCONFIG.devel
+-include $(makefiledir)/devel.mk
# Local additions, like -DDEBUG can go here
--include $(topdir)/MCONFIG.local
+-include $(makefiledir)/local.mk
diff --git a/modules/Makefile b/modules/Makefile
index 9b50bb23..f878c70d 100644
--- a/modules/Makefile
+++ b/modules/Makefile
@@ -15,7 +15,8 @@
##
topdir = ..
-include $(topdir)/MCONFIG.embedded
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/embedded.mk
INCLUDES = -I$(com32)/include
diff --git a/mtools/Makefile b/mtools/Makefile
index 6164d24c..04e9d7de 100755
--- a/mtools/Makefile
+++ b/mtools/Makefile
@@ -1,5 +1,6 @@
topdir = ..
-include $(topdir)/MCONFIG
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/syslinux.mk
OPTFLAGS = -g -Os
INCLUDES = -I. -I.. -I../libfat -I../libinstaller
diff --git a/sample/Makefile b/sample/Makefile
index d7f439ca..9e504d96 100644
--- a/sample/Makefile
+++ b/sample/Makefile
@@ -15,7 +15,8 @@
##
topdir = ..
-include $(topdir)/MCONFIG.embedded
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/embedded.mk
PPMTOLSS16 = $(topdir)/utils/ppmtolss16
diff --git a/syslinux.spec.in b/syslinux.spec.in
index c4b466b5..b82d9a14 100644
--- a/syslinux.spec.in
+++ b/syslinux.spec.in
@@ -11,7 +11,7 @@ Source0: ftp://ftp.kernel.org/pub/linux/utils/boot/syslinux/%{name}-%{VERSION}.t
ExclusiveArch: i386 i486 i586 i686 athlon pentium4 x86_64
Packager: H. Peter Anvin <hpa@zytor.com>
Buildroot: %{_tmppath}/%{name}-%{VERSION}-root
-BuildPrereq: nasm >= 2.03, perl
+BuildRequires: nasm >= 2.03, perl
Autoreq: 0
%ifarch x86_64
Requires: mtools, libc.so.6()(64bit)
@@ -94,6 +94,7 @@ rm -rf %{buildroot}
%{_datadir}/syslinux/*.0
%{_datadir}/syslinux/memdisk
%{_datadir}/syslinux/dosutil/*
+%{_datadir}/syslinux/diag/*
%files devel
%{_datadir}/syslinux/com32
diff --git a/utils/Makefile b/utils/Makefile
index 455eb828..eed07bba 100644
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -15,7 +15,8 @@
#
topdir = ..
-include $(topdir)/MCONFIG
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/syslinux.mk
CFLAGS = $(GCCWARN) -Os -fomit-frame-pointer -D_FILE_OFFSET_BITS=64
LDFLAGS = -O2 -s
diff --git a/utils/ppmtolss16 b/utils/ppmtolss16
index 5af90831..ae2d546d 100755
--- a/utils/ppmtolss16
+++ b/utils/ppmtolss16
@@ -229,7 +229,7 @@ for ( $y = 0 ; $y < $ysize ; $y++ ) {
start_new_row();
for ( $x = 0 ; $x < $xsize ; $x++ ) {
die "$0: Premature EOF at ($x,$y) of ($xsize,$ysize)\n"
- if ( !defined(@pnmrgb = getrgb($form)) );
+ if ( !scalar(@pnmrgb = getrgb($form)) );
# Convert to 6-bit representation
$rgb = rgbconvert($pnmrgb[0], $pnmrgb[1], $pnmrgb[2], $maxmult);
$color_count{$rgb}++;