aboutsummaryrefslogtreecommitdiffstats
path: root/com32
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 /com32
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
Diffstat (limited to 'com32')
-rw-r--r--com32/MCONFIG99
-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/MCONFIG80
-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/MCONFIG27
-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
100 files changed, 4292 insertions, 563 deletions
diff --git a/com32/MCONFIG b/com32/MCONFIG
deleted file mode 100644
index 6216f0d7..00000000
--- a/com32/MCONFIG
+++ /dev/null
@@ -1,99 +0,0 @@
-## -*- makefile -*- -------------------------------------------------------
-##
-## Copyright 2008-2009 H. Peter Anvin - All Rights Reserved
-## Copyright 2009 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
-## the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
-## Boston MA 02110-1301, USA; either version 2 of the License, or
-## (at your option) any later version; incorporated herein by reference.
-##
-## -----------------------------------------------------------------------
-
-##
-## COM32 common configurables
-##
-
-include $(topdir)/MCONFIG
-
-GCCOPT := $(call gcc_ok,-std=gnu99,)
-GCCOPT += $(call gcc_ok,-m32,)
-GCCOPT += $(call gcc_ok,-fno-stack-protector,)
-GCCOPT += $(call gcc_ok,-fwrapv,)
-GCCOPT += $(call gcc_ok,-freg-struct-return,)
-GCCOPT += -mregparm=3 -DREGPARM=3 -march=i386 -Os
-GCCOPT += $(call gcc_ok,-fPIE,-fPIC)
-GCCOPT += $(call gcc_ok,-fno-exceptions,)
-GCCOPT += $(call gcc_ok,-fno-asynchronous-unwind-tables,)
-GCCOPT += $(call gcc_ok,-fno-strict-aliasing,)
-GCCOPT += $(call gcc_ok,-falign-functions=0,-malign-functions=0)
-GCCOPT += $(call gcc_ok,-falign-jumps=0,-malign-jumps=0)
-GCCOPT += $(call gcc_ok,-falign-labels=0,-malign-labels=0)
-GCCOPT += $(call gcc_ok,-falign-loops=0,-malign-loops=0)
-GCCOPT += $(call gcc_ok,-mpreferred-stack-boundary=2,)
-GCCOPT += $(call gcc_ok,-incoming-stack-boundary=2,)
-
-com32 := $(topdir)/com32
-RELOCS := $(com32)/tools/relocs
-
-ifneq ($(NOGPL),1)
-GPLLIB = $(com32)/gpllib/libcom32gpl.a
-GPLINCLUDE = -I$(com32)/gplinclude
-else
-GPLLIB =
-GPLINCLUDE =
-endif
-
-CFLAGS = $(GCCOPT) $(GCCWARN) -march=i386 \
- -fomit-frame-pointer -D__COM32__ \
- -nostdinc -iwithprefix include \
- -I$(com32)/libutil/include -I$(com32)/include $(GPLINCLUDE)
-SFLAGS = $(GCCOPT) $(GCCWARN) -march=i386 \
- -fomit-frame-pointer -D__COM32__ \
- -nostdinc -iwithprefix include \
- -I$(com32)/libutil/include -I$(com32)/include $(GPLINCLUDE)
-
-COM32LD = $(com32)/lib/elf32.ld
-LDFLAGS = -m elf_i386 -shared --hash-style=gnu -T $(COM32LD)
-LIBGCC := $(shell $(CC) $(GCCOPT) --print-libgcc)
-
-LNXCFLAGS = -I$(com32)/libutil/include $(GCCWARN) -O -g \
- -D_GNU_SOURCE -D_FORTIFY_SOURCE=0 -Wno-error
-LNXSFLAGS = -g
-LNXLDFLAGS = -g
-
-C_LIBS = $(com32)/libutil/libutil_com.a $(GPLLIB) \
- $(com32)/lib/libcom32.a $(LIBGCC)
-C_LNXLIBS = $(com32)/libutil/libutil_lnx.a
-
-.SUFFIXES: .lss .c .lo .o .elf .c32 .lnx
-
-.PRECIOUS: %.o
-%.o: %.S
- $(CC) $(MAKEDEPS) $(SFLAGS) -c -o $@ $<
-
-.PRECIOUS: %.o
-%.o: %.c
- $(CC) $(MAKEDEPS) $(CFLAGS) -c -o $@ $<
-
-.PRECIOUS: %.elf
-%.elf: %.o $(LIBS) $(C_LIBS) $(COM32LD)
- $(LD) $(LDFLAGS) -o $@ $(filter-out $(COM32LD),$^)
-
-.PRECIOUS: %.lo
-%.lo: %.S
- $(CC) $(MAKEDEPS) $(LNXSFLAGS) -c -o $@ $<
-
-.PRECIOUS: %.lo
-%.lo: %.c
- $(CC) $(MAKEDEPS) $(LNXCFLAGS) -c -o $@ $<
-
-.PRECIOUS: %.lnx
-%.lnx: %.lo $(LNXLIBS) $(C_LNXLIBS)
- $(CC) $(LNXCFLAGS) -o $@ $^
-
-%.c32: %.elf
- $(OBJCOPY) --strip-debug --strip-unneeded $< $@
- ##$(OBJCOPY) -O binary $< $@
- ##$(RELOCS) $< >> $@ || ( rm -f $@ ; false )
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/MCONFIG b/com32/lib/MCONFIG
deleted file mode 100644
index c441c9c1..00000000
--- a/com32/lib/MCONFIG
+++ /dev/null
@@ -1,80 +0,0 @@
-# -*- makefile -*-
-
-include $(topdir)/MCONFIG
-
-GCCOPT := $(call gcc_ok,-std=gnu99,)
-GCCOPT += $(call gcc_ok,-m32,)
-GCCOPT += $(call gcc_ok,-fno-stack-protector,)
-GCCOPT += $(call gcc_ok,-fwrapv,)
-GCCOPT += $(call gcc_ok,-freg-struct-return,)
-GCCOPT += $(call gcc_ok,-fPIE,-fPIC)
-GCCOPT += $(call gcc_ok,-fno-exceptions,)
-GCCOPT += $(call gcc_ok,-fno-asynchronous-unwind-tables,)
-GCCOPT += $(call gcc_ok,-fno-strict-aliasing,)
-GCCOPT += $(call gcc_ok,-falign-functions=0,-malign-functions=0)
-GCCOPT += $(call gcc_ok,-falign-jumps=0,-malign-jumps=0)
-GCCOPT += $(call gcc_ok,-falign-labels=0,-malign-labels=0)
-GCCOPT += $(call gcc_ok,-falign-loops=0,-malign-loops=0)
-GCCOPT += $(call gcc_ok,-mpreferred-stack-boundary=2,)
-
-INCLUDE = -I.
-STRIP = strip --strip-all -R .comment -R .note
-
-# zlib and libpng configuration flags
-LIBFLAGS = -DDYNAMIC_CRC_TABLE -DPNG_NO_CONSOLE_IO \
- -DPNG_NO_WRITE_SUPPORTED \
- -DPNG_NO_MNG_FEATURES \
- -DPNG_NO_READ_tIME -DPNG_NO_WRITE_tIME
-
-# We need some features in libpng which apparently aren't available in the
-# fixed-point versions. It's OK, because we have to have a non-graphical
-# fallback anyway, just use that on old machines...
-# LIBFLAGS += -DPNG_NO_FLOATING_POINT_SUPPORTED
-
-REQFLAGS = $(GCCOPT) -g -mregparm=3 -DREGPARM=3 -D__COM32__ \
- -nostdinc -iwithprefix include -I. -I./sys -I../include
-OPTFLAGS = -Os -march=i386 -falign-functions=0 -falign-jumps=0 \
- -falign-labels=0 -ffast-math -fomit-frame-pointer
-WARNFLAGS = $(GCCWARN) -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Winline
-
-CFLAGS = $(OPTFLAGS) $(REQFLAGS) $(WARNFLAGS) $(LIBFLAGS)
-LDFLAGS = -m elf32_i386 --hash-style=gnu
-
-.SUFFIXES: .c .o .a .so .lo .i .S .s .ls .ss .lss
-
-% : %.c # Cancel default rule
-
-% : %.S
-
-.c.o:
- $(CC) $(MAKEDEPS) $(CFLAGS) -c -o $@ $<
-
-.c.i:
- $(CC) $(MAKEDEPS) $(CFLAGS) -E -o $@ $<
-
-.c.s:
- $(CC) $(MAKEDEPS) $(CFLAGS) -S -o $@ $<
-
-.S.o:
- $(CC) $(MAKEDEPS) $(CFLAGS) -D__ASSEMBLY__ -c -o $@ $<
-
-.S.s:
- $(CC) $(MAKEDEPS) $(CFLAGS) -D__ASSEMBLY__ -E -o $@ $<
-
-.S.lo:
- $(CC) $(MAKEDEPS) $(CFLAGS) $(SOFLAGS) -D__ASSEMBLY__ -c -o $@ $<
-
-.S.ls:
- $(CC) $(MAKEDEPS) $(CFLAGS) $(SOFLAGS) -D__ASSEMBLY__ -E -o $@ $<
-
-.s.o:
- $(CC) $(MAKEDEPS) $(CFLAGS) -x assembler -c -o $@ $<
-
-.ls.lo:
- $(CC) $(MAKEDEPS) $(CFLAGS) $(SOFLAGS) -x assembler -c -o $@ $<
-
-.c.lo:
- $(CC) $(MAKEDEPS) $(CFLAGS) $(SOFLAGS) -c -o $@ $<
-
-.c.ls:
- $(CC) $(MAKEDEPS) $(CFLAGS) $(SOFLAGS) -S -o $@ $<
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/MCONFIG b/com32/rosh/MCONFIG
deleted file mode 100644
index 25c41396..00000000
--- a/com32/rosh/MCONFIG
+++ /dev/null
@@ -1,27 +0,0 @@
-## -*- makefile -*- -------------------------------------------------------
-##
-## Copyright 2008 H. Peter Anvin - All Rights Reserved
-##
-## 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
-## the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
-## Boston MA 02110-1301, USA; either version 2 of the License, or
-## (at your option) any later version; incorporated herein by reference.
-##
-## -----------------------------------------------------------------------
-
-##
-## COM32 GRC configurables
-##
-
-## Include the COM32 common configurables
-include ../MCONFIG
-
-# CFLAGS = $(GCCOPT) $(GCCWARN) -march=i386 \
-# -fomit-frame-pointer -D__COM32__ \
-# -nostdinc -iwithprefix include \
-# -I$(com32)/libutil/include -I$(com32)/include
-# -g3 -dD
-
-# LNXCFLAGS = -I$(com32)/libutil/include $(GCCWARN) -O -g3 -D_GNU_SOURCE -dD
-# -U__GNUC__
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