summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.autoheader36
-rw-r--r--Makefile91
-rw-r--r--README2
-rw-r--r--contrib/python-dmidecode.spec70
-rw-r--r--debian/changelog33
-rw-r--r--debian/control4
-rw-r--r--debian/copyright9
-rw-r--r--debian/python-dmidecode-dbg.docs4
-rw-r--r--debian/python-dmidecode.docs4
-rw-r--r--debian/upstream.changelog3158
-rw-r--r--dmidecode.py89
-rw-r--r--doc/AUTHORS24
-rw-r--r--doc/LICENSE914
-rwxr-xr-xdoc/dmidump.py54
-rwxr-xr-xexamples/dmidump.py38
-rwxr-xr-xexamples/test.py112
-rw-r--r--python-dmidecode.spec44
-rw-r--r--src/config.h39
-rw-r--r--src/dmidecode.c8809
-rw-r--r--src/dmidecode.h39
-rw-r--r--src/dmidecodemodule.c964
-rw-r--r--src/dmidecodemodule.h87
-rw-r--r--src/dmidump.c168
-rw-r--r--src/dmidump.h37
-rw-r--r--src/dmierror.c79
-rw-r--r--src/dmierror.h54
-rw-r--r--src/dmihelper.c115
-rw-r--r--src/dmihelper.h189
-rw-r--r--src/dmioem.c125
-rw-r--r--src/dmioem.h1
-rw-r--r--src/dmixml.c360
-rw-r--r--src/dmixml.h79
-rw-r--r--src/efi.c83
-rw-r--r--src/efi.h35
-rw-r--r--src/libxml_wrap.h280
-rw-r--r--src/pymap.xml864
-rw-r--r--src/setup-dbg.py77
-rw-r--r--src/setup.py77
-rw-r--r--src/setup_common.py93
-rw-r--r--src/types.h46
-rw-r--r--src/util.c235
-rw-r--r--src/util.h3
-rw-r--r--src/version.h2
-rw-r--r--src/xmlpythonizer.c1183
-rw-r--r--src/xmlpythonizer.h60
-rw-r--r--unit-tests/Makefile34
-rw-r--r--unit-tests/POCDemo.py12
-rw-r--r--unit-tests/demo.c99
-rw-r--r--unit-tests/demo.h14
-rw-r--r--unit-tests/dmixml.c248
-rw-r--r--unit-tests/dmixml.h43
-rw-r--r--unit-tests/libxml_wrap.h249
-rwxr-xr-xunit-tests/unit268
-rwxr-xr-xutils/c-code-indent3
-rwxr-xr-xutils/set_version56
55 files changed, 13177 insertions, 6718 deletions
diff --git a/.autoheader b/.autoheader
new file mode 100644
index 0000000..bc6e134
--- /dev/null
+++ b/.autoheader
@@ -0,0 +1,36 @@
+
+© 2007-2009 Nima Talebi <nima@autonomy.net.au>
+© 2009 David Sommerseth <davids@redhat.com>
+© 2002-2008 Jean Delvare <khali@linux-fr.org>
+© 2000-2002 Alan Cox <alan@redhat.com>
+
+This file is part of @PKG@.
+
+ @PKG@ 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, either version 2 of the License, or
+ (at your option) any later version.
+
+ @PKG@ is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with @PKG@. If not, see <http://www.gnu.org/licenses/>.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ADAPTED M. STONE & T. PARKER DISCLAIMER: THIS SOFTWARE COULD RESULT IN INJURY
+AND/OR DEATH, AND AS SUCH, IT SHOULD NOT BE BUILT, INSTALLED OR USED BY ANYONE.
+
+$AutoHeaderSerial::@SERIAL@ $
diff --git a/Makefile b/Makefile
index 8e69bb5..107dbdb 100644
--- a/Makefile
+++ b/Makefile
@@ -3,95 +3,60 @@
#.
#. (C) 2008 Nima Talebi <nima@it.net.au>
#.
-#. Licensed under the GNU Public License v3
+#. Licensed under the GNU Public License v2
#.
-VERSION := 2.10
-PY := $(shell python -V 2>&1 |sed -e 's/.\(ython\) \(2\.[0-9]\)\..*/p\1\2/')
-PY_VER := $(subst python,,$(PY))
+VERSION := $(shell cd src;python -c "from setup_common import *; print get_version();")
PACKAGE := python-dmidecode
-SRCSRV := /var/www/nima/sites/src.autonomy.net.au/pub
+PY_VER := $(shell python -c 'import sys; print "%d.%d"%sys.version_info[0:2]')
+PY := python$(PY_VER)
+SO = build/lib.linux-$(shell uname -m)-$(PY_VER)/dmidecodemod.so
-CC := gcc
-RM := rm -f
-SRC_D := src
-OBJ_D := lib
-CFLAGS = -g -D_XOPEN_SOURCE=600
-CFLAGS += -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-align
-CFLAGS += -Wwrite-strings -Wmissing-prototypes -Winline -Wundef #-Wcast-qual
-CFLAGS += -pthread -fno-strict-aliasing -DNDEBUG -fPIC
-CFLAGS += -I/usr/include/$(PY)
-CFLAGS += -O3
-#CFLAGS += -DNDEBUG
-#CFLAGS += -DBIGENDIAN
-#CFLAGS += -DALIGNMENT_WORKAROUND
-#LDFLAGS = -lefence
-LDFLAGS =
-SOFLAGS = -pthread -shared -L/home/nima/dev-room/projects/dmidecode -lutil
-SO = build/lib.linux-$(shell uname -m)-$(PY_VER)/dmidecode.so
-
-#. Search
-vpath %.o $(OBJ_D)
-vpath %.c $(SRC_D)
-vpath %.h $(SRC_D)
-vpath % $(OBJ_D)
+###############################################################################
+.PHONY: build dmidump install uninstall clean tarball rpm unit version
+all : build dmidump
-###############################################################################
-build: $(PY)-dmidecode.so
-$(PY)-dmidecode.so: $(SO)
+build: $(PY)-dmidecodemod.so
+$(PY)-dmidecodemod.so: $(SO)
cp $< $@
-
-build: $(SO)
$(SO):
$(PY) src/setup.py build
+dmidump : src/util.o src/efi.o
+ $(CC) -o $@ src/dmidump.c $^ -g -Wall -D_DMIDUMP_MAIN_
+
install:
$(PY) src/setup.py install
uninstall:
$(PY) src/setup.py uninstall
-clean :
- dh_clean
- $(PY) src/setup.py clean
- -$(RM) *.so lib/*.o core
- -rm -rf build .dpkg
+clean:
+ -$(PY) src/setup.py clean --all
+ -rm -f *.so lib/*.o core dmidump
+ -rm -rf build
+ -rm -rf rpm
+ -rm -rf src/setup_common.py[oc]
+ -rm -rf $(PACKAGE)-$(VERSION) $(PACKAGE)-$(VERSION).tar.gz
+ $(MAKE) -C unit-tests clean
tarball:
rm -rf $(PACKAGE)-$(VERSION)
mkdir $(PACKAGE)-$(VERSION)
- cp -r contrib doc examples lib Makefile man README src $(PACKAGE)-$(VERSION)
+ cp -r contrib doc examples Makefile man README src dmidecode.py $(PACKAGE)-$(VERSION)
tar -czvf $(PACKAGE)-$(VERSION).tar.gz $(PACKAGE)-$(VERSION)
-rpm: tarball
- rm -rf rpm
+rpm: tarball
mkdir -p rpm/{BUILD,RPMS,SRPMS,SPECS,SOURCES}
cp contrib/$(PACKAGE).spec rpm/SPECS
cp $(PACKAGE)-$(VERSION).tar.gz rpm/SOURCES
rpmbuild -ba --define "_topdir $(shell pwd)/rpm" rpm/SPECS/$(PACKAGE).spec
-###############################################################################
-libdmidecode.so: dmihelper.o util.o dmioem.o dmidecode.o dmidecodemodule.o
- $(CC) $(LDFLAGS) $(SOFLAGS) $^ -o $@
-
-$(OBJ_D)/dmidecodemodule.o: dmidecodemodule.c
- $(CC) $(CFLAGS) -c -o $@ $<
+unit:
+ $(MAKE) -C unit-tests
-$(OBJ_D)/dmidecode.o: dmidecode.c version.h types.h util.h config.h dmidecode.h dmioem.h
- $(CC) $(CFLAGS) -c -o $@ $<
+version:
+ @echo "python-dmidecode: $(VERSION)"
+ @echo "python version: $(PY_VER) ($(PY))"
-$(OBJ_D)/dmihelper.o: dmihelper.c dmihelper.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-$(OBJ_D)/util.o: util.c types.h util.h config.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-$(OBJ_D)/dmioem.o: dmioem.c types.h dmidecode.h dmioem.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-
-
-###############################################################################
-.PHONY: install clean uninstall build dupload
-.PHONY: srcsrv binary source orig.tar.gz all
diff --git a/README b/README
index 089a6f3..4892ef5 100644
--- a/README
+++ b/README
@@ -1 +1 @@
-Please visit http://projects.autonomy.net.au/dmidecode/
+Please visit http://projects.autonomy.net.au/python-dmidecode/
diff --git a/contrib/python-dmidecode.spec b/contrib/python-dmidecode.spec
new file mode 100644
index 0000000..0d48fc3
--- /dev/null
+++ b/contrib/python-dmidecode.spec
@@ -0,0 +1,70 @@
+%{!?python_sitearch: %define python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")}
+%{!?python_ver: %define python_ver %(%{__python} -c "import sys ; print sys.version[:3]")}
+
+Summary: python extension module to access DMI data
+Name: python-dmidecode
+Version: 3.10.6
+Release: 6%{?dist}
+License: GPLv2
+Group: System Environment/Libraries
+URL: http://projects.autonomy.net.au/dmidecode/
+Source0: %{name}-%{version}.tar.gz
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
+Requires: libxml2
+Requires: libxml2-python
+BuildRequires: libxml2-python
+BuildRequires: libxml2-devel
+BuildRequires: python-devel
+
+%description
+python-dmidecode is a python extension module that uses the
+code-base of the 'dmidecode' utility, and presents the data
+as python data structures or as XML data using libxml2.
+
+%prep
+%setup -q
+
+%build
+make build
+
+%install
+rm -rf $RPM_BUILD_ROOT
+python src/setup.py install --root $RPM_BUILD_ROOT
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+
+%files
+%defattr(-,root,root,-)
+%doc
+%{python_sitearch}/dmidecodemod.so
+%{python_sitearch}/dmidecode.py
+%{python_sitearch}/dmidecode.py[co]
+%if "%{python_ver}" >= "2.5"
+%{python_sitearch}/*.egg-info
+%endif
+/usr/share/python-dmidecode/pymap.xml
+
+%changelog
+* Wed Jul 13 2009 David Sommerseth <davids@redhat.com> - 3.10.6-6
+- Only build the python-dmidecode module, not everything
+
+* Wed Jul 13 2009 David Sommerseth <davids@redhat.com> - 3.10.6-5
+- Added missing BuildRequres for libxml2-python
+
+* Wed Jul 13 2009 David Sommerseth <davids@redhat.com> - 3.10.6-4
+- Added missing BuildRequres for python-devel
+
+* Wed Jul 13 2009 David Sommerseth <davids@redhat.com> - 3.10.6-3
+- Added missing BuildRequres for libxml2-devel
+
+* Wed Jul 13 2009 David Sommerseth <davids@redhat.com> - 3.10.6-2
+- Updated release, to avoid build conflict
+
+* Wed Jun 10 2009 David Sommerseth <davids@redhat.com> - 3.10.6-1
+- Updated to work with the new XML based python-dmidecode
+
+* Sat Mar 7 2009 Clark Williams <williams@redhat.com> - 2.10.3-1
+- Initial build.
+
diff --git a/debian/changelog b/debian/changelog
index e9a044f..01b37e7 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,11 +1,34 @@
+python-dmidecode (3.10.6-2) unstable; urgency=low
+
+ * Fixed homepage (Closes: #540389).
+
+ -- Nima Talebi <nima@it.net.au> Sat, 08 Aug 2009 13:53:40 +1000
+
+python-dmidecode (3.10.6-1) unstable; urgency=low
+
+ * Introducing the XML extensions to python-dmidecode, by of David Sommerseth
+ from Red Hat. A big thankyou to David, Red Hat, and other people from
+ Red Hat that contributed (and are still contributing) time and knowledge
+ to this project. These changes are summarized as follows...
+ * Rewritten the internals to use libxml2 for (in memory) data storage.
+ * Added much more useful information into the XML data than what the original
+ data structured could held.
+ * Implemented mapping methods to dynamically map XML fields to Python
+ dictionaries. The mapping itself is defined in an XML file utilising XPath
+ expressions.
+ * Prepared python-dmidecode for a native XML implementation from Python using
+ libxml2.
+
+ -- Nima Talebi <nima@it.net.au> Sat, 23 May 2009 13:19:25 +1000
+
python-dmidecode (2.10.6-1) unstable; urgency=low
- * David Sommerseth picked up some bad behaviour while working on the libxml2
- extension of python-dmidecode - on further investigation it was found that
- this was due to a copy-paste-gone-wrong during the initial migration of
- dmidecode to python-dmidecode - Fixed.
+ * David Sommerseth, as part of wrting the XML (libxml2) extensions to
+ python-dmidecode, noted a few abnormalities. Sure enough, they were
+ silent bugs introduced at the time of the initial writing of
+ python-dmidecode (from dmidecode). This has now been fixed.
- -- Nima Talebi <nima@it.net.au> Wed, 20 May 2009 22:32:24 +1000
+ -- Nima Talebi <nima@it.net.au> Wed, 20 May 2009 23:15:32 +1000
python-dmidecode (2.10.5-3) unstable; urgency=low
diff --git a/debian/control b/debian/control
index 4874563..f0f88e9 100644
--- a/debian/control
+++ b/debian/control
@@ -2,10 +2,10 @@ Source: python-dmidecode
XS-Python-Version: >= 2.4
Section: python
Priority: optional
-Homepage: http://projects.autonomy.net.au/dmidecode
+Homepage: http://projects.autonomy.net.au/python-dmidecode
Maintainer: Nima Talebi <nima@it.net.au>
Build-Depends: debhelper (> 7), python-support (>= 0.5.3), python,
- python-all-dev (>= 2.3.5-11), python-all-dbg
+ python-all-dev (>= 2.3.5-11), python-all-dbg, electric-fence (> 2)
Standards-Version: 3.8.1
Package: python-dmidecode
diff --git a/debian/copyright b/debian/copyright
index 2515d56..2a3c869 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -13,13 +13,13 @@ It was downloaded from http://projects.autonomy.net.au/dmidecode/
Upstream Author: Nima Talebi <nima@autonomy.net.au>
The Debian packaging is © 2008, Nima Talebi <nima@it.net.au> and is licensed
-under the GPL, see `/usr/share/common-licenses/GPL-3'.
+under the GPL, see `/usr/share/common-licenses/GPL-2'.
License:
- GPLv3 - The python-dmidecode packages is available under the terms of
+ GPLv2 - The python-dmidecode packages is available under the terms of
the GNU General Public license version 3. On Debian systems, the complete
text of the GNU General Public License can be found in
- `/usr/share/common-licenses/GPL-3'.
+ `/usr/share/common-licenses/GPL-2'.
DMIDecode
@@ -36,7 +36,8 @@ Copyrights
==========
© 2000-2002 Alan Cox <alan@redhat.com>
© 2000-2008 Jean Delvare <khali@linux-fr.org>
- © 2007-2009Nima Talebi <nima@it.net.au>
+ © 2007-2009 Nima Talebi <nima@it.net.au>
+ © 2009 David Sommerseth <davids@redhat.com>
License:
This program is free software; you can redistribute it and/or modify
diff --git a/debian/python-dmidecode-dbg.docs b/debian/python-dmidecode-dbg.docs
index 5ac33e9..a2456eb 100644
--- a/debian/python-dmidecode-dbg.docs
+++ b/debian/python-dmidecode-dbg.docs
@@ -1,2 +1,6 @@
README
+doc/AUTHORS
doc/changelog
+doc/README.types
+doc/AUTHORS.upstream
+doc/README.upstream
diff --git a/debian/python-dmidecode.docs b/debian/python-dmidecode.docs
index 5ac33e9..a2456eb 100644
--- a/debian/python-dmidecode.docs
+++ b/debian/python-dmidecode.docs
@@ -1,2 +1,6 @@
README
+doc/AUTHORS
doc/changelog
+doc/README.types
+doc/AUTHORS.upstream
+doc/README.upstream
diff --git a/debian/upstream.changelog b/debian/upstream.changelog
index e0f0ddc..1310319 100644
--- a/debian/upstream.changelog
+++ b/debian/upstream.changelog
@@ -1,952 +1,2454 @@
-------------------------------------------------------------------------
-r166 | nima | 2008-12-22 15:02:00 -0800 (Mon, 22 Dec 2008) | 2 lines
+commit 1c598ad8847d5c506f783b145c734be161100ce9
+Author: Nima Talebi <nima@autonomy.net.au>
+Date: Sat May 23 13:27:01 2009 +1000
-Source file name change.
+ Added missing doc files
-------------------------------------------------------------------------
-r165 | nima | 2008-12-22 15:01:22 -0800 (Mon, 22 Dec 2008) | 2 lines
+commit 3acedf5a988eab36f238979548cc79545bd7dced
+Author: Nima Talebi <nima@autonomy.net.au>
+Date: Sat May 23 13:24:02 2009 +1000
-A more complete dmidecode example.
+ Final cleanup
-------------------------------------------------------------------------
-r164 | nima | 2008-12-22 14:40:51 -0800 (Mon, 22 Dec 2008) | 2 lines
+commit 1bd60ee4c38615f2f1aac873d95cde0e6fae7b1e
+Author: Nima Talebi <nima@autonomy.net.au>
+Date: Sat May 23 13:14:42 2009 +1000
-Applied the nice changes suggested by Piotr Ożarowsk.
+ Fixed minor bug which prevented debug builds
-------------------------------------------------------------------------
-r163 | nima | 2008-12-22 05:37:43 -0800 (Mon, 22 Dec 2008) | 6 lines
+commit 0de97ae9ab884efb0bd24bb0ea1f5770cc74ff89
+Author: Nima Talebi <nima@autonomy.net.au>
+Date: Sat May 23 13:14:34 2009 +1000
-Cleaned up the fix for type(127).
+ Update
-Added the second type of stuffed bios (upstream).
+commit 45d267577a107f7d148f9afe39369785dcd49044
+Author: Nima Talebi <nima@autonomy.net.au>
+Date: Sat May 23 12:58:00 2009 +1000
-Integrated dmidecode the binary into the test case for a more objective result.
+ GPLv3 changed to GPLv2
+
+ Also preparing/cleaning-up example/test-case script.
-------------------------------------------------------------------------
-r162 | nima | 2008-12-22 01:06:43 -0800 (Mon, 22 Dec 2008) | 2 lines
+commit d06d776adb0fef9504bd7662760e4cd0971fb748
+Author: Nima Talebi <nima@autonomy.net.au>
+Date: Fri May 22 23:49:55 2009 +1000
-Fixed the type(127) problem (at least on this machine) - again.
+ Reversioned, relicensed, and rejigged
+
+ The version is of now, v3.10.6. The version major field has been
+ upped due to the newly added XML functionality.
+
+ The version has been reverted to GPLv2.
+
+ Some headers have been cleaned up, copyright notices added etc.
+
+ Credits given where due.
-------------------------------------------------------------------------
-r161 | nima | 2008-12-21 04:52:51 -0800 (Sun, 21 Dec 2008) | 4 lines
+commit cd387fa3d1929505299d1df733fae890aacc75bc
+Author: Nima Talebi <nima@autonomy.net.au>
+Date: Thu May 21 08:20:29 2009 +1000
-Removed unnecessay manpage.
+ Update copyright notice
-Spell my own name correctly.
+commit df5ddd3f51a353d03f2bd6a27c5d9ce14f077f41
+Author: Nima Talebi <nima@autonomy.net.au>
+Date: Thu May 21 00:05:58 2009 +1000
-------------------------------------------------------------------------
-r160 | nima | 2008-12-21 03:31:36 -0800 (Sun, 21 Dec 2008) | 2 lines
+ Bringing setup files upto date
-Added an upload into src.autonomy.net.au after source build.
+commit ceaf615744b2a1a9cd655abef25e0840de731d01
+Author: Nima Talebi <nima@autonomy.net.au>
+Date: Wed May 20 23:18:28 2009 +1000
-------------------------------------------------------------------------
-r159 | nima | 2008-12-21 03:27:52 -0800 (Sun, 21 Dec 2008) | 2 lines
+ Fixed a bug, and preparing to dupload to Debian
-Fixed sample.
+commit ff36dbbc2804858ad7229e1b6bda51fc2250133d
+Author: David Sommerseth <davids@redhat.com>
+Date: Tue May 19 17:09:48 2009 +0200
-------------------------------------------------------------------------
-r158 | nima | 2008-12-21 02:22:06 -0800 (Sun, 21 Dec 2008) | 6 lines
+ Changed the node content of /dmidecode/ProcessorInfo/CPUCore/cpu_flags/flag to maintain backwards compatibility
+
+ The old python-dmidecode uses the format '{flag} ({description})'. This
+ format is now used is well as contents for the cpu_flags/flag text nodes.
-Cleanup copyright.
+commit eff9145436de625fdf0be489be95118c69ec3a2e
+Author: David Sommerseth <davids@redhat.com>
+Date: Tue May 19 17:02:47 2009 +0200
-Cleanup debian/rules.
+ Fixed the bios field mapping to use relative XPaths
-Adding test.py to examples.
+commit 457723c74c011c9a60b6f16c4f089225b5df30c3
+Author: David Sommerseth <davids@redhat.com>
+Date: Tue May 19 16:54:42 2009 +0200
-------------------------------------------------------------------------
-r157 | nima | 2008-12-21 02:04:03 -0800 (Sun, 21 Dec 2008) | 2 lines
+ Added field mapping for dmidecode.connectors()
-Remove README.Debian - no point.
+commit 6e66a28fb04934a58286df8d3b84caf904ae2da7
+Author: David Sommerseth <davids@redhat.com>
+Date: Tue May 19 16:41:16 2009 +0200
-------------------------------------------------------------------------
-r156 | nima | 2008-12-20 23:57:49 -0800 (Sat, 20 Dec 2008) | 2 lines
+ Added field mapping for dmidecode.slots()
-Cleanup.
+commit 5900424cc4a3ba70b79a6f2c31cf2d738b4e0217
+Author: David Sommerseth <davids@redhat.com>
+Date: Tue May 19 16:39:10 2009 +0200
-------------------------------------------------------------------------
-r155 | nima | 2008-12-20 23:53:54 -0800 (Sat, 20 Dec 2008) | 3 lines
+ Use correct index value for /dmidecode/SystemSlots/SlotCharacteristics/Characteristic/@index
-Handle cases where user does not have appropriate permission to access the
-memory file or device.
+commit 2ab1ede583c1dc2e9a81c20c80dc882964dde9a1
+Author: David Sommerseth <davids@redhat.com>
+Date: Tue May 19 15:46:09 2009 +0200
-------------------------------------------------------------------------
-r154 | nima | 2008-12-20 21:44:04 -0800 (Sat, 20 Dec 2008) | 2 lines
+ Added field mapping for dmidecode.baseboard()
-Names.
+commit 15fd846d16312aae19d48bac080498a44a7c469c
+Author: David Sommerseth <davids@redhat.com>
+Date: Tue May 19 15:36:23 2009 +0200
-------------------------------------------------------------------------
-r153 | nima | 2008-12-20 21:43:06 -0800 (Sat, 20 Dec 2008) | 2 lines
+ Added field mapping for the dmidecode.system() section
-Better naming.
+commit 599642f7370cb3f2fbf5c079c20269318d5a775f
+Author: David Sommerseth <davids@redhat.com>
+Date: Tue May 19 15:29:56 2009 +0200
-------------------------------------------------------------------------
-r152 | nima | 2008-12-20 20:41:39 -0800 (Sat, 20 Dec 2008) | 4 lines
+ Added support for value type 'list:dict' for field mapping
+
+ This builds up a list of dicts. Syntax is:
+
+ <Map keytype="constant" key="TestData"
+ valuetype="list:dict" value="/xml/XPath/to/nodes">
+ <Map keytype="constant" key="field"
+ valuetype="string" key="ValueNode"/>
+ </Map>
+
+ The parser will iterate all nodes defined in the @value attribute
+ and the root path will of the nested mapping will be using the path
+ in @value as the root path for further parsing.
-Upped debhelper build-required version from 5 to 7.
+commit 52f936c82d9098b2a64986228ebc1e9109828ac9
+Author: David Sommerseth <davids@redhat.com>
+Date: Tue May 19 12:53:34 2009 +0200
-Final cleanups.
+ Added field python dict mapping for CacheInfo
-------------------------------------------------------------------------
-r151 | nima | 2008-12-20 18:55:19 -0800 (Sat, 20 Dec 2008) | 2 lines
+commit 9f34b97089fe7fb14c6877cc426658c06f04cb9e
+Author: David Sommerseth <davids@redhat.com>
+Date: Tue May 19 11:56:41 2009 +0200
-Cleaned up and Lintian-approved.
+ Fixed some errors in the XML layout on CacheInfo
-------------------------------------------------------------------------
-r150 | nima | 2008-12-20 18:48:05 -0800 (Sat, 20 Dec 2008) | 2 lines
+commit c5ad272970644cee25eefb2010061b751dd17519
+Author: David Sommerseth <davids@redhat.com>
+Date: Fri May 15 13:43:09 2009 +0200
-Email address fixed.
+ Added a few missing comments
-------------------------------------------------------------------------
-r149 | nima | 2008-12-20 18:39:16 -0800 (Sat, 20 Dec 2008) | 2 lines
+commit b20e017f0b09e6f8946db04b0acef69e62fcf114
+Author: Nima Talebi <nima@autonomy.net.au>
+Date: Wed May 20 22:19:23 2009 +1000
-Sigh.
+ Fixed some ugly, unattractive and unhealthy code
+
+ These hangover lines must have crept in at the early stages of the
+ initial conversion of dmidecode to python-dmidecode. Fixed.
-------------------------------------------------------------------------
-r148 | nima | 2008-12-20 18:38:35 -0800 (Sat, 20 Dec 2008) | 2 lines
+commit b694abeb522f93aa842d16720a3aa1f98ad2aa84
+Author: David Sommerseth <davids@redhat.com>
+Date: Fri May 15 11:55:25 2009 +0200
-Changing to svn-buildpackage.
+ Reorganised attributes in SystemSlots tag
+
+ This part of the XML result was not valid due to duplicated tag attributes.
+ Moved some of this specifications from the SystemSlots tag to its own
+ SlotID tag, with even more details.
-------------------------------------------------------------------------
-r147 | nima | 2008-12-20 18:22:20 -0800 (Sat, 20 Dec 2008) | 2 lines
+commit 88688ef91d816e4158fd388131c4060e22116c74
+Author: David Sommerseth <davids@redhat.com>
+Date: Fri May 15 11:28:56 2009 +0200
-Cleanup.
+ Completed mapping the memory section
-------------------------------------------------------------------------
-r146 | nima | 2008-12-20 18:07:56 -0800 (Sat, 20 Dec 2008) | 2 lines
+commit a8d6f0ee846d03d10c188080af69c10567887b56
+Author: David Sommerseth <davids@redhat.com>
+Date: Fri May 15 11:20:07 2009 +0200
-Source generation.
+ Fixed some errors in decoding "3.3.5.9 Processor Characteristics"
+
+ Fixes regression in parsing introduced when rewriting dmidecode to use libxml2
-------------------------------------------------------------------------
-r145 | nima | 2008-12-20 17:41:57 -0800 (Sat, 20 Dec 2008) | 6 lines
+commit 72016cb607798e567ac2f2ce67cc50652b0daa32
+Author: David Sommerseth <davids@redhat.com>
+Date: Fri May 15 11:06:20 2009 +0200
-Fixed watchfile now that I've created a src (orig.tar.gz) repository.
+ Added 'emptyValue' attribute in the Map tag
+
+ This attribute defines a default value when XML source data
+ is empty
-Added more copyright/lisencing information.
+commit fff6c8a1cd328ebce904b7fab4bdc642596a8ef5
+Author: David Sommerseth <davids@redhat.com>
+Date: Thu May 14 17:11:55 2009 +0200
-More debianizing.
+ Remove 'ns' from the speed_ns attribute in memory section
-------------------------------------------------------------------------
-r144 | nima | 2008-12-20 09:00:56 -0800 (Sat, 20 Dec 2008) | 2 lines
+commit 9d47720a88ee77ac4c0ab5f138a8eaf601c492d0
+Author: David Sommerseth <davids@redhat.com>
+Date: Thu May 14 17:06:18 2009 +0200
-Required for dh_installdocs.
+ Added new Map attribute - emptyIsNone
+
+ If the emptyIsNone attribute is set to "1", the Python result
+ will be forced to Py_None if the referenced XML value is empty.
+
+ When checking if the value is empty, the XML value is right trimmed
+ to remove trailing spaces. Only spaces are are removed.
-------------------------------------------------------------------------
-r143 | nima | 2008-12-20 08:54:32 -0800 (Sat, 20 Dec 2008) | 2 lines
+commit a92cc1236ca7c5abee27e4360284b67297e39c15
+Author: David Sommerseth <davids@redhat.com>
+Date: Thu May 14 16:31:34 2009 +0200
-Cleanup.
+ Support fixed size lists
+
+ When using one of the list types as valuetype, the Map tag now
+ also supports fixedsize and index_attr attributes.
+
+ - fixedsize : Defines a fixed size of the list
+ - index_attr : Defines an attribute name of the input XML data
+ which contains the list index for the value
+
+commit eeb40ea2c5a47737f318a1631316416e6f1ab75a
+Author: David Sommerseth <davids@redhat.com>
+Date: Thu May 14 14:57:12 2009 +0200
-------------------------------------------------------------------------
-r142 | nima | 2008-12-20 08:52:15 -0800 (Sat, 20 Dec 2008) | 2 lines
+ Fixed another parser issue
+
+ When using rootpath, it did not parse all elements as expected. Also
+ restricted the rootpath to only work when valuetype="dict".
-Cleanup.
+commit c07eb6b33813e41d98d4210dbca18e5de8c8fad6
+Author: David Sommerseth <davids@redhat.com>
+Date: Wed May 13 18:30:58 2009 +0200
-------------------------------------------------------------------------
-r141 | nima | 2008-12-20 08:49:40 -0800 (Sat, 20 Dec 2008) | 2 lines
+ Avoid segfault if XPATH_NODESET do not contain any data
-Removed out-of-place README.
+commit ce4d3eac5a50d25e2821a8aedf09f266b16988fe
+Author: David Sommerseth <davids@redhat.com>
+Date: Wed May 13 18:11:50 2009 +0200
-------------------------------------------------------------------------
-r140 | nima | 2008-12-20 08:47:18 -0800 (Sat, 20 Dec 2008) | 2 lines
+ Added mapping for chassis information
-Hide private data from subversion.
+commit f7ab4ee0a2d1bd0ba32f78dceb1c95b28e313fa6
+Author: David Sommerseth <davids@redhat.com>
+Date: Wed May 13 17:42:11 2009 +0200
-------------------------------------------------------------------------
-r139 | nima | 2008-12-20 08:46:37 -0800 (Sat, 20 Dec 2008) | 2 lines
+ Added mapping for ProcessorInfo
-Remove private memory dumps.
+commit 94e81cb43908f90ccdeca4d7d459172999d4ae90
+Author: David Sommerseth <davids@redhat.com>
+Date: Wed May 13 17:39:33 2009 +0200
-------------------------------------------------------------------------
-r138 | nima | 2008-12-20 08:45:39 -0800 (Sat, 20 Dec 2008) | 4 lines
+ Big rewrite of xmlpythonizer
+
+ - Supports relative XPaths now by using the rootpath attribute in the
+ Map tag. This path is then set for all elements inside this Map tag.
+
+ - Rewrote the parser to recurse correctly. The former version did not
+ recurse well on the very outer (first) Map level.
-Added missing info to copyright file.
+commit 40cd1a7ac2f912eb8be659a0c9dbadf5a0b22f14
+Author: David Sommerseth <davids@redhat.com>
+Date: Wed May 13 17:22:04 2009 +0200
-Source creation target.
+ Mark CPU as Populated = 'No' when not present
-------------------------------------------------------------------------
-r137 | nima | 2008-12-20 08:26:43 -0800 (Sat, 20 Dec 2008) | 2 lines
+commit 03bdcc92ff93e58a9befa5c9439b0cd656e57ccc
+Author: David Sommerseth <davids@redhat.com>
+Date: Wed May 13 11:44:15 2009 +0200
-Cleanup.
+ Add all CPU flags, and mark them as available or not
+
+ This is to preserve backwards compatibility
-------------------------------------------------------------------------
-r136 | nima | 2008-12-20 07:49:18 -0800 (Sat, 20 Dec 2008) | 4 lines
+commit ff78802fb52fe6404d12cbde3037371b69d05c03
+Author: David Sommerseth <davids@redhat.com>
+Date: Wed May 13 11:23:17 2009 +0200
-Handle cases where user asks for invalid types.
+ Fixed segfault when processing XPATH_NODESET type and the nodeset is NULL
-Updated test cases to test for this too.
+commit baf01ef0ad9635e506171d66c0e7ffa8c8c45ae1
+Author: David Sommerseth <davids@redhat.com>
+Date: Wed May 13 11:22:47 2009 +0200
-------------------------------------------------------------------------
-r135 | nima | 2008-12-20 07:32:30 -0800 (Sat, 20 Dec 2008) | 6 lines
+ Corrected minor errors in ProcessorInfo XML tags
-Version information now set once during init().
+commit 1ccdf74b1e537c4bd747c079530a5d9ea904e138
+Author: David Sommerseth <davids@redhat.com>
+Date: Mon May 4 10:39:02 2009 +0200
-Bettered test cases.
+ Improved error handling when parsing mapping XML
-Case 127 magically fixed.
+commit aad6b79d7363ea4fa1c1ce67a39848b13bdd19f4
+Author: David Sommerseth <davids@redhat.com>
+Date: Mon May 4 09:32:19 2009 +0200
-------------------------------------------------------------------------
-r134 | nima | 2008-12-19 17:46:42 -0800 (Fri, 19 Dec 2008) | 2 lines
+ Fixed typo in config.h - error in pythonmap.xml filename
-Debian specific target.
+commit 1bf1da9fa4ad24148fe18c1c5baa9a4ec931402c
+Author: David Sommerseth <davids@redhat.com>
+Date: Thu Apr 30 19:38:25 2009 +0200
-------------------------------------------------------------------------
-r133 | nima | 2008-12-19 17:44:55 -0800 (Fri, 19 Dec 2008) | 8 lines
+ Improved setting of pythonmap.xml
+
+ The default file is now set to /usr/share/python-dmidecode/pythonmap.xml
+ (defined in config.h) and can be overridden with the dmidecode.pythonmap()
+ function in Python.
-Removed "detected" from appearing in every single function call. TODO: An ivar
-should be implemented to return this string, so further cleanup is still
-required; as it stands, there is no access to this information anymore!
+commit 89d2c50a648e3affd81ceb24e332bbd60de2b75d
+Author: David Sommerseth <davids@redhat.com>
+Date: Thu Apr 30 19:18:17 2009 +0200
-Updated test case.
+ Fixed a bug causing segv
+
+ When calling dmidecode_get_xml(...) several times could cause a crash
+ due to the opt.dmiversion_n pointer being freed by a mistake when the
+ generated dmixml_n got freed later on in the function.
+
+ Also fixed an assertion typo
-Further general cleanup.
+commit 268687f5b525ce4bdb1becd5a5207bfc2ced8340
+Author: Nima Talebi <nima@autonomy.net.au>
+Date: Tue Apr 28 00:55:28 2009 +1000
-------------------------------------------------------------------------
-r132 | nima | 2008-12-19 15:55:53 -0800 (Fri, 19 Dec 2008) | 4 lines
+ Version number fix
-Further testing shows that the segfault does not occur when the device is
-/dev/mem, but does so for all images (where requested type is 127), suggesting
-that the problem could be with the image or surrounding processes.
+commit 27b3d2281f4b7677e908ef2505bd649305b5ac78
+Author: David Sommerseth <davids@redhat.com>
+Date: Thu Apr 30 18:24:49 2009 +0200
-------------------------------------------------------------------------
-r131 | nima | 2008-12-19 15:46:46 -0800 (Fri, 19 Dec 2008) | 2 lines
+ Began completing the rewrite of needed dmidecodemodule changes
+
+commit cea1270777d0a5bd42284011307fe183a67f8ada
+Author: David Sommerseth <davids@redhat.com>
+Date: Thu Apr 30 16:07:43 2009 +0200
+
+ Rewritten dmixml_GetXPathContent(...) and _get_key_value(...)
+
+ This rewrite was to handle XPATH_NUMBER more correctly. Now these
+ functions needs an preallocated memory buffer for the result.
+
+commit 6453a1131547b71c4a21a978fd9588d67d056233
+Author: David Sommerseth <davids@redhat.com>
+Date: Wed Apr 29 18:42:12 2009 +0200
+
+ Completed mapping the bios section
+
+commit 2aaa3c0822bff7204167f73b62035bc10f620881
+Author: David Sommerseth <davids@redhat.com>
+Date: Wed Apr 29 18:32:57 2009 +0200
+
+ Reimplemented the XPath integration
+
+ Now the XPath expressions can include XPath functions as well. The
+ previous implementation only supported XPATH_NODESET results from
+ XPath queries. Now XPATH_STRING and XPATH_NUMBER results are
+ supported as well. XPATH_BOOLEAN might be needed later on.
+
+commit d64ab66e4fbf8d6dfceed628aef21f01063c3d66
+Author: David Sommerseth <davids@redhat.com>
+Date: Wed Apr 29 18:29:50 2009 +0200
+
+ Added function for retrieving values from XPath objects
+
+ Reverted commit 75aaf67d43cf4a28fe8d3e07111dab75a0c4396d in addition
+
+commit a3047723df9b66b6a56bcc72a469a129bbaf4d54
+Author: David Sommerseth <davids@redhat.com>
+Date: Wed Apr 29 18:28:02 2009 +0200
+
+ dmidecode: Moved ROMsize size unit into tag attribute
+
+commit 6a89cde8f253cb9826da4287007a869de99709a6
+Author: David Sommerseth <davids@redhat.com>
+Date: Wed Apr 29 13:09:07 2009 +0200
+
+ Filter out BIOS characteristics with XPath expressions
+
+commit 7cf8017a95f04d6207ae3bbf923c8be5d873f6a1
+Author: David Sommerseth <davids@redhat.com>
+Date: Wed Apr 29 13:07:16 2009 +0200
+
+ Revert "Added filter and filtervalue attributes to xmlpythonizer's <Map> tags"
+
+ This reverts commit 4b925a1433b65c217e787804df3cf349d6b387aa.
+
+ Discovered that XPath got the needed power for filtering, no need for
+ this extra feature
+
+commit c6baf0a8f50cc19f319ad13ceeb2c40ace0b4d7e
+Author: David Sommerseth <davids@redhat.com>
+Date: Wed Apr 29 11:18:57 2009 +0200
+
+ Exported ptzmap_Free()
+
+commit e013d57e504c4e989c0503e62b63369bb16ebdaf
+Author: David Sommerseth <davids@redhat.com>
+Date: Tue Apr 28 19:12:25 2009 +0200
+
+ Added pythonmap.xml - default XML -> Python mapping setup
+
+ Only added mapping for the 'bios' section.
+
+commit 4b925a1433b65c217e787804df3cf349d6b387aa
+Author: David Sommerseth <davids@redhat.com>
+Date: Tue Apr 28 19:10:45 2009 +0200
+
+ Added filter and filtervalue attributes to xmlpythonizer's <Map> tags
+
+ Using these attributes, only XML data (from the given XPath in 'filter')
+ which matches the value in 'filtervalue' will be added to the Python
+ data.
+
+commit 11691f4b5e5786878cca1d30b183103477d5311f
+Author: David Sommerseth <davids@redhat.com>
+Date: Tue Apr 28 16:58:33 2009 +0200
+
+ Updated xmlpythonizer to support boolean type and dynamic XPath keys
+
+ * Added support boolean and list:boolean value types
+
+ * Traversing child nodes and having dynamic keys
+ Now it is possible to do the following:
+
+ ** test.xml **
+ <?xml version="1.0" encoding="UTF-8"?>
+ <testdata>
+ <list>
+ <value enabled="1">Option 1</value>
+ <value enabled="0">Option 2</value>
+ <value enabled="1">Option 3</value>
+ </list>
+ </testdata>
+
+ ** mapping.xml **
+ <?xml version="1.0" encoding="UTF-8"?>
+ <dmidecode_fieldmap version="1">
+ <Mapping name="example">
+ <Map keytype="string" key="/testdata/list/value"
+ valuetype="boolean" value="/testdata/list/value/@enabled"/>
+ </Mapping>
+ </dmidecode_fieldmap>
+
+ Which should result in:
+
+ {'Option 1': True, 'Option 2': False, 'Option 3': True'}
+
+commit c7be629d44d4e2be6c8116796714e0042a977885
+Author: David Sommerseth <davids@redhat.com>
+Date: Tue Apr 28 11:12:58 2009 +0200
+
+ Added generic XML -> Python parser
+
+ The xmlpythonizer module will convert any XML data (xmlNode
+ or xmlDoc) and format it as a Python object. The formatting is
+ defined in it's own XML file.
+
+ Basic format:
+ <dmidecode_fieldmap version="1">
+ <Mapping name="{name of mapping table}">
+ <Map keytype="{key type}" key="{key value}"
+ valuetype="{value type} value="{value}"/>
+ </Mapping>
+ </dmidecode_fieldmap>
+
+ The keytype and key attributes defines the key in the Python Dict. The
+ root element will always be a Python Dict structure. The valid key types
+ are:
+ * constant
+ Uses the value in {key} as the key value
+
+ * string, integer, float
+ Uses a string value from the data XML to be converted to Python. The
+ value set in the key attribute defines an XPath value which points to the
+ data to be used as a Python dict key.
+
+ Since Python only supports C strings in the C interface for Python dict
+ keys, integer and float will be treated as strings.
+
+ The valuetype and value attributes are similar to the keys, but with some more
+ features. Valid valuetypes are:
+
+ * constant
+ The value given in the value attribute will be used in the value in
+ the Python result.
+
+ * string, integer, float
+ The value given in the value attribute defines the XPath to the data XML,
+ of where to retrieve the value for the given key.
+
+ The valuetype defines if the data should be understood as a string, integer
+ or float in the Python result.
+
+ * list:string, list:integer, list:float
+ This does the same as the string, integer or float type, with a tweak. The
+ data will be put into a list. If the XPath given returns multiple nodes,
+ all of them will be added to this list.
+
+ * dict
+ The dict valuetype is more special. It should not contain any value
+ attribute. On the other hand, it should contain a sub-level of <Map> tags.
+ In this way, you can build up a multi dimensional Python dict.
+
+ Example:
+
+ ** pythonmap.xml **
+ <?xml version="1.0" encoding="UTF-8"?>
+ <dmidecode_fieldmap version="1">
+ <Mapping name="example_map">
+ <Map keytype="constant" key="DemoCase" valuetype="constant" value="XML Pythonizing"/>
+ <Map keytype="constant" key="String1" valuetype="string" value="/example/string1"/>
+ <Map keytype="constant" key="AttribString1" valuetype="integer" value="/example/string1/@int_value"/>
+ <Map keytype="string" key="/example/keyset/@value" valuetype="dict">
+ <Map keytype="constant" key="Value1" valuetype="string" value="/example/keyset/value1"/>
+ <Map keytype="constant" key="ValueList" valuetype="list:string" value="/example/keyset/valuelist"/>
+ </Map>
+ </Mapping>
+ </dmidecode_fieldmap>
+
+ ** exampledata.xml **
+ <?xml version="1.0" encoding="UTF-8"?>
+ <example>
+ <string1 int_value="1234">String value #1</string1>
+ <keyset value="TestData">
+ <value1>More test data</value1>
+ <valuelist>Value1 in list</valuelist>
+ <valuelist>Value2 in list</valuelist>
+ <valuelist>Value3 in list</valuelist>
+ </keyset>
+ </example>
+
+ ** C code snippet **
+
+ void xmlpythonizer() {
+ xmlDoc *xmlmap = NULL;
+ xmlDoc *xmldata = NULL;
+ ptzMAP *mapping = NULL;
+ PyObject *pythondata = NULL;
+
+ // Read XML files
+ xmlmap = xmlReadFile("pythonmap.xml", NULL, 0);
+ xmldata = xmlReadFile("exampledata.xml", NULL, 0);
+
+ // Parse the mapping XML
+ mapping = dmiMAP_ParseMappingXML(xmlmap, "example_map");
+
+ // Parse the xmldata into a Python object
+ pythondata = pythonizeXMLdoc(mapping, xmldata);
+
+ // ..... the program continues to do something useful
+ }
+
+ The result stored inside the pythondata object should now be
+ something similar to:
+
+ {'DemoCase': 'XML Pythonizing',
+ 'String1': 'String value #1',
+ 'AttribString1: 1234,
+ 'TestData': {'Value1': 'More test data',
+ 'ValueList': ['Value1 in list','Value2 in list','Value3 in list']}
+ }
+
+commit 70e35765fbb9be6ddd6aab6555916777a593e0aa
+Author: David Sommerseth <davids@redhat.com>
+Date: Tue Apr 28 11:07:51 2009 +0200
+
+ Only consider XML nodes which is of XML_ELEMENT_NODE when finding a specific node
+
+commit 75aaf67d43cf4a28fe8d3e07111dab75a0c4396d
+Author: David Sommerseth <davids@redhat.com>
+Date: Fri Apr 24 17:09:41 2009 +0200
+
+ Don't return NULL in dmixml_GetContent(...)
+
+commit 0af6d685a83d7c060de52717859e00104bc7c4b8
+Author: David Sommerseth <davids@redhat.com>
+Date: Tue Apr 14 14:22:09 2009 +0200
+
+ Fixed compiler error due to API changes
+
+ This fixes a regression from commit 7f0fa9b2e1afd6aecea0b34b62cf9ebdf075164d
+
+commit 8c5015cfd169bbec89974e57b04da3985425e6cd
+Author: David Sommerseth <davids@redhat.com>
+Date: Tue Apr 14 14:21:48 2009 +0200
+
+ More XML cleanup
+
+commit 38c943db697b13e5f9be020a0729f58b7366e932
+Author: David Sommerseth <davids@redhat.com>
+Date: Fri Apr 10 13:52:47 2009 +0200
+
+ Cleaned up the XML data
+
+commit 62f276eea2d8477854d7fe9b230a957a8df4102c
+Author: David Sommerseth <davids@redhat.com>
+Date: Fri Apr 10 13:51:01 2009 +0200
+
+ Do not add XML values if input is "(null)"
+
+commit b8bcbc709a3bdb5ee1e59e22d5e54c59f391165f
+Author: David Sommerseth <davids@redhat.com>
+Date: Fri Apr 10 13:38:52 2009 +0200
+
+ Added right trim of xml data
+
+commit 92ea3b07784853558d93391dbc364c69463cd61d
+Author: David Sommerseth <davids@redhat.com>
+Date: Fri Apr 10 11:28:41 2009 +0200
+
+ Fixed wrong string handling of DMI data, which caused SEGV
+
+commit 46988f9abcec9eb072be5f5d52fc594de89478e8
+Author: David Sommerseth <davids@redhat.com>
+Date: Thu Apr 9 15:13:23 2009 +0200
+
+ Added more XML functions
-Oops - fixed.
+commit 8b2fe610dc309579f07787696f0814c359aa4de1
+Author: David Sommerseth <davids@redhat.com>
+Date: Thu Apr 9 14:51:31 2009 +0200
-------------------------------------------------------------------------
-r130 | nima | 2008-12-19 15:45:55 -0800 (Fri, 19 Dec 2008) | 3 lines
+ Added missing copyright details
-Test case is close to complete, type 127 results in a segfault - (test case
-is serving its purpose).
+commit 95b156e3d8a6b82bddb5516735e82355f5dee50a
+Author: David Sommerseth <davids@redhat.com>
+Date: Thu Apr 9 12:12:56 2009 +0200
-------------------------------------------------------------------------
-r129 | nima | 2008-12-19 15:29:50 -0800 (Fri, 19 Dec 2008) | 3 lines
+ Removed all Python dependencies in dmidecode.[ch]
-Adding an image from parallel's desktop running Debian lenny, and another for
-a physical server also running Debian. Both are intel 32 bit.
+commit 581b015c91a3b364b1c1324bed775bfd2ce99dbd
+Author: David Sommerseth <davids@redhat.com>
+Date: Thu Apr 9 11:49:50 2009 +0200
-------------------------------------------------------------------------
-r128 | nima | 2008-12-19 15:27:10 -0800 (Fri, 19 Dec 2008) | 4 lines
+ Made it compile
-More work on test case.
+commit 612445e94781f14af65490b52c898b9eaa5f5e85
+Author: David Sommerseth <davids@redhat.com>
+Date: Wed Apr 8 19:02:03 2009 +0200
-Updated setup.py to reflect new version.
+ Ported most functions to XML interface
+
+ Still do not compile
-------------------------------------------------------------------------
-r127 | nima | 2008-12-19 05:49:19 -0800 (Fri, 19 Dec 2008) | 2 lines
+commit 0cdb1cbffae8237635b991993ee4467e2753dafa
+Author: David Sommerseth <davids@redhat.com>
+Date: Tue Apr 7 09:27:47 2009 +0200
-More testing and fixes.
+ Checked in a work in progress - Python dict -> XML
+ Does not compile yet
-------------------------------------------------------------------------
-r126 | nima | 2008-12-19 05:42:10 -0800 (Fri, 19 Dec 2008) | 2 lines
+commit a35afd0190f6a6925aa134ac43d2653aaf018ff8
+Author: David Sommerseth <davids@redhat.com>
+Date: Fri Apr 3 14:50:02 2009 +0200
-Improved test case.
+ Fixed wrong xmlAttrNode type to xmlAttr
-------------------------------------------------------------------------
-r125 | nima | 2008-12-19 05:32:35 -0800 (Fri, 19 Dec 2008) | 2 lines
+commit 2ed8a0e7cb6cbdeec1c1c49e7aedf03188e72017
+Author: David Sommerseth <davids@redhat.com>
+Date: Thu Apr 2 19:27:30 2009 +0200
-Removed a printf() comment.
+ Modified setup.py to compile in dmixml.c and link against libxml2
-------------------------------------------------------------------------
-r124 | nima | 2008-12-19 05:21:24 -0800 (Fri, 19 Dec 2008) | 6 lines
+commit 1da04aa097db78c7474877049334c2c07b33bda1
+Author: David Sommerseth <davids@redhat.com>
+Date: Thu Apr 2 19:26:56 2009 +0200
-Check that the path given with set_dev() is writeable.
+ Added dmixml.[ch] - helper function for generating XML nodes
-Don't crash when writing to a read-only file, return False instead.
+commit 805dced32cbb2eef1f2b639100faef3bb0482e29
+Author: David Sommerseth <davids@redhat.com>
+Date: Wed Apr 1 16:10:55 2009 +0200
-Missing an INCREF in get_dev() fixed.
+ Added indenting tool for C code and reindented *.[ch] files
-------------------------------------------------------------------------
-r123 | nima | 2008-12-19 03:56:39 -0800 (Fri, 19 Dec 2008) | 2 lines
+commit 764717bd15eeaa0c6cbed39a8b674dad406e57f9
+Author: Nima Talebi <nima@autonomy.net.au>
+Date: Fri Apr 17 21:41:34 2009 +1000
-Test for write permission prior to write attempts.
+ Converting to pysupport from pycentral
-------------------------------------------------------------------------
-r122 | nima | 2008-12-19 01:02:52 -0800 (Fri, 19 Dec 2008) | 2 lines
+commit d8aecc31dd70d0286258aeac3f5ca0adb51a9add
+Author: Nima Talebi <nima@autonomy.net.au>
+Date: Fri Apr 17 21:40:55 2009 +1000
-Fixed watch file.
+ Converting to pysupport from pycentral.
-------------------------------------------------------------------------
-r121 | nima | 2008-12-18 21:05:38 -0800 (Thu, 18 Dec 2008) | 4 lines
+commit 69dfdaee01c89096e76fbd8db9531d759d43e7c2
+Author: Nima Talebi <nima@autonomy.net.au>
+Date: Fri Apr 17 20:34:04 2009 +1000
-Received ITP auto-ack: #509169.
+ Testing git push
-More debianizing cleanup.
+commit f6a5c9a497fe10ff61399e640973fa396aa0b425
+Author: Nima Talebi <nima@epenguin1-3.appmgmt.det.nsw.edu.au>
+Date: Fri Apr 17 10:36:21 2009 +1000
-------------------------------------------------------------------------
-r120 | nima | 2008-12-18 20:13:24 -0800 (Thu, 18 Dec 2008) | 2 lines
+ Wrapped long lines
-Cleanup.
+commit 7788d30989f2bafca2aacda198947c1841e420a3
+Author: Nima Talebi <nima@epenguin1-3.appmgmt.det.nsw.edu.au>
+Date: Tue Apr 14 19:08:51 2009 +1000
-------------------------------------------------------------------------
-r119 | nima | 2008-12-18 20:07:06 -0800 (Thu, 18 Dec 2008) | 3 lines
+ Small cleanup change
-Further work in enforcing the Debian policy in package based on advice from
-`POX' and the documentation.
+commit 521af88003aef1af0118f2414c550e2762e4d94c
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Tue Mar 31 11:42:58 2009 +0000
-------------------------------------------------------------------------
-r118 | nima | 2008-12-18 18:23:32 -0800 (Thu, 18 Dec 2008) | 2 lines
+ Cleanup.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@181 abc39116-655e-4be6-ad55-d661dc543056
-Removed junk and doing more debianizing - WIP.
+commit d7200d96d5b90bcd0013c84ec1b053acbcca86c9
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Tue Mar 31 11:42:38 2009 +0000
-------------------------------------------------------------------------
-r117 | nima | 2008-12-18 05:49:57 -0800 (Thu, 18 Dec 2008) | 2 lines
+ Reverting recent (pointless) change.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@180 abc39116-655e-4be6-ad55-d661dc543056
-Updated.
+commit 37d1a8117cd212ee9e47bbd4225ba76dece7dad7
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Tue Mar 31 11:37:58 2009 +0000
-------------------------------------------------------------------------
-r116 | nima | 2008-12-18 05:48:52 -0800 (Thu, 18 Dec 2008) | 6 lines
+ Preparing to migrate to GIT.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@179 abc39116-655e-4be6-ad55-d661dc543056
-The dmidecode.type() call not takes ints, not strings.
+commit 17cfe3a41998c075991a54a6deace28ba7744ed6
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Tue Mar 10 01:53:51 2009 +0000
-Adding an example directory.
+ Fixes.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@178 abc39116-655e-4be6-ad55-d661dc543056
-Adding test case.
+commit f60a804e9d0bb4be0a2a7c37819f4deb64eb0535
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sun Mar 8 13:49:21 2009 +0000
-------------------------------------------------------------------------
-r115 | nima | 2008-12-18 05:45:37 -0800 (Thu, 18 Dec 2008) | 4 lines
+ Releasing v2.10.4.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@177 abc39116-655e-4be6-ad55-d661dc543056
-The dmidecode.type() call not takes ints, not strings.
+commit f3cc6c86366af6df0c6320100b86bcdf404ba3ae
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sun Mar 8 11:32:42 2009 +0000
-Adding an example directory.
-
-------------------------------------------------------------------------
-r114 | nima | 2008-12-17 17:12:50 -0800 (Wed, 17 Dec 2008) | 5 lines
-
-More upstream changes implemented, see CHANGELOG by Jean Delvare from the
-period 2008-02-16 to 2008-11-23.
-
-These changes have been made, but not yet fully tested.
-
-------------------------------------------------------------------------
-r113 | nima | 2008-12-17 05:26:57 -0800 (Wed, 17 Dec 2008) | 5 lines
-
-Claim to support revision 32 of Intel AP-485 (CPUID). No relevant change since
-revision 31.
-
-Update reference to AMD CPUID document.
-
-------------------------------------------------------------------------
-r112 | nima | 2008-12-17 05:11:35 -0800 (Wed, 17 Dec 2008) | 2 lines
-
-Handle chassis information records of size 19 (DMI type 3).
-
-------------------------------------------------------------------------
-r111 | nima | 2008-12-17 05:00:12 -0800 (Wed, 17 Dec 2008) | 2 lines
-
-And the debian subfolder itself...
-
-------------------------------------------------------------------------
-r110 | nima | 2008-12-17 04:59:32 -0800 (Wed, 17 Dec 2008) | 2 lines
-
-Debianizing dmidecode.
-
-------------------------------------------------------------------------
-r109 | nima | 2008-12-16 23:30:04 -0800 (Tue, 16 Dec 2008) | 2 lines
-
-Adding spec file written by Joel Heenan.
-
-------------------------------------------------------------------------
-r108 | nima | 2008-12-16 23:20:56 -0800 (Tue, 16 Dec 2008) | 2 lines
-
-Cleaning up source area, ready for debianizing, and rpm after that.
-
-------------------------------------------------------------------------
-r107 | nima | 2008-10-31 07:45:34 -0700 (Fri, 31 Oct 2008) | 2 lines
-
-Changed default target of Makefile back to `setup.py' method of installation.
-
-------------------------------------------------------------------------
-r106 | nima | 2008-10-31 07:41:02 -0700 (Fri, 31 Oct 2008) | 2 lines
-
-Cleanup.
-
-------------------------------------------------------------------------
-r105 | nima | 2008-10-31 07:33:03 -0700 (Fri, 31 Oct 2008) | 3 lines
-
-This commit closes #2 reported by Justin Cook, the ticket will remain open
-until Justin confirms this however.
-
-------------------------------------------------------------------------
-r104 | nima | 2008-10-31 07:07:22 -0700 (Fri, 31 Oct 2008) | 6 lines
-
-Implemented reading a dump to - this concludes syncing to the upstream release.
-
-Next, exceptions should be thrown in certain places, more error checking in the
-python side of things, and also in relation to setting and unsetting of the
-alternate memory file.
-
-------------------------------------------------------------------------
-r103 | nima | 2008-10-31 06:42:35 -0700 (Fri, 31 Oct 2008) | 2 lines
-
-Cleanup.
-
-------------------------------------------------------------------------
-r102 | nima | 2008-10-31 06:38:24 -0700 (Fri, 31 Oct 2008) | 3 lines
-
-Fixed dump. The `offset' problem was not really an offset problem - it was a
-silly typo.
-
-------------------------------------------------------------------------
-r101 | nima | 2008-10-31 06:24:04 -0700 (Fri, 31 Oct 2008) | 2 lines
-
-Missed two lines.
-
-------------------------------------------------------------------------
-r100 | nima | 2008-10-31 06:19:50 -0700 (Fri, 31 Oct 2008) | 3 lines
-
-Dump-to-file is almost working, there seems to be a 4-byte misalignment in the
-produced file though for now - needs to be fixed.
-
-------------------------------------------------------------------------
-r99 | nima | 2008-10-31 04:43:15 -0700 (Fri, 31 Oct 2008) | 2 lines
-
-Removed junk comments.
-
-------------------------------------------------------------------------
-r98 | nima | 2008-10-31 04:21:24 -0700 (Fri, 31 Oct 2008) | 2 lines
-
-Cleanup.
-
-------------------------------------------------------------------------
-r97 | nima | 2008-10-31 04:15:19 -0700 (Fri, 31 Oct 2008) | 2 lines
-
-Cleanup.
-
-------------------------------------------------------------------------
-r96 | nima | 2008-10-31 03:24:41 -0700 (Fri, 31 Oct 2008) | 2 lines
-
-Cleanup.
-
-------------------------------------------------------------------------
-r95 | nima | 2008-10-31 02:05:23 -0700 (Fri, 31 Oct 2008) | 6 lines
-
-Integration of required `dmiopt.h' bits.
-Removed QUIETness code.
-Other cleanups.
-Added get/set methods for changinf the default /dev/mem device.
-
-
-------------------------------------------------------------------------
-r94 | nima | 2008-10-31 02:02:21 -0700 (Fri, 31 Oct 2008) | 2 lines
-
-Removed traces of `_' and integrating required bits from dmiopt.h.
-
-------------------------------------------------------------------------
-r93 | nima | 2008-10-31 02:01:41 -0700 (Fri, 31 Oct 2008) | 2 lines
-
-Removed traces of `_'.
-
-------------------------------------------------------------------------
-r92 | nima | 2008-10-31 02:00:26 -0700 (Fri, 31 Oct 2008) | 2 lines
-
-Integrating the required bits from dmiopt into dmihelper.
-
-------------------------------------------------------------------------
-r91 | nima | 2008-10-31 01:39:12 -0700 (Fri, 31 Oct 2008) | 4 lines
-
-Removed `_' buffer.
-Removed use of `FLAGS_QUIET' as it makes no sense for a module.
-Removed the `submain()' function.
-
-------------------------------------------------------------------------
-r90 | nima | 2008-10-31 01:30:00 -0700 (Fri, 31 Oct 2008) | 2 lines
-
-Cleanup.
-
-------------------------------------------------------------------------
-r89 | nima | 2008-10-31 01:29:06 -0700 (Fri, 31 Oct 2008) | 2 lines
-
-Removed dependency on dmiopt.
-
-------------------------------------------------------------------------
-r88 | nima | 2008-10-31 01:28:33 -0700 (Fri, 31 Oct 2008) | 2 lines
-
-Removed verbose printout.
-
-------------------------------------------------------------------------
-r87 | nima | 2008-10-30 03:14:24 -0700 (Thu, 30 Oct 2008) | 2 lines
-
-Removed final traces of the `_' buffer.
-
-------------------------------------------------------------------------
-r86 | nima | 2008-10-29 19:11:56 -0700 (Wed, 29 Oct 2008) | 2 lines
-
-Implementing (incomplete) upstream changes.
-
-------------------------------------------------------------------------
-r85 | nima | 2008-10-29 00:15:35 -0700 (Wed, 29 Oct 2008) | 2 lines
-
-Cleanup.
-
-------------------------------------------------------------------------
-r84 | nima | 2008-10-29 00:13:49 -0700 (Wed, 29 Oct 2008) | 5 lines
-
-Adding man pages from upstream. Sooner or later, these will be removed, as will
-all other work that's simply replicating the demidecode binary. All this
-package should provide is the python module, and some py-module-specific man
-pages.
-
-------------------------------------------------------------------------
-r83 | nima | 2008-10-29 00:10:24 -0700 (Wed, 29 Oct 2008) | 4 lines
-
-Recoded the new work from upstream into these (main) files. The options to
-dump the memory image onto file, and read back from it has not yet been
-worked in, but the underlying work has been completed.
-
-------------------------------------------------------------------------
-r82 | nima | 2008-10-29 00:09:10 -0700 (Wed, 29 Oct 2008) | 3 lines
-
-Tested new dmidecode python module with this example file. A real test case
-will be implemented sometime in future.
-
-------------------------------------------------------------------------
-r81 | nima | 2008-10-29 00:07:56 -0700 (Wed, 29 Oct 2008) | 2 lines
-
-Cleanup.
-
-------------------------------------------------------------------------
-r80 | nima | 2008-10-29 00:07:13 -0700 (Wed, 29 Oct 2008) | 2 lines
-
-Cleanup.
-
-------------------------------------------------------------------------
-r79 | nima | 2008-10-29 00:06:47 -0700 (Wed, 29 Oct 2008) | 2 lines
-
-Using dmihelper now.
-
-------------------------------------------------------------------------
-r78 | nima | 2008-10-29 00:05:58 -0700 (Wed, 29 Oct 2008) | 2 lines
-
-Upstream.
-
-------------------------------------------------------------------------
-r77 | nima | 2008-10-29 00:04:19 -0700 (Wed, 29 Oct 2008) | 2 lines
-
-Upstream.
-
-------------------------------------------------------------------------
-r76 | nima | 2008-10-29 00:04:03 -0700 (Wed, 29 Oct 2008) | 2 lines
-
-Cleanup.
-
-------------------------------------------------------------------------
-r75 | nima | 2008-10-28 23:36:23 -0700 (Tue, 28 Oct 2008) | 2 lines
-
-Renamed to a more appropriate name.
-
-------------------------------------------------------------------------
-r74 | nima | 2008-10-28 23:35:21 -0700 (Tue, 28 Oct 2008) | 3 lines
-
-Committing new dmidecode helper functions, and next, renaming it to a
-meaningful name.
-
-------------------------------------------------------------------------
-r73 | nima | 2008-10-28 23:27:31 -0700 (Tue, 28 Oct 2008) | 3 lines
-
-Synced to the latest from upstream, with a light modification required for the
-module.
-
-------------------------------------------------------------------------
-r72 | nima | 2008-10-18 02:34:09 -0700 (Sat, 18 Oct 2008) | 5 lines
-
-Python does not have unsigned integers, hence %u and %lu in printf style
-strings are taken to be literal strings, not space-holders. All occurences
-of '%u' (78) have been amended to '%i', there was no '%lu'.
-
-
-------------------------------------------------------------------------
-r71 | nima | 2008-10-18 02:28:46 -0700 (Sat, 18 Oct 2008) | 4 lines
-
-Fixed bug reported by by Justin Cook, where dmidecode.type() would segfault.
-It turned out to be some code that was forgotten about during the conversion, or
-at least very incomplete and wrong.
-
-------------------------------------------------------------------------
-r70 | nima | 2008-10-16 08:52:48 -0700 (Thu, 16 Oct 2008) | 2 lines
-
-Remove efence.
-
-------------------------------------------------------------------------
-r69 | nima | 2008-09-04 20:08:02 -0700 (Thu, 04 Sep 2008) | 2 lines
-
-Fixed a bug that crashed dmidecode.slot().
-
-------------------------------------------------------------------------
-r68 | nima | 2008-09-03 23:09:55 -0700 (Wed, 03 Sep 2008) | 5 lines
-
-Cleaning up of the dmidecode module, mostly conversion of things that can be
-Python `None's or `Int's but were `String'.
-
-Replaced a meaningless int dictionary key to `data'.
-
-------------------------------------------------------------------------
-r67 | nima | 2008-09-03 19:26:09 -0700 (Wed, 03 Sep 2008) | 3 lines
-
-Work on CPU details - seemed to been a bug with appending to a string rather
-than rewriting it.
-
-------------------------------------------------------------------------
-r66 | nima | 2008-08-08 07:15:47 -0700 (Fri, 08 Aug 2008) | 4 lines
-
-Replaced `%X' with `%x'.
-
-Logic cleanup - Put the `Handle' info back into the dictionary.
-
-------------------------------------------------------------------------
-r65 | nima | 2008-08-08 00:57:44 -0700 (Fri, 08 Aug 2008) | 2 lines
-
-Anoher bug fix, this time in baseboard.
-
-------------------------------------------------------------------------
-r64 | nima | 2008-08-08 00:27:36 -0700 (Fri, 08 Aug 2008) | 3 lines
-
-Fixed many major bugs (all of which were expected based on the way we mass
-converted all the `case' blocks.
-
-------------------------------------------------------------------------
-r63 | nima | 2008-08-07 05:32:39 -0700 (Thu, 07 Aug 2008) | 2 lines
-
-Cleaned up a little.
-
-------------------------------------------------------------------------
-r62 | nima | 2008-08-06 18:34:15 -0700 (Wed, 06 Aug 2008) | 2 lines
-
-Fixed some conversion bits missed during last night.
-
-------------------------------------------------------------------------
-r61 | nima | 2008-08-06 06:32:37 -0700 (Wed, 06 Aug 2008) | 2 lines
-
-Updated authors file with developers of the dmidecode python module.
-
-------------------------------------------------------------------------
-r60 | nima | 2008-08-06 06:27:26 -0700 (Wed, 06 Aug 2008) | 2 lines
-
-Changed to GNU GPL v3 License.
-
-------------------------------------------------------------------------
-r59 | nima | 2008-08-06 05:59:03 -0700 (Wed, 06 Aug 2008) | 2 lines
-
-Removed `sudo'.
-
-------------------------------------------------------------------------
-r58 | nima | 2008-08-06 05:52:46 -0700 (Wed, 06 Aug 2008) | 4 lines
-
-Completed `case 126', thought to have been completed in previous commit.
-
-Some housekeeping elsewhere.
-
-------------------------------------------------------------------------
-r57 | nima | 2008-08-06 01:51:05 -0700 (Wed, 06 Aug 2008) | 4 lines
-
-Completed all conversions! Only problem now is of course finding all the memory
-leaks and introduced logic errors which (confirmed) do exists - use valgrind and
-see.
-
-------------------------------------------------------------------------
-r56 | vwhitteron | 2008-08-06 01:29:18 -0700 (Wed, 06 Aug 2008) | 1 line
-
-Completed `Case 34' through `Case 39'
-------------------------------------------------------------------------
-r55 | nima | 2008-08-06 01:12:43 -0700 (Wed, 06 Aug 2008) | 2 lines
-
-Almost there!
-
-------------------------------------------------------------------------
-r54 | vwhitteron | 2008-08-06 00:49:23 -0700 (Wed, 06 Aug 2008) | 1 line
-
-Completed `Case 29' and `Case 32'
-------------------------------------------------------------------------
-r53 | nima | 2008-08-06 00:42:34 -0700 (Wed, 06 Aug 2008) | 2 lines
-
-Converted `case 30'.
-
-------------------------------------------------------------------------
-r52 | vwhitteron | 2008-08-06 00:40:42 -0700 (Wed, 06 Aug 2008) | 1 line
-
-Completed `Case 26', `Case 27' and `Case 28'
-------------------------------------------------------------------------
-r51 | nima | 2008-08-06 00:30:41 -0700 (Wed, 06 Aug 2008) | 3 lines
-
-Added `PyObject *data;' to all remaining functions which will generate a warning
-as to indicate these need to be converted.
-
-------------------------------------------------------------------------
-r50 | nima | 2008-08-06 00:27:30 -0700 (Wed, 06 Aug 2008) | 2 lines
-
-Completed functions for `csae 28'.
-
-------------------------------------------------------------------------
-r49 | nima | 2008-08-06 00:23:35 -0700 (Wed, 06 Aug 2008) | 2 lines
-
-Completed functions for `case 27', and fixed error in last commit for `case 26'.
-
-------------------------------------------------------------------------
-r48 | nima | 2008-08-06 00:19:27 -0700 (Wed, 06 Aug 2008) | 2 lines
-
-Completed functions for `case 26'.
-
-------------------------------------------------------------------------
-r47 | vwhitteron | 2008-08-06 00:09:11 -0700 (Wed, 06 Aug 2008) | 1 line
-
-Completed `Case 23', `Case 24', `Case24' and `Case 25'
-------------------------------------------------------------------------
-r46 | nima | 2008-08-06 00:07:20 -0700 (Wed, 06 Aug 2008) | 2 lines
-
-Completed functions for `case 25'.
-
-------------------------------------------------------------------------
-r45 | nima | 2008-08-06 00:00:41 -0700 (Wed, 06 Aug 2008) | 2 lines
-
-Converted function for `case 24'.
-
-------------------------------------------------------------------------
-r44 | nima | 2008-08-05 23:59:35 -0700 (Tue, 05 Aug 2008) | 2 lines
-
-More fixes on recent commits (by me), and more conversions on functions.
-
-------------------------------------------------------------------------
-r43 | vwhitteron | 2008-08-05 23:57:13 -0700 (Tue, 05 Aug 2008) | 1 line
-
-Completed `Case 22'
-------------------------------------------------------------------------
-r42 | nima | 2008-08-05 23:53:24 -0700 (Tue, 05 Aug 2008) | 2 lines
-
-Oops. Fixed stupidity on last commit.
-
-------------------------------------------------------------------------
-r41 | nima | 2008-08-05 23:52:01 -0700 (Tue, 05 Aug 2008) | 2 lines
-
-Completed functions called by `case 21' and `case 22'.
-
-------------------------------------------------------------------------
-r40 | nima | 2008-08-05 23:42:54 -0700 (Tue, 05 Aug 2008) | 3 lines
-
-Completed `case 21' functions.
-Cleanup.
-
-------------------------------------------------------------------------
-r39 | vwhitteron | 2008-08-05 23:39:53 -0700 (Tue, 05 Aug 2008) | 2 lines
-
-Completed `case 19' and `case 20'.
-
-------------------------------------------------------------------------
-r38 | nima | 2008-08-05 23:17:21 -0700 (Tue, 05 Aug 2008) | 2 lines
-
-Started on `case 19'.
-
-------------------------------------------------------------------------
-r37 | nima | 2008-08-05 22:43:05 -0700 (Tue, 05 Aug 2008) | 2 lines
-
-Completed `case 18' and `case 19'.
-
-------------------------------------------------------------------------
-r36 | nima | 2008-08-05 22:06:03 -0700 (Tue, 05 Aug 2008) | 2 lines
-
-Added `case 16' and `case 17'.
-
-------------------------------------------------------------------------
-r35 | nima | 2008-08-05 21:26:45 -0700 (Tue, 05 Aug 2008) | 2 lines
-
-Cleanup.
-
-------------------------------------------------------------------------
-r34 | nima | 2008-08-05 21:05:06 -0700 (Tue, 05 Aug 2008) | 2 lines
-
-Converted `case 5', `case 6', and `case 7'.
-
-------------------------------------------------------------------------
-r33 | nima | 2008-08-01 00:59:51 -0700 (Fri, 01 Aug 2008) | 2 lines
-
-Default case set to return python's `None'.
-
-------------------------------------------------------------------------
-r32 | nima | 2008-08-01 00:58:24 -0700 (Fri, 01 Aug 2008) | 2 lines
-
-Completed `case 15'.
-
-------------------------------------------------------------------------
-r31 | nima | 2008-07-28 21:33:59 -0700 (Mon, 28 Jul 2008) | 2 lines
-
-Completed `case 9' and case `8'.
-
-------------------------------------------------------------------------
-r30 | nima | 2008-07-28 18:31:21 -0700 (Mon, 28 Jul 2008) | 2 lines
-
-Completed `case 11'.
-
-------------------------------------------------------------------------
-r29 | nima | 2008-07-28 18:28:04 -0700 (Mon, 28 Jul 2008) | 2 lines
-
-Completed `case 12' and `case 14'.
-
-------------------------------------------------------------------------
-r28 | nima | 2008-07-28 17:29:05 -0700 (Mon, 28 Jul 2008) | 6 lines
-
-Bug fix (removed unnecessary breakr).
-
-Changed %i back to %u for now, even though it does not work with Python.
-Better to do the change globally - later.
-
-
-------------------------------------------------------------------------
-r27 | nima | 2008-07-28 03:14:38 -0700 (Mon, 28 Jul 2008) | 2 lines
-
-Try and determine python version dynamically.
-
-------------------------------------------------------------------------
-r26 | nima | 2008-07-27 05:15:51 -0700 (Sun, 27 Jul 2008) | 2 lines
-
-Completed `case 4', which was thought to have been completed falsely before.
-
-------------------------------------------------------------------------
-r25 | nima | 2008-07-26 02:15:53 -0700 (Sat, 26 Jul 2008) | 6 lines
-
-Completed cases 1, 4, and 13. Also altered the main PyDict object such that
-each case has a value of a list to which items are appended. Without this,
-each object of the same type would overwrite the previous, for example, 8
-processors would result in one single cpu with data pertaining to the last
-cpu (7).
-
-------------------------------------------------------------------------
-r24 | nima | 2008-07-25 16:35:30 -0700 (Fri, 25 Jul 2008) | 2 lines
-
-Completed `case 0'.
-
-------------------------------------------------------------------------
-r23 | root | 2008-07-25 06:17:24 -0700 (Fri, 25 Jul 2008) | 2 lines
-
-Added `case 3'.
-
-------------------------------------------------------------------------
-r22 | root | 2008-07-25 05:51:02 -0700 (Fri, 25 Jul 2008) | 2 lines
-
-No new moves, cleanup on last commit and better test file template.
-
-------------------------------------------------------------------------
-r21 | root | 2008-07-25 05:27:26 -0700 (Fri, 25 Jul 2008) | 8 lines
-
-Next phase is to start converting all pure C functions returning `char *' and
-such to new Pythonized functions returning `PyObject *', to save from having
-to `PyString_FromString()' and similar, and more importantly, some functions
-return a long string that could better be represented by a PyDict, PyList etc.
-
-This is the first commit of many more to come, converting a `case XX:' at a
-time, making sure that each commit can actually compile and run.
-
-------------------------------------------------------------------------
-r20 | root | 2008-07-24 18:13:13 -0700 (Thu, 24 Jul 2008) | 2 lines
-
-Cleanup (DECREF).
-
-------------------------------------------------------------------------
-r19 | root | 2008-07-24 18:12:46 -0700 (Thu, 24 Jul 2008) | 2 lines
-
-Add in electric fence for now.
-
-------------------------------------------------------------------------
-r18 | root | 2008-07-24 18:11:39 -0700 (Thu, 24 Jul 2008) | 5 lines
-
-This was the culprit causing the `Abort' crash, valgrind showed that this file
-is where the error lied. Stephen Darragh discovered this, and the fix has been
-to use vsnprintf() and not vsprintf(), which should have been the case to begin
-with really.
-
-------------------------------------------------------------------------
-r17 | root | 2008-07-24 17:46:00 -0700 (Thu, 24 Jul 2008) | 2 lines
-
-Cleaner to not vsprintf() at all if `format' is NULL.
-
-------------------------------------------------------------------------
-r16 | root | 2008-07-24 17:45:11 -0700 (Thu, 24 Jul 2008) | 2 lines
-
- The `biosdecode' is a program, nothing to do with the module, removed.
-
-------------------------------------------------------------------------
-r15 | nima | 2008-07-24 07:36:16 -0700 (Thu, 24 Jul 2008) | 2 lines
-
-Added my small role in AUTHORS so nobody bugs others for my code.
-
-------------------------------------------------------------------------
-r14 | nima | 2008-07-24 07:17:16 -0700 (Thu, 24 Jul 2008) | 2 lines
-
-Cleanup.
-
-------------------------------------------------------------------------
-r13 | nima | 2008-07-24 05:02:12 -0700 (Thu, 24 Jul 2008) | 2 lines
-
-Some cleaning, crash in interactive mode on dmidecode.bios() still not fixed.
-
-------------------------------------------------------------------------
-r12 | nima | 2008-07-24 03:48:01 -0700 (Thu, 24 Jul 2008) | 3 lines
-
-Now that code has been converted, work has started on "bios", and at the point
-of proof-of-concept.
-
-------------------------------------------------------------------------
-r11 | nima | 2008-07-04 08:24:22 -0700 (Fri, 04 Jul 2008) | 3 lines
-
-Removing printf() statements, instead adding to Python dictionary object,
-untested.
-
-------------------------------------------------------------------------
-r10 | nima | 2008-07-03 08:59:08 -0700 (Thu, 03 Jul 2008) | 6 lines
-
-Major changes have been implemented, alas, untested, in hope to move towards
-a new version of dmi decode where rather than having data just printed to
-screen in functions, data is passed around, and some data structure is
-constructed, which is then used to construct the Python list/dicitonary
-objects.
-
-------------------------------------------------------------------------
-r9 | nima | 2008-07-02 00:02:05 -0700 (Wed, 02 Jul 2008) | 4 lines
-
-WIP - Adding h->type value to catsprintf (as int major), later will add minor
-too, and finally will replace the buffer with a linked list of structs, which
-will be added to the python dictionary/list.
-
-------------------------------------------------------------------------
-r8 | nima | 2008-07-01 21:53:48 -0700 (Tue, 01 Jul 2008) | 3 lines
-
-Now the `Handle' hex codes are the key values in the python dictionaries
-returned.
-
-------------------------------------------------------------------------
-r7 | nima | 2008-07-01 16:14:17 -0700 (Tue, 01 Jul 2008) | 2 lines
-
-Brought main() back into the python module and fixed malloc/free problems.
-
-------------------------------------------------------------------------
-r6 | nima | 2008-07-01 00:05:57 -0700 (Tue, 01 Jul 2008) | 2 lines
-
-Removed junk comments.
-
-------------------------------------------------------------------------
-r5 | nima | 2008-06-30 23:11:21 -0700 (Mon, 30 Jun 2008) | 2 lines
-
-Update for file renames.
-
-------------------------------------------------------------------------
-r4 | nima | 2008-06-30 23:04:02 -0700 (Mon, 30 Jun 2008) | 2 lines
-
-Better named.
-
-------------------------------------------------------------------------
-r3 | nima | 2008-06-30 23:01:21 -0700 (Mon, 30 Jun 2008) | 5 lines
-
-Project progressing along excellently. The python module is now functional and
-has as many methods as the --type option takes.
-
-Next is to expand and harness the code around the `--string' option.
-
-------------------------------------------------------------------------
-r2 | nima | 2008-06-30 07:14:46 -0700 (Mon, 30 Jun 2008) | 4 lines
-
-Split out the module header into its own file.
-
-Cleaned up Makefile a little.
-
-------------------------------------------------------------------------
-r1 | nima | 2008-06-30 05:08:58 -0700 (Mon, 30 Jun 2008) | 2 lines
-
-First commit to SVN.
-
-------------------------------------------------------------------------
+ Adding spec file supplied by Clark Williams <williams at redhat.com>.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@176 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 72c61bede5e0279cd4ee3b60cc3f0d0947fc4977
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sun Mar 8 11:31:31 2009 +0000
+
+ Applied patch submitted by Clark Williams <williams at redhat.com>.
+
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@175 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 78c26d98b13f3ee16d93f8950198376afb7589cb
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sun Feb 22 13:34:24 2009 +0000
+
+ Fixed bug reported by Ralf Treinen.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@174 abc39116-655e-4be6-ad55-d661dc543056
+
+commit e203e56f9b06f7860f4f1f4c3dded6c7e2031c5b
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Feb 13 14:39:23 2009 +0000
+
+ Removing spec file from upstream.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@173 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 32bf7d52f21c1fc74583e3ae6d6978b879d4c650
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Feb 13 14:36:16 2009 +0000
+
+ Upped sub-version.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@172 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 8f278a3de968fca02762da08ec5e85810cb27107
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Feb 13 14:32:06 2009 +0000
+
+ Small changes - final touches for 2.10.1.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@171 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 83ad351950a3f7a587810801689b8f2e0fdbd72f
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Feb 13 14:30:37 2009 +0000
+
+ Versioning now chagned to reflect the version of the upstream (dmidecode)
+ version with which python-dmidecode is in sync with.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@170 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 28707fdf3241fabac3a5a379ae83770a0b3216bd
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Tue Jan 13 12:48:28 2009 +0000
+
+ Fixed watch file.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@169 abc39116-655e-4be6-ad55-d661dc543056
+
+commit f9134f3aca61ee5b1cec3f136cf99e37a90bb9f4
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Mon Jan 12 13:06:34 2009 +0000
+
+ Debian changes completely separated from upstream.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@168 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 52f3744ec2b709791ad062e2668aea2fef5ae43e
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Mon Jan 12 13:04:52 2009 +0000
+
+ Removed Debian-specific targets from the makefile.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@167 abc39116-655e-4be6-ad55-d661dc543056
+
+commit f5223b667e367a522949b320e76be96b56199b5c
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Mon Dec 22 23:02:00 2008 +0000
+
+ Source file name change.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@166 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 67154ad0a8b84de61bb07335150117507e2b7eef
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Mon Dec 22 23:01:22 2008 +0000
+
+ A more complete dmidecode example.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@165 abc39116-655e-4be6-ad55-d661dc543056
+
+commit d866a378dbc4645d224f06dfd41c5ca793690e81
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Mon Dec 22 22:40:51 2008 +0000
+
+ Applied the nice changes suggested by Piotr Ożarowsk.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@164 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 25f310ab03c3010d89b0cafa989aeab94bcda58f
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Mon Dec 22 13:37:43 2008 +0000
+
+ Cleaned up the fix for type(127).
+
+ Added the second type of stuffed bios (upstream).
+
+ Integrated dmidecode the binary into the test case for a more objective result.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@163 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 915ed13f64903adda36446657d19e6bae02e3be2
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Mon Dec 22 09:06:43 2008 +0000
+
+ Fixed the type(127) problem (at least on this machine) - again.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@162 abc39116-655e-4be6-ad55-d661dc543056
+
+commit ffea5fcd1f1a50860e8f731e2afa8481a819e28b
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sun Dec 21 12:52:51 2008 +0000
+
+ Removed unnecessay manpage.
+
+ Spell my own name correctly.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@161 abc39116-655e-4be6-ad55-d661dc543056
+
+commit b89740eb95934cfa50815076a39a6948002f50ca
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sun Dec 21 11:31:36 2008 +0000
+
+ Added an upload into src.autonomy.net.au after source build.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@160 abc39116-655e-4be6-ad55-d661dc543056
+
+commit ddee60b9bad068405f520ddd772dffda2c742087
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sun Dec 21 11:27:52 2008 +0000
+
+ Fixed sample.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@159 abc39116-655e-4be6-ad55-d661dc543056
+
+commit ea7bb44fc527bfab6b418ad6fd0e5cf87341298e
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sun Dec 21 10:22:06 2008 +0000
+
+ Cleanup copyright.
+
+ Cleanup debian/rules.
+
+ Adding test.py to examples.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@158 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 66a38305dab867627657cd5f094d1d8bf2a51825
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sun Dec 21 10:04:03 2008 +0000
+
+ Remove README.Debian - no point.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@157 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 8b39733bc2b67ba2b229cbe119d553a9247c77a2
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sun Dec 21 07:57:49 2008 +0000
+
+ Cleanup.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@156 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 0ff1b5b45facd7543529dab5711cf2812c47c218
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sun Dec 21 07:53:54 2008 +0000
+
+ Handle cases where user does not have appropriate permission to access the
+ memory file or device.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@155 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 42617d59e66684bff7272c9c49c0cadd2e53c7f9
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sun Dec 21 05:44:04 2008 +0000
+
+ Names.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@154 abc39116-655e-4be6-ad55-d661dc543056
+
+commit c53e65f772d248194bc0d45bdcfec5374d0bee9f
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sun Dec 21 05:43:06 2008 +0000
+
+ Better naming.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@153 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 20543ee1abb96ed63f4e6fa317954439b8a3057f
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sun Dec 21 04:41:39 2008 +0000
+
+ Upped debhelper build-required version from 5 to 7.
+
+ Final cleanups.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@152 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 5337eca7114bec25f59910971c734d7aac416c2e
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sun Dec 21 02:55:19 2008 +0000
+
+ Cleaned up and Lintian-approved.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@151 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 39341f8c367a9de724047c7a980ca75fc60814c8
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sun Dec 21 02:48:05 2008 +0000
+
+ Email address fixed.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@150 abc39116-655e-4be6-ad55-d661dc543056
+
+commit b2e8392246743a46da312c9897c5b1225a7e3841
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sun Dec 21 02:39:16 2008 +0000
+
+ Sigh.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@149 abc39116-655e-4be6-ad55-d661dc543056
+
+commit b8ac8f18072dfaebaa5c3028017c7c37bd8e3853
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sun Dec 21 02:38:35 2008 +0000
+
+ Changing to svn-buildpackage.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@148 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 0c05fe155d2c92451713dc36013f2d2a276a2a84
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sun Dec 21 02:22:20 2008 +0000
+
+ Cleanup.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@147 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 558f9ab291dbbb46e5228f5d87e3d27657cd15f3
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sun Dec 21 02:07:56 2008 +0000
+
+ Source generation.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@146 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 0005d9f98cb72d01f081d6c4cbe4a588fd9d3926
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sun Dec 21 01:41:57 2008 +0000
+
+ Fixed watchfile now that I've created a src (orig.tar.gz) repository.
+
+ Added more copyright/lisencing information.
+
+ More debianizing.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@145 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 3a79b7e48e1f19b520ee866ef36b07668020147c
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sat Dec 20 17:00:56 2008 +0000
+
+ Required for dh_installdocs.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@144 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 0a3f625c078d200d8867dfc15415b2c8c5534ccc
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sat Dec 20 16:54:32 2008 +0000
+
+ Cleanup.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@143 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 3f492c5cb392aa7038d496b7c516dca95d225dee
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sat Dec 20 16:52:15 2008 +0000
+
+ Cleanup.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@142 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 578bb67b183860861c9bc322fcf18c5d3f4b08a3
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sat Dec 20 16:49:40 2008 +0000
+
+ Removed out-of-place README.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@141 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 36124e46822d1e31f17d68dc4b10ec7b2e63c507
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sat Dec 20 16:47:18 2008 +0000
+
+ Hide private data from subversion.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@140 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 4c616b1753292d631212461093bec9b2fcc519f0
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sat Dec 20 16:46:37 2008 +0000
+
+ Remove private memory dumps.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@139 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 88614ec62615e420346a4fc4cc8a532ff14a5f08
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sat Dec 20 16:45:39 2008 +0000
+
+ Added missing info to copyright file.
+
+ Source creation target.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@138 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 181dbf623e793005c0293a769ee669eec06a3fad
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sat Dec 20 16:26:43 2008 +0000
+
+ Cleanup.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@137 abc39116-655e-4be6-ad55-d661dc543056
+
+commit fe4e406114752c7d61280f32b4af84cdc2504b4d
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sat Dec 20 15:49:18 2008 +0000
+
+ Handle cases where user asks for invalid types.
+
+ Updated test cases to test for this too.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@136 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 0e2598266442b8f1015c75833034ac0f26857820
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sat Dec 20 15:32:30 2008 +0000
+
+ Version information now set once during init().
+
+ Bettered test cases.
+
+ Case 127 magically fixed.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@135 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 6d5ebf5d39e419e2f83960223bf840275426dc87
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sat Dec 20 01:46:42 2008 +0000
+
+ Debian specific target.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@134 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 8626bbd2cfcb10109cfa85b8d7ef99898e6f7771
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sat Dec 20 01:44:55 2008 +0000
+
+ Removed "detected" from appearing in every single function call. TODO: An ivar
+ should be implemented to return this string, so further cleanup is still
+ required; as it stands, there is no access to this information anymore!
+
+ Updated test case.
+
+ Further general cleanup.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@133 abc39116-655e-4be6-ad55-d661dc543056
+
+commit f5397d936f5dc85813d1d6d50cf5f7d6ba9716c8
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Dec 19 23:55:53 2008 +0000
+
+ Further testing shows that the segfault does not occur when the device is
+ /dev/mem, but does so for all images (where requested type is 127), suggesting
+ that the problem could be with the image or surrounding processes.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@132 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 7433f78f76c509f7253fca4a44fb1867dbbb4092
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Dec 19 23:46:46 2008 +0000
+
+ Oops - fixed.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@131 abc39116-655e-4be6-ad55-d661dc543056
+
+commit ecc5f901bbb8c888ca3c9e89296a98442bbb0f9e
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Dec 19 23:45:55 2008 +0000
+
+ Test case is close to complete, type 127 results in a segfault - (test case
+ is serving its purpose).
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@130 abc39116-655e-4be6-ad55-d661dc543056
+
+commit b23485083a007a0490d8ca3125d65bf239e4fae2
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Dec 19 23:29:50 2008 +0000
+
+ Adding an image from parallel's desktop running Debian lenny, and another for
+ a physical server also running Debian. Both are intel 32 bit.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@129 abc39116-655e-4be6-ad55-d661dc543056
+
+commit b23d9e08db459d72fa496b1c47979bf3311926ef
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Dec 19 23:27:10 2008 +0000
+
+ More work on test case.
+
+ Updated setup.py to reflect new version.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@128 abc39116-655e-4be6-ad55-d661dc543056
+
+commit ea6e33f5a11185286c464305f6ef408ff8ff8b93
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Dec 19 13:49:19 2008 +0000
+
+ More testing and fixes.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@127 abc39116-655e-4be6-ad55-d661dc543056
+
+commit ef62ae6dea3de725825a92e92bfab6cb9a581f93
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Dec 19 13:42:10 2008 +0000
+
+ Improved test case.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@126 abc39116-655e-4be6-ad55-d661dc543056
+
+commit bc5647310466c6f4409bc195e5abf32710abedfa
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Dec 19 13:32:35 2008 +0000
+
+ Removed a printf() comment.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@125 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 11ec71fe19b72a35612fa52cef5c25760e487d7d
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Dec 19 13:21:24 2008 +0000
+
+ Check that the path given with set_dev() is writeable.
+
+ Don't crash when writing to a read-only file, return False instead.
+
+ Missing an INCREF in get_dev() fixed.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@124 abc39116-655e-4be6-ad55-d661dc543056
+
+commit b007b775afdba38cdc3430ec9c909324d3522fb4
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Dec 19 11:56:39 2008 +0000
+
+ Test for write permission prior to write attempts.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@123 abc39116-655e-4be6-ad55-d661dc543056
+
+commit eaa8d27476769e2b65e92d6b0010356ca7cc4f2e
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Dec 19 09:02:52 2008 +0000
+
+ Fixed watch file.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@122 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 4b92dd269005ced52ff82061a65719e73162a2b3
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Dec 19 05:05:38 2008 +0000
+
+ Received ITP auto-ack: #509169.
+
+ More debianizing cleanup.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@121 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 262375e89de043a6df588d87e6d87e69e28141cc
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Dec 19 04:13:24 2008 +0000
+
+ Cleanup.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@120 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 6249a27ea72b83726975bfa6771b226f325c1a95
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Dec 19 04:07:06 2008 +0000
+
+ Further work in enforcing the Debian policy in package based on advice from
+ `POX' and the documentation.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@119 abc39116-655e-4be6-ad55-d661dc543056
+
+commit e620d0a9d88875c425741ad2d40579e61cdd15b0
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Dec 19 02:23:32 2008 +0000
+
+ Removed junk and doing more debianizing - WIP.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@118 abc39116-655e-4be6-ad55-d661dc543056
+
+commit c19f68cb27021c0fd5e0ad1962ff9547bd616e23
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Thu Dec 18 13:49:57 2008 +0000
+
+ Updated.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@117 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 4b189e807e77894dde0df32cefae8ab5f530ce16
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Thu Dec 18 13:48:52 2008 +0000
+
+ The dmidecode.type() call not takes ints, not strings.
+
+ Adding an example directory.
+
+ Adding test case.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@116 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 2343c69ba224db0f6c7cca4be5496ce1f3382baf
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Thu Dec 18 13:45:37 2008 +0000
+
+ The dmidecode.type() call not takes ints, not strings.
+
+ Adding an example directory.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@115 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 8a49e58086274526d2526edade1d53ee02af2820
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Thu Dec 18 01:12:50 2008 +0000
+
+ More upstream changes implemented, see CHANGELOG by Jean Delvare from the
+ period 2008-02-16 to 2008-11-23.
+
+ These changes have been made, but not yet fully tested.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@114 abc39116-655e-4be6-ad55-d661dc543056
+
+commit f22d0e6e9604c15c7e9f75545cee9fa429acb5aa
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Dec 17 13:26:57 2008 +0000
+
+ Claim to support revision 32 of Intel AP-485 (CPUID). No relevant change since
+ revision 31.
+
+ Update reference to AMD CPUID document.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@113 abc39116-655e-4be6-ad55-d661dc543056
+
+commit a08bb2a9c602a130471b3408fcf88745bc68a53d
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Dec 17 13:11:35 2008 +0000
+
+ Handle chassis information records of size 19 (DMI type 3).
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@112 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 78c7237b805620d0b8275377fefa9b3ba8ff1954
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Dec 17 13:00:12 2008 +0000
+
+ And the debian subfolder itself...
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@111 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 46632c536288d4159d7c78cab921dc2ab2d08dc4
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Dec 17 12:59:32 2008 +0000
+
+ Debianizing dmidecode.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@110 abc39116-655e-4be6-ad55-d661dc543056
+
+commit d4241f4f3203d11cf8ded804df36bc97053df333
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Dec 17 07:30:04 2008 +0000
+
+ Adding spec file written by Joel Heenan.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@109 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 39378ee26e0d1d2ab4c76eed22514c6f986c5495
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Dec 17 07:20:56 2008 +0000
+
+ Cleaning up source area, ready for debianizing, and rpm after that.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@108 abc39116-655e-4be6-ad55-d661dc543056
+
+commit b0103d72736fdf47760049dbf880a859b52c88fa
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Oct 31 14:45:34 2008 +0000
+
+ Changed default target of Makefile back to `setup.py' method of installation.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@107 abc39116-655e-4be6-ad55-d661dc543056
+
+commit f173034b410e82cfd69d702ed862b4964beb4cd6
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Oct 31 14:41:02 2008 +0000
+
+ Cleanup.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@106 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 0bf883a82fdf4a8665c1a7832121418d3be8d201
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Oct 31 14:33:03 2008 +0000
+
+ This commit closes #2 reported by Justin Cook, the ticket will remain open
+ until Justin confirms this however.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@105 abc39116-655e-4be6-ad55-d661dc543056
+
+commit f120b5fa5933fef104c1f5e711581455e3980e2e
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Oct 31 14:07:22 2008 +0000
+
+ Implemented reading a dump to - this concludes syncing to the upstream release.
+
+ Next, exceptions should be thrown in certain places, more error checking in the
+ python side of things, and also in relation to setting and unsetting of the
+ alternate memory file.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@104 abc39116-655e-4be6-ad55-d661dc543056
+
+commit e703746faad221f6c367e4fe5fd27ebd6b4aae54
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Oct 31 13:42:35 2008 +0000
+
+ Cleanup.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@103 abc39116-655e-4be6-ad55-d661dc543056
+
+commit e812ea8f8576cd8dbbe8a956053c200a35362480
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Oct 31 13:38:24 2008 +0000
+
+ Fixed dump. The `offset' problem was not really an offset problem - it was a
+ silly typo.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@102 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 8db7b4d856573841afc6de7e16bbb286b0269cbd
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Oct 31 13:24:04 2008 +0000
+
+ Missed two lines.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@101 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 4b4afad325b8e11800f622fad2f6eacb22e3f2bb
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Oct 31 13:19:50 2008 +0000
+
+ Dump-to-file is almost working, there seems to be a 4-byte misalignment in the
+ produced file though for now - needs to be fixed.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@100 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 56069e096f18a9538a8c0e86c96959b2fbef3dcf
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Oct 31 11:43:15 2008 +0000
+
+ Removed junk comments.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@99 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 28ddefea64e27dbcbd928cae362527b2d63dcb5a
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Oct 31 11:21:24 2008 +0000
+
+ Cleanup.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@98 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 6f7a8bbe18e60f6691e7a7c566e28b2a5eda7c94
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Oct 31 11:15:19 2008 +0000
+
+ Cleanup.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@97 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 24f10bb094c9831f4133d488d0af90dc2a83590f
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Oct 31 10:24:41 2008 +0000
+
+ Cleanup.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@96 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 34ed409541219e8239a5826849ef36d8f4a05eb9
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Oct 31 09:05:23 2008 +0000
+
+ Integration of required `dmiopt.h' bits.
+ Removed QUIETness code.
+ Other cleanups.
+ Added get/set methods for changinf the default /dev/mem device.
+
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@95 abc39116-655e-4be6-ad55-d661dc543056
+
+commit ddabe05f4eb607e35aaea36226227580af723745
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Oct 31 09:02:21 2008 +0000
+
+ Removed traces of `_' and integrating required bits from dmiopt.h.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@94 abc39116-655e-4be6-ad55-d661dc543056
+
+commit f81f2790ea8c0f592418fc2a6fc2c900866e18d4
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Oct 31 09:01:41 2008 +0000
+
+ Removed traces of `_'.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@93 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 3dd06d10c6b4465bb05203393ae192cb98d511d4
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Oct 31 09:00:26 2008 +0000
+
+ Integrating the required bits from dmiopt into dmihelper.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@92 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 895dc84ff44587d7cd6832d68b4efd82f31cab7b
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Oct 31 08:39:12 2008 +0000
+
+ Removed `_' buffer.
+ Removed use of `FLAGS_QUIET' as it makes no sense for a module.
+ Removed the `submain()' function.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@91 abc39116-655e-4be6-ad55-d661dc543056
+
+commit c81c458bcffbb973d90c5902bb73d2bbd7ff843c
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Oct 31 08:30:00 2008 +0000
+
+ Cleanup.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@90 abc39116-655e-4be6-ad55-d661dc543056
+
+commit fd945b4d3ecdb0e678d595896328ba200a552345
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Oct 31 08:29:06 2008 +0000
+
+ Removed dependency on dmiopt.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@89 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 7953fe6ab9bf5c1e6a76a671e4a4895351a31559
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Oct 31 08:28:33 2008 +0000
+
+ Removed verbose printout.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@88 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 97c2bf5aa740ad9a7e2f39d95ba3095725567ad2
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Thu Oct 30 10:14:24 2008 +0000
+
+ Removed final traces of the `_' buffer.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@87 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 6e5ae9b4399e847b365b00e03b8c619efdf3bba1
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Thu Oct 30 02:11:56 2008 +0000
+
+ Implementing (incomplete) upstream changes.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@86 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 90f1ca30ef2d9ce324fc198ea7c3a128410d085a
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Oct 29 07:15:35 2008 +0000
+
+ Cleanup.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@85 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 6c0e97f2159991f0de26f79d49fed4a4d3caa326
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Oct 29 07:13:49 2008 +0000
+
+ Adding man pages from upstream. Sooner or later, these will be removed, as will
+ all other work that's simply replicating the demidecode binary. All this
+ package should provide is the python module, and some py-module-specific man
+ pages.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@84 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 912c8ba257f0c0b05b3d5916da203bc8566c83af
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Oct 29 07:10:24 2008 +0000
+
+ Recoded the new work from upstream into these (main) files. The options to
+ dump the memory image onto file, and read back from it has not yet been
+ worked in, but the underlying work has been completed.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@83 abc39116-655e-4be6-ad55-d661dc543056
+
+commit e308e170fc844c8b4454384873497f52f0d37ae7
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Oct 29 07:09:10 2008 +0000
+
+ Tested new dmidecode python module with this example file. A real test case
+ will be implemented sometime in future.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@82 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 8cbb9ffa69310c065247d3f76eac2e7ee9991af7
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Oct 29 07:07:56 2008 +0000
+
+ Cleanup.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@81 abc39116-655e-4be6-ad55-d661dc543056
+
+commit e855dac8a474342fb59317de682b9b9e87e0d79e
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Oct 29 07:07:13 2008 +0000
+
+ Cleanup.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@80 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 798528d678675f424d70a43785e4e77caaa25ebe
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Oct 29 07:06:47 2008 +0000
+
+ Using dmihelper now.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@79 abc39116-655e-4be6-ad55-d661dc543056
+
+commit ad98794d4d92d173462c53714e3d9f2a0726ff68
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Oct 29 07:05:58 2008 +0000
+
+ Upstream.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@78 abc39116-655e-4be6-ad55-d661dc543056
+
+commit a4a07b0955dfe6d77e046db346b69e48c7d29066
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Oct 29 07:04:19 2008 +0000
+
+ Upstream.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@77 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 3c78c1ef20182ab39bde47677ee615bbbd208837
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Oct 29 07:04:03 2008 +0000
+
+ Cleanup.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@76 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 601a1baf86b023feb8cb6ca1754c225ebbbe371f
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Oct 29 06:36:23 2008 +0000
+
+ Renamed to a more appropriate name.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@75 abc39116-655e-4be6-ad55-d661dc543056
+
+commit e2f610150c546645c4520cbb5f79c5fd0571ce53
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Oct 29 06:35:21 2008 +0000
+
+ Committing new dmidecode helper functions, and next, renaming it to a
+ meaningful name.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@74 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 4dbf349a3c8c623f08b9d20991461814888ab492
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Oct 29 06:27:31 2008 +0000
+
+ Synced to the latest from upstream, with a light modification required for the
+ module.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@73 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 8cb72b16a67bb1540763d654fe9d5f61ee7c83a3
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sat Oct 18 09:34:09 2008 +0000
+
+ Python does not have unsigned integers, hence %u and %lu in printf style
+ strings are taken to be literal strings, not space-holders. All occurences
+ of '%u' (78) have been amended to '%i', there was no '%lu'.
+
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@72 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 4c92ab9878eaff844316e8f416a3bb59c5c9df46
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sat Oct 18 09:28:46 2008 +0000
+
+ Fixed bug reported by by Justin Cook, where dmidecode.type() would segfault.
+ It turned out to be some code that was forgotten about during the conversion, or
+ at least very incomplete and wrong.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@71 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 259d4088f61379786d1889c2e5bc7df2687ea6c3
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Thu Oct 16 15:52:48 2008 +0000
+
+ Remove efence.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@70 abc39116-655e-4be6-ad55-d661dc543056
+
+commit c3078cd8c661c23b3ecc0928169a9a7b4613b6ee
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Sep 5 03:08:02 2008 +0000
+
+ Fixed a bug that crashed dmidecode.slot().
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@69 abc39116-655e-4be6-ad55-d661dc543056
+
+commit e7369539f2ccab7db4fb91f6ae470d8a5a4d25fb
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Thu Sep 4 06:09:55 2008 +0000
+
+ Cleaning up of the dmidecode module, mostly conversion of things that can be
+ Python `None's or `Int's but were `String'.
+
+ Replaced a meaningless int dictionary key to `data'.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@68 abc39116-655e-4be6-ad55-d661dc543056
+
+commit b3880a3305dcdd866638202b9da95cd99f06b085
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Thu Sep 4 02:26:09 2008 +0000
+
+ Work on CPU details - seemed to been a bug with appending to a string rather
+ than rewriting it.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@67 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 1fea35ea0c1635e080028c914b88849c721764e6
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Aug 8 14:15:47 2008 +0000
+
+ Replaced `%X' with `%x'.
+
+ Logic cleanup - Put the `Handle' info back into the dictionary.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@66 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 663aaf5ee1150ea15f9314f11d5272eb23ab5901
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Aug 8 07:57:44 2008 +0000
+
+ Anoher bug fix, this time in baseboard.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@65 abc39116-655e-4be6-ad55-d661dc543056
+
+commit bea781c97b383c90df7e201d27709017f680374b
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Aug 8 07:27:36 2008 +0000
+
+ Fixed many major bugs (all of which were expected based on the way we mass
+ converted all the `case' blocks.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@64 abc39116-655e-4be6-ad55-d661dc543056
+
+commit e5ac5d6d7ca49e1280fe498c373d95843412419d
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Thu Aug 7 12:32:39 2008 +0000
+
+ Cleaned up a little.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@63 abc39116-655e-4be6-ad55-d661dc543056
+
+commit fe54050ef08fe0273ac4f244d62d1259f0787ab8
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Thu Aug 7 01:34:15 2008 +0000
+
+ Fixed some conversion bits missed during last night.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@62 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 8cb2f6cb98436c17f23d3ab1f66418d221ac4d95
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 13:32:37 2008 +0000
+
+ Updated authors file with developers of the dmidecode python module.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@61 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 1e47ff265d8bd054717f7b935f4d920b94c372c9
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 13:27:26 2008 +0000
+
+ Changed to GNU GPL v3 License.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@60 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 6cb20ba1cabd295bdb5984edbec41e00670959f4
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 12:59:03 2008 +0000
+
+ Removed `sudo'.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@59 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 6c0d824bea2f120deec404d8d0b549a4fa7022e3
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 12:52:46 2008 +0000
+
+ Completed `case 126', thought to have been completed in previous commit.
+
+ Some housekeeping elsewhere.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@58 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 6ec138d6b4df9c034e44803350ee00b5249db718
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 08:51:05 2008 +0000
+
+ Completed all conversions! Only problem now is of course finding all the memory
+ leaks and introduced logic errors which (confirmed) do exists - use valgrind and
+ see.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@57 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 1b20c68297ccbefb06d87b3080f357487090e289
+Author: vwhitteron <vwhitteron@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 08:29:18 2008 +0000
+
+ Completed `Case 34' through `Case 39'
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@56 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 1ec75e6a426a35aafa9ef260bf766a85412fb2d8
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 08:12:43 2008 +0000
+
+ Almost there!
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@55 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 43f1a78747dd745221817550f2c5d2417c926162
+Author: vwhitteron <vwhitteron@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 07:49:23 2008 +0000
+
+ Completed `Case 29' and `Case 32'
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@54 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 38759e9c012958de8227848ad3a45230d03e99c9
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 07:42:34 2008 +0000
+
+ Converted `case 30'.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@53 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 7e04e6983fdb1cda3332a5d6b67123b806b3dca9
+Author: vwhitteron <vwhitteron@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 07:40:42 2008 +0000
+
+ Completed `Case 26', `Case 27' and `Case 28'
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@52 abc39116-655e-4be6-ad55-d661dc543056
+
+commit cf3ab83777f1b61e6f046d0fcc8cf2d4417a498a
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 07:30:41 2008 +0000
+
+ Added `PyObject *data;' to all remaining functions which will generate a warning
+ as to indicate these need to be converted.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@51 abc39116-655e-4be6-ad55-d661dc543056
+
+commit e4c2636d13fd3465745f5d087fbbd5828aeaa16b
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 07:27:30 2008 +0000
+
+ Completed functions for `csae 28'.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@50 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 8eb77f162256ae17a1ab1d36d32aa33f8d69647e
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 07:23:35 2008 +0000
+
+ Completed functions for `case 27', and fixed error in last commit for `case 26'.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@49 abc39116-655e-4be6-ad55-d661dc543056
+
+commit ea79c3b4226de0671d67bc2a178a21c116ee9e99
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 07:19:27 2008 +0000
+
+ Completed functions for `case 26'.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@48 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 4bf9a5a95007e5d75bdc47381150d590934c24cc
+Author: vwhitteron <vwhitteron@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 07:09:11 2008 +0000
+
+ Completed `Case 23', `Case 24', `Case24' and `Case 25'
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@47 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 1e07aedaeb1d455cab5a9a4975284e59ee5003de
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 07:07:20 2008 +0000
+
+ Completed functions for `case 25'.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@46 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 1f0c5e5936f3c0bb55419c6ee1f55e9ff3f0078d
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 07:00:41 2008 +0000
+
+ Converted function for `case 24'.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@45 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 78f950bf54293a9afeb0e9aea46009a883eb5b5b
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 06:59:35 2008 +0000
+
+ More fixes on recent commits (by me), and more conversions on functions.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@44 abc39116-655e-4be6-ad55-d661dc543056
+
+commit f3c71346a009f1b88a3acc29a66fa6a9c01b124d
+Author: vwhitteron <vwhitteron@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 06:57:13 2008 +0000
+
+ Completed `Case 22'
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@43 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 0b91f0fc928b320e12e43e7ba004cbd61d4cfacc
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 06:53:24 2008 +0000
+
+ Oops. Fixed stupidity on last commit.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@42 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 62564b881ff2d443d662ddea931c467be1220dad
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 06:52:01 2008 +0000
+
+ Completed functions called by `case 21' and `case 22'.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@41 abc39116-655e-4be6-ad55-d661dc543056
+
+commit afc3d425009009cf65bb08cb69bc8054d7d61150
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 06:42:54 2008 +0000
+
+ Completed `case 21' functions.
+ Cleanup.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@40 abc39116-655e-4be6-ad55-d661dc543056
+
+commit f503ee22561092a8169048a8005faaefd81f102d
+Author: vwhitteron <vwhitteron@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 06:39:53 2008 +0000
+
+ Completed `case 19' and `case 20'.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@39 abc39116-655e-4be6-ad55-d661dc543056
+
+commit cfa3d0433906670cffa49bd645cdc3b99383f208
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 06:17:21 2008 +0000
+
+ Started on `case 19'.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@38 abc39116-655e-4be6-ad55-d661dc543056
+
+commit a1554740cea413d44314c861da9b95fd77ea0189
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 05:43:05 2008 +0000
+
+ Completed `case 18' and `case 19'.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@37 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 6bf676ffe12c1e25f6b2224d69a5bd2f3b85f609
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 05:06:03 2008 +0000
+
+ Added `case 16' and `case 17'.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@36 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 538d307f94bb761f6e56bbecfc2146bd1cf3fdc7
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 04:26:45 2008 +0000
+
+ Cleanup.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@35 abc39116-655e-4be6-ad55-d661dc543056
+
+commit c979fb48a97fd7a40cf024120ac8457405a937fd
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Aug 6 04:05:06 2008 +0000
+
+ Converted `case 5', `case 6', and `case 7'.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@34 abc39116-655e-4be6-ad55-d661dc543056
+
+commit f983c44c7ad77605dbccdb3029d0a9874ce19caa
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Aug 1 07:59:51 2008 +0000
+
+ Default case set to return python's `None'.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@33 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 97aff8721825836c9d4b635fe2b1e16a888a2d03
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Aug 1 07:58:24 2008 +0000
+
+ Completed `case 15'.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@32 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 3ee245f63459233914c63241783a11b96daafb2e
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Tue Jul 29 04:33:59 2008 +0000
+
+ Completed `case 9' and case `8'.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@31 abc39116-655e-4be6-ad55-d661dc543056
+
+commit e60c33b99aeb6293662c3c0cfe29311660a1561f
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Tue Jul 29 01:31:21 2008 +0000
+
+ Completed `case 11'.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@30 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 3db9a258855f62caf5b923e6ec6cbcdad00fda5b
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Tue Jul 29 01:28:04 2008 +0000
+
+ Completed `case 12' and `case 14'.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@29 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 968758dda5dfcb6b241e33453537b1d01adc185e
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Tue Jul 29 00:29:05 2008 +0000
+
+ Bug fix (removed unnecessary breakr).
+
+ Changed %i back to %u for now, even though it does not work with Python.
+ Better to do the change globally - later.
+
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@28 abc39116-655e-4be6-ad55-d661dc543056
+
+commit c4a6a91790a555db27956429ac74ca277988e24b
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Mon Jul 28 10:14:38 2008 +0000
+
+ Try and determine python version dynamically.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@27 abc39116-655e-4be6-ad55-d661dc543056
+
+commit f285118e5d4d62a9918a563c9fb1e7aba0299c9e
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sun Jul 27 12:15:51 2008 +0000
+
+ Completed `case 4', which was thought to have been completed falsely before.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@26 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 65cca18ecfb4c72faf0cf77872f3db494aa80c35
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Sat Jul 26 09:15:53 2008 +0000
+
+ Completed cases 1, 4, and 13. Also altered the main PyDict object such that
+ each case has a value of a list to which items are appended. Without this,
+ each object of the same type would overwrite the previous, for example, 8
+ processors would result in one single cpu with data pertaining to the last
+ cpu (7).
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@25 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 8671ea0ba8caa35428afeee68efa53671c839815
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Jul 25 23:35:30 2008 +0000
+
+ Completed `case 0'.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@24 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 3ca138e7776d5356fa6ac1b58101d64b6f3c3fa0
+Author: root <root@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Jul 25 13:17:24 2008 +0000
+
+ Added `case 3'.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@23 abc39116-655e-4be6-ad55-d661dc543056
+
+commit d64493ba04c17b83b30aaae1e27850ade958252d
+Author: root <root@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Jul 25 12:51:02 2008 +0000
+
+ No new moves, cleanup on last commit and better test file template.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@22 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 91a850b6d91e76c5450781b1e029c1611ef9f2e7
+Author: root <root@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Jul 25 12:27:26 2008 +0000
+
+ Next phase is to start converting all pure C functions returning `char *' and
+ such to new Pythonized functions returning `PyObject *', to save from having
+ to `PyString_FromString()' and similar, and more importantly, some functions
+ return a long string that could better be represented by a PyDict, PyList etc.
+
+ This is the first commit of many more to come, converting a `case XX:' at a
+ time, making sure that each commit can actually compile and run.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@21 abc39116-655e-4be6-ad55-d661dc543056
+
+commit dfcf0bfff41f31fd7f75df43e37e2ba7db70b362
+Author: root <root@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Jul 25 01:13:13 2008 +0000
+
+ Cleanup (DECREF).
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@20 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 825f492e53776cbd5cb957a61b0299b3edf5ced2
+Author: root <root@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Jul 25 01:12:46 2008 +0000
+
+ Add in electric fence for now.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@19 abc39116-655e-4be6-ad55-d661dc543056
+
+commit b163757a47d525019cebae8e1ecb843a49a14196
+Author: root <root@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Jul 25 01:11:39 2008 +0000
+
+ This was the culprit causing the `Abort' crash, valgrind showed that this file
+ is where the error lied. Stephen Darragh discovered this, and the fix has been
+ to use vsnprintf() and not vsprintf(), which should have been the case to begin
+ with really.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@18 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 9483c94352b0182580972e7cac2ba585022398d5
+Author: root <root@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Jul 25 00:46:00 2008 +0000
+
+ Cleaner to not vsprintf() at all if `format' is NULL.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@17 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 49d89e73d077c399cd85dcbbd623e08c59547304
+Author: root <root@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Jul 25 00:45:11 2008 +0000
+
+ The `biosdecode' is a program, nothing to do with the module, removed.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@16 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 8ae9e8165aa42f710ce9e65601f9cdea44a59462
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Thu Jul 24 14:36:16 2008 +0000
+
+ Added my small role in AUTHORS so nobody bugs others for my code.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@15 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 24088a00c8ca6e9743ee6bba4ddf958fbe3149cb
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Thu Jul 24 14:17:16 2008 +0000
+
+ Cleanup.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@14 abc39116-655e-4be6-ad55-d661dc543056
+
+commit c0c4e2446ffca88aed27726fd28f99470fb85d40
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Thu Jul 24 12:02:12 2008 +0000
+
+ Some cleaning, crash in interactive mode on dmidecode.bios() still not fixed.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@13 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 4289505932068a0c071c7c9fb4655678394cb469
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Thu Jul 24 10:48:01 2008 +0000
+
+ Now that code has been converted, work has started on "bios", and at the point
+ of proof-of-concept.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@12 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 2a92460699aa8a18bc0602d48afed1ebb408c16a
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Fri Jul 4 15:24:22 2008 +0000
+
+ Removing printf() statements, instead adding to Python dictionary object,
+ untested.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@11 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 60eb9d480daa352d7af19ad67e410f384f0e9f74
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Thu Jul 3 15:59:08 2008 +0000
+
+ Major changes have been implemented, alas, untested, in hope to move towards
+ a new version of dmi decode where rather than having data just printed to
+ screen in functions, data is passed around, and some data structure is
+ constructed, which is then used to construct the Python list/dicitonary
+ objects.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@10 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 831e6bd3e28b85a87f68917bb928b1f3ce7601ce
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Jul 2 07:02:05 2008 +0000
+
+ WIP - Adding h->type value to catsprintf (as int major), later will add minor
+ too, and finally will replace the buffer with a linked list of structs, which
+ will be added to the python dictionary/list.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@9 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 0b6d2fb3e16489f5bc349e2fdc214636c478bba0
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Wed Jul 2 04:53:48 2008 +0000
+
+ Now the `Handle' hex codes are the key values in the python dictionaries
+ returned.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@8 abc39116-655e-4be6-ad55-d661dc543056
+
+commit c10adcd728be238d8579bf98075a2468f0143cc2
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Tue Jul 1 23:14:17 2008 +0000
+
+ Brought main() back into the python module and fixed malloc/free problems.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@7 abc39116-655e-4be6-ad55-d661dc543056
+
+commit a7a5cb531b86a75265f106b91d7033e45d754612
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Tue Jul 1 07:05:57 2008 +0000
+
+ Removed junk comments.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@6 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 2a070d8c8e3ea6ca24684a62016a46d928481eb7
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Tue Jul 1 06:11:21 2008 +0000
+
+ Update for file renames.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@5 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 64bcd594dd652d58133ec69659ed89c700e8964c
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Tue Jul 1 06:04:02 2008 +0000
+
+ Better named.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@4 abc39116-655e-4be6-ad55-d661dc543056
+
+commit eb7958574ce98601433022d7d23343025c1e34b8
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Tue Jul 1 06:01:21 2008 +0000
+
+ Project progressing along excellently. The python module is now functional and
+ has as many methods as the --type option takes.
+
+ Next is to expand and harness the code around the `--string' option.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@3 abc39116-655e-4be6-ad55-d661dc543056
+
+commit 4f5bfc68e416a7d1e6264e43278fe9b9df684eed
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Mon Jun 30 14:14:46 2008 +0000
+
+ Split out the module header into its own file.
+
+ Cleaned up Makefile a little.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@2 abc39116-655e-4be6-ad55-d661dc543056
+
+commit e7d6d472c21aa80c28be01c0d6dcbfd250d57a25
+Author: nima <nima@abc39116-655e-4be6-ad55-d661dc543056>
+Date: Mon Jun 30 12:08:58 2008 +0000
+
+ First commit to SVN.
+
+
+ git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@1 abc39116-655e-4be6-ad55-d661dc543056
diff --git a/dmidecode.py b/dmidecode.py
new file mode 100644
index 0000000..cd37b40
--- /dev/null
+++ b/dmidecode.py
@@ -0,0 +1,89 @@
+#
+# dmidecode.py
+# Module front-end for the python-dmidecode module.
+#
+# Copyright 2009 David Sommerseth <davids@redhat.com>
+#
+# 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; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# For the avoidance of doubt the "preferred form" of this code is one which
+# is in an open unpatent encumbered format. Where cryptographic key signing
+# forms part of the process of creating an executable the information
+# including keys needed to generate an equivalently functional executable
+# are deemed to be part of the source code.
+#
+
+import libxml2
+from dmidecodemod import *
+
+DMIXML_NODE='n'
+DMIXML_DOC='d'
+
+class dmidecodeXML:
+ "Native Python API for retrieving dmidecode information as XML"
+
+ def __init__(self):
+ self.restype = DMIXML_NODE;
+
+ def SetResultType(self, type):
+ """
+ Sets the result type of queries. The value can be DMIXML_NODE or DMIXML_DOC,
+ which will return an libxml2::xmlNode or libxml2::xmlDoc object, respectively
+ """
+
+ if type == DMIXML_NODE:
+ self.restype = DMIXML_NODE
+ elif type == DMIXML_DOC:
+ self.restype = DMIXML_DOC
+ else:
+ raise TypeError, "Invalid result type value"
+ return True
+
+ def QuerySection(self, sectname):
+ """
+ Queries the DMI data structure for a given section name. A section
+ can often contain several DMI type elements
+ """
+ if self.restype == DMIXML_NODE:
+ ret = libxml2.xmlNode( _obj = xmlapi(query_type='s',
+ result_type=self.restype,
+ section=sectname) )
+ elif self.restype == DMIXML_DOC:
+ ret = libxml2.xmlDoc( _obj = xmlapi(query_type='s',
+ result_type=self.restype,
+ section=sectname) )
+ else:
+ raise TypeError, "Invalid result type value"
+
+ return ret
+
+
+ def QueryTypeId(self, tpid):
+ """
+ Queries the DMI data structure for a specific DMI type.
+ """
+ if self.restype == DMIXML_NODE:
+ ret = libxml2.xmlNode( _obj = xmlapi(query_type='t',
+ result_type=self.restype,
+ typeid=tpid))
+ elif self.restype == DMIXML_DOC:
+ ret = libxml2.xmlDoc( _obj = xmlapi(query_type='t',
+ result_type=self.restype,
+ typeid=tpid))
+ else:
+ raise TypeError, "Invalid result type value"
+
+ return ret
+
diff --git a/doc/AUTHORS b/doc/AUTHORS
index 05475b7..b061b5d 100644
--- a/doc/AUTHORS
+++ b/doc/AUTHORS
@@ -1,15 +1,21 @@
DEVELOPER AND MAINTAINER OF PYTHON MODULE (http://projects.autonomy.net.au/dmidecode)
-Nima Talebi <nima@it.net.au>
+ Nima Talebi <nima@it.net.au>
+ David Sommerseth <davids@redhat.com>
DEVELOPER AND MAINTAINER OF DMIDECODE (Please see http://www.nongnu.org/dmidecode)
-Jean Delvare <khali@linux-fr.org>
+ Jean Delvare <khali@linux-fr.org>
ORIGINAL AUTHOR
-Alan Cox <alan@redhat.com>
+ Alan Cox <alan@redhat.com>
-MANY THANKS TO (IN CHRONOLOGICAL ORDER)
-Jean Delvare <khali@linux-fr.org>
-Stephen Darragh <srd@it.net.au>
-Joel Heenan <joel.heenan@det.nsw.edu.au>
-Vaughan Whitteron <vaughan.whitteron@det.nsw.edu.au>
-Justin Cook
+MANY THANKS TO (IN REVERSE CHRONOLOGICAL ORDER)
+ Richard Fontana
+ Daniel Veillard
+ David Sommerseth <davids@redhat.com>
+ Clark Williams <williams@redhat.com>
+ Christoph Haas <haas@debian.org>
+ Jean Delvare <khali@linux-fr.org>
+ Vaughan Whitteron <vaughan.whitteron@det.nsw.edu.au>
+ Joel Heenan <joel.heenan@det.nsw.edu.au>
+ Stephen Darragh <srd@it.net.au>
+ Justin Cook
diff --git a/doc/LICENSE b/doc/LICENSE
index 94a0453..d511905 100644
--- a/doc/LICENSE
+++ b/doc/LICENSE
@@ -1,621 +1,339 @@
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
- Preamble
+ Preamble
- The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users. We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors. You can apply it to
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
- To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights. Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received. You must make sure that they, too, receive
-or can get the source code. And you must show them these terms so they
-know their rights.
-
- Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
- For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software. For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
- Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so. This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software. The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable. Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products. If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
- Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary. To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
this License.
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If conditions are imposed on you (whether by court order, agreement or
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Use with the GNU Affero General Public License.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time. Such new versions will
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
- Each version is given a distinguishing version number. If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/doc/dmidump.py b/doc/dmidump.py
deleted file mode 100755
index a6c7bf7..0000000
--- a/doc/dmidump.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/env python2.4
-import dmidecode
-import sys
-from pprint import pprint
-
-#. Test all functions using /dev/mem...
-print "*** bios ***\n"; dmidecode.bios()
-print "*** system ***\n"; dmidecode.system()
-print "*** system ***\n"; dmidecode.system()
-print "*** baseboard ***\n"; dmidecode.baseboard()
-print "*** chassis ***\n"; dmidecode.chassis()
-print "*** processor ***\n"; dmidecode.processor()
-print "*** memory ***\n"; dmidecode.memory()
-print "*** cache ***\n"; dmidecode.cache()
-print "*** connector ***\n"; dmidecode.connector()
-print "*** slot ***\n"; dmidecode.slot()
-
-#. Now test get/set of memory device file...
-print dmidecode.get_dev()
-print dmidecode.set_dev("private/mem-XXX");
-print dmidecode.get_dev()
-
-#. Test taking a dump...
-print dmidecode.dump()
-
-#. Test reading the dump...
-print "*** bios ***\n"; pprint(dmidecode.bios())
-print "*** system ***\n"; pprint(dmidecode.system())
-print "*** system ***\n"; pprint(dmidecode.system())
-print "*** baseboard ***\n"; pprint(dmidecode.baseboard())
-print "*** chassis ***\n"; pprint(dmidecode.chassis())
-print "*** processor ***\n"; pprint(dmidecode.processor())
-print "*** memory ***\n"; pprint(dmidecode.memory())
-print "*** cache ***\n"; pprint(dmidecode.cache())
-print "*** connector ***\n"; pprint(dmidecode.connector())
-print "*** slot ***\n"; pprint(dmidecode.slot())
-
-sys.exit(0)
-print "*** bios ***\n"; pprint(dmidecode.bios())
-print "*** system ***\n"; pprint(dmidecode.system())
-print "*** baseboard ***\n"; pprint(dmidecode.baseboard())
-print "*** chassis ***\n"; pprint(dmidecode.chassis())
-print "*** processor ***\n"; pprint(dmidecode.processor())
-print "*** memory ***\n"; pprint(dmidecode.memory())
-print "*** cache ***\n"; pprint(dmidecode.cache())
-print "*** connector ***\n"; pprint(dmidecode.connector())
-print "*** slot ***\n"; pprint(dmidecode.slot())
-
-for v in dmidecode.memory().values():
- if type(v) == dict and v['dmi_type'] == 17:
- pprint(v['data']['Size']),
-
-pprint(dmidecode.type('3'))
-pprint(dmidecode.type('bios'))
diff --git a/examples/dmidump.py b/examples/dmidump.py
index 161da44..a6c7bf7 100755
--- a/examples/dmidump.py
+++ b/examples/dmidump.py
@@ -3,6 +3,26 @@ import dmidecode
import sys
from pprint import pprint
+#. Test all functions using /dev/mem...
+print "*** bios ***\n"; dmidecode.bios()
+print "*** system ***\n"; dmidecode.system()
+print "*** system ***\n"; dmidecode.system()
+print "*** baseboard ***\n"; dmidecode.baseboard()
+print "*** chassis ***\n"; dmidecode.chassis()
+print "*** processor ***\n"; dmidecode.processor()
+print "*** memory ***\n"; dmidecode.memory()
+print "*** cache ***\n"; dmidecode.cache()
+print "*** connector ***\n"; dmidecode.connector()
+print "*** slot ***\n"; dmidecode.slot()
+
+#. Now test get/set of memory device file...
+print dmidecode.get_dev()
+print dmidecode.set_dev("private/mem-XXX");
+print dmidecode.get_dev()
+
+#. Test taking a dump...
+print dmidecode.dump()
+
#. Test reading the dump...
print "*** bios ***\n"; pprint(dmidecode.bios())
print "*** system ***\n"; pprint(dmidecode.system())
@@ -15,4 +35,20 @@ print "*** cache ***\n"; pprint(dmidecode.cache())
print "*** connector ***\n"; pprint(dmidecode.connector())
print "*** slot ***\n"; pprint(dmidecode.slot())
-_=[dmidecode.type(_) and pprint(dmidecode.type(_)) for _ in range(1,128)]
+sys.exit(0)
+print "*** bios ***\n"; pprint(dmidecode.bios())
+print "*** system ***\n"; pprint(dmidecode.system())
+print "*** baseboard ***\n"; pprint(dmidecode.baseboard())
+print "*** chassis ***\n"; pprint(dmidecode.chassis())
+print "*** processor ***\n"; pprint(dmidecode.processor())
+print "*** memory ***\n"; pprint(dmidecode.memory())
+print "*** cache ***\n"; pprint(dmidecode.cache())
+print "*** connector ***\n"; pprint(dmidecode.connector())
+print "*** slot ***\n"; pprint(dmidecode.slot())
+
+for v in dmidecode.memory().values():
+ if type(v) == dict and v['dmi_type'] == 17:
+ pprint(v['data']['Size']),
+
+pprint(dmidecode.type('3'))
+pprint(dmidecode.type('bios'))
diff --git a/examples/test.py b/examples/test.py
deleted file mode 100755
index 79f11d3..0000000
--- a/examples/test.py
+++ /dev/null
@@ -1,112 +0,0 @@
-#!/usr/bin/env python
-#.awk '$0 ~ /case [0-9]+: .. 3/ { sys.stdout.write($2 }' src/dmidecode.c|tr ':\n' ', '
-
-from pprint import pprint
-import os, sys, random, tempfile, time
-import commands
-
-dmidecode = True in [os.path.exists(os.path.join(_, "dmidecode")) for _ in os.getenv("PATH").split(':')]
-if dmidecode:
- print "Please install `dmidecode' (the binary) for complete testing."
-
-FH, DUMP = tempfile.mkstemp()
-os.unlink(DUMP)
-os.close(FH)
-
-total = 0
-success = 0
-
-def test(r):
- global total
- global success
-
- total += 1
- if r:
- sys.stdout.write("Good\n")
- success += 1
- return True
- else:
- sys.stdout.write("FAILED\n")
- return False
-
-total += 1
-print "-"*80
-sys.stdout.write("Importing module...")
-try:
- import dmidecode
- success += 1
- sys.stdout.write("Done\n")
- sys.stdout.write(" * Version: %s\n"%dmidecode.version)
- sys.stdout.write(" * DMI Version String: %s\n"%dmidecode.dmi)
-
- print "-"*80
- sys.stdout.write("Testing that default device is /dev/mem...")
- test(dmidecode.get_dev() == "/dev/mem")
-
- sys.stdout.write("Testing that write-lock will not break on dump()...")
- test(not dmidecode.dump())
-
- sys.stdout.write("Testing ability to change device to %s..."%DUMP)
- test(dmidecode.set_dev(DUMP))
-
- sys.stdout.write("Testing that device has changed to %s..."%DUMP)
- test(dmidecode.get_dev() == DUMP)
-
- sys.stdout.write("Testing that write on new file is ok...")
- test(dmidecode.dump())
-
- sys.stdout.write("Testing that file was actually written...")
- time.sleep(0.1)
- test(os.path.exists(DUMP))
- os.unlink(DUMP)
-
- types = range(0, 42)+range(126, 128)
- bad_types = [-1, -1000, 256]
- sections = ["bios", "system", "baseboard", "chassis", "processor", "memory", "cache", "connector", "slot"]
- devices = []
- if os.path.exists("private"):
- devices.extend([os.path.join("private", _) for _ in os.listdir("private")])
- devices.remove('private/.svn')
- else:
- sys.stdout.write("If you have memory dumps to test, create a directory called `private' and drop them in there.\n")
- devices.append("/dev/mem")
- random.shuffle(types)
- random.shuffle(devices)
- random.shuffle(sections)
-
- for dev in devices:
- sys.stdout.write(" * Testing %s..."%dev); sys.stdout.flush()
- if test(dmidecode.set_dev(dev) and dmidecode.get_dev() == dev):
- print "-"*80
- print sections
- for section in sections:
- sys.stdout.write(" * Testing %s..."%section); sys.stdout.flush()
- output = getattr(dmidecode, section)()
- test(output is not False)
- if output: sys.stdout.write(" * %s\n"%output.keys())
-
- print "-"*80
- for i in bad_types:
- sys.stdout.write(" * Testing bad type %i..."%i); sys.stdout.flush()
- try:
- output = dmidecode.type(i)
- test(output is False)
- except SystemError:
- sys.stdout.write("FAILED\n")
-
- print "-"*80
- for i in types:
- sys.stdout.write(" * Testing type %i..."%i); sys.stdout.flush()
- output = dmidecode.type(i)
- if dmidecode:
- _output = commands.getoutput("dmidecode -t %d"%i).strip().split('\n')
- test(len(_output) == 1 and len(output) == 0 or True)
- else:
- test(output is not False)
- if output:
- sys.stdout.write(" * %s\n"%output.keys())
-
-except ImportError:
- sys.stdout.write("FAILED\n")
-
-sys.stdout.write("Score: %d/%d\n"%(success, total))
diff --git a/python-dmidecode.spec b/python-dmidecode.spec
deleted file mode 100644
index bee613c..0000000
--- a/python-dmidecode.spec
+++ /dev/null
@@ -1,44 +0,0 @@
-%{!?python_sitearch: %define python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")}
-%{!?python_ver: %define python_ver %(%{__python} -c "import sys ; print sys.version[:3]")}
-
-Summary: python extension module to access DMI data
-Name: python-dmidecode
-Version: 2.10
-Release: 1
-License: GPLv3
-Group: System Environment/Libraries
-URL: http://projects.autonomy.net.au/dmidecode/
-Source0: %{name}-%{version}.tar.gz
-BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
-
-%description
-python-dmidecode is a python extension module that uses the
-code-base of the 'dmidecode' utility, and presents the data
-as python data structures
-
-%prep
-%setup -q
-
-%build
-make
-
-%install
-rm -rf $RPM_BUILD_ROOT
-python src/setup.py install --root $RPM_BUILD_ROOT
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-
-%files
-%defattr(-,root,root,-)
-%doc
-%{python_sitearch}/dmidecode.so
-%if "%{python_ver}" >= "2.5"
-%{python_sitearch}/*.egg-info
-%endif
-
-%changelog
-* Sat Mar 7 2009 Clark Williams <williams@redhat.com> - 2.10.3-1
-- Initial build.
-
diff --git a/src/config.h b/src/config.h
index c1d7d03..2876788 100644
--- a/src/config.h
+++ b/src/config.h
@@ -1,4 +1,39 @@
/*
+ * © 2007-2009 Nima Talebi <nima@autonomy.net.au>
+ * © 2009 David Sommerseth <davids@redhat.com>
+ *
+ * This file is part of Python DMI-Decode.
+ *
+ * Python DMI-Decode 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, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Python DMI-Decode is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Python DMI-Decode. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ADAPTED M. STONE & T. PARKER DISCLAIMER: THIS SOFTWARE COULD RESULT IN INJURY
+ * AND/OR DEATH, AND AS SUCH, IT SHOULD NOT BE BUILT, INSTALLED OR USED BY ANYONE.
+ *
+ */
+
+/*
* Configuration
*/
@@ -22,4 +57,8 @@
#define ALIGNMENT_WORKAROUND
#endif
+#ifndef PYTHON_XML_MAP
+#define PYTHON_XML_MAP "/usr/share/python-dmidecode/pymap.xml"
+#endif
+
#endif
diff --git a/src/dmidecode.c b/src/dmidecode.c
index bbf05cf..aa2332d 100644
--- a/src/dmidecode.c
+++ b/src/dmidecode.c
@@ -1,30 +1,48 @@
+
+/*. ******* coding:utf-8 AUTOHEADER START v1.1 *******
+ *. vim: fileencoding=utf-8 syntax=c sw=2 ts=2 et
+ *.
+ *. © 2007-2009 Nima Talebi <nima@autonomy.net.au>
+ *. © 2009 David Sommerseth <davids@redhat.com>
+ *. © 2002-2008 Jean Delvare <khali@linux-fr.org>
+ *. © 2000-2002 Alan Cox <alan@redhat.com>
+ *.
+ *. This file is part of Python DMI-Decode.
+ *.
+ *. Python DMI-Decode 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, either version 2 of the License, or
+ *. (at your option) any later version.
+ *.
+ *. Python DMI-Decode is distributed in the hope that it will be useful,
+ *. but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *. GNU General Public License for more details.
+ *.
+ *. You should have received a copy of the GNU General Public License
+ *. along with Python DMI-Decode. If not, see <http://www.gnu.org/licenses/>.
+ *.
+ *. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *. WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *. MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ *. EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ *. PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ *. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ *. OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ *. ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *.
+ *. ADAPTED M. STONE & T. PARKER DISCLAIMER: THIS SOFTWARE COULD RESULT IN INJURY
+ *. AND/OR DEATH, AND AS SUCH, IT SHOULD NOT BE BUILT, INSTALLED OR USED BY ANYONE.
+ *.
+ *. $AutoHeaderSerial::20090522 $
+ *. ******* AUTOHEADER END v1.1 ******* */
+
/*
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* DMI Decode
*
- * Copyright 2000-2002 Alan Cox <alan@redhat.com>
- * Copyright 2002-2008 Jean Delvare <khali@linux-fr.org>
- *
- * 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; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * For the avoidance of doubt the "preferred form" of this code is one which
- * is in an open unpatent encumbered format. Where cryptographic key signing
- * forms part of the process of creating an executable the information
- * including keys needed to generate an equivalently functional executable
- * are deemed to be part of the source code.
- *
* Unless specified otherwise, all references are aimed at the "System
* Management BIOS Reference Specification, Version 2.6" document,
* available from http://www.dmtf.org/standards/smbios/.
@@ -49,334 +67,384 @@
* - BIOS Integrity Services Application Programming Interface version 1.0
* http://www.intel.com/design/archives/wfm/downloads/bisspec.htm
*
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * DMI Decode Python Module (Extension)
- *
- * Copyright: 2007-2008 Nima Talebi <nima@autonomy.net.au>
- * License: GPLv3
- *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
-#include <Python.h>
-
-/*
-#undef NDEBUG
#include <assert.h>
-*/
-
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
+#include <libxml/tree.h>
#include "version.h"
#include "config.h"
#include "types.h"
#include "util.h"
+#include "dmixml.h"
#include "dmidecode.h"
#include "dmioem.h"
+#include "efi.h"
+#include "dmidump.h"
#include "dmihelper.h"
-#define EFI_NOT_FOUND (-1)
-#define EFI_NO_SMBIOS (-2)
-
-static const char *out_of_spec = "<OUT OF SPEC>";
-static const char *bad_index = "<BAD INDEX>";
-#define BAD_INDEX PyString_FromString("<BAD INDEX>")
-#define OUT_OF_SPEC PyString_FromString("<OUT OF SPEC>")
-
/*******************************************************************************
** Type-independant Stuff
*/
-static PyObject *dmi_string_py(const struct dmi_header *dm, u8 s) {
- char *bp=(char *)dm->data;
- size_t i, len;
-
- PyObject *data;
-
- if(s==0) data = PyString_FromString("Not Specified");
- else {
- bp += dm->length;
- while(s>1 && *bp) { bp += strlen(bp); bp++; s--; }
-
- if(!*bp) data = BAD_INDEX;
- else {
- /* ASCII filtering */
- len=strlen(bp);
- for(i=0; i<len; i++)
- if(bp[i]<32 || bp[i]==127)
- bp[i]='.';
- data = PyString_FromString(bp);
- }
- }
- return data;
-}
-
-const char *dmi_string(const struct dmi_header *dm, u8 s) {
- char *bp = (char *)dm->data;
- size_t i, len;
-
- if(s == 0) return "Not Specified";
-
- bp += dm->length;
- while(s>1 && *bp) {
- bp+=strlen(bp);
- bp++;
- s--;
- }
-
- if(!*bp) return bad_index;
-
- /* ASCII filtering */
- len = strlen(bp);
- for(i=0; i<len; i++)
- if(bp[i]<32 || bp[i]==127)
- bp[i]='.';
-
- return bp;
-}
-
-
-
-
-static const char *dmi_smbios_structure_type(u8 code) {
- static const char *type[] = {
- "BIOS", /* 0 */
- "System",
- "Base Board",
- "Chassis",
- "Processor",
- "Memory Controller",
- "Memory Module",
- "Cache",
- "Port Connector",
- "System Slots",
- "On Board Devices",
- "OEM Strings",
- "System Configuration Options",
- "BIOS Language",
- "Group Associations",
- "System Event Log",
- "Physical Memory Array",
- "Memory Device",
- "32-bit Memory Error",
- "Memory Array Mapped Address",
- "Memory Device Mapped Address",
- "Built-in Pointing Device",
- "Portable Battery",
- "System Reset",
- "Hardware Security",
- "System Power Controls",
- "Voltage Probe",
- "Cooling Device",
- "Temperature Probe",
- "Electrical Current Probe",
- "Out-of-band Remote Access",
- "Boot Integrity Services",
- "System Boot",
- "64-bit Memory Error",
- "Management Device",
- "Management Device Component",
- "Management Device Threshold Data",
- "Memory Channel",
- "IPMI Device",
- "Power Supply" /* 39 */
- };
-
- if(code<=39) return(type[code]);
- return out_of_spec;
-}
-
-static int dmi_bcd_range(u8 value, u8 low, u8 high) {
- if(value>0x99 || (value&0x0F)>0x09) return 0;
- if(value<low || value>high) return 0;
- return 1;
-}
-
-PyObject* dmi_dump(struct dmi_header *h) {
- int row, i;
- const char *s;
-
- PyObject *data = PyDict_New();
- PyObject *data1 = PyList_New(0);
- for(row=0; row<((h->length-1)>>4)+1; row++) {
- for(i=0; i<16 && i<h->length-(row<<4); i++)
- PyList_Append(data1, PyString_FromFormat("0x%02x", (h->data)[(row<<4)+i]));
- }
- PyDict_SetItemString(data, "Header and Data", data1);
-
- if((h->data)[h->length] || (h->data)[h->length+1]) {
- i=1;
- PyObject *data2 = PyList_New(0);
- while((s=dmi_string(h, i++))!=bad_index) {
- //. FIXME: DUMP
- /*
- if(opt.flags & FLAG_DUMP) {
- int j, l = strlen(s)+1;
- for(row=0; row<((l-1)>>4)+1; row++) {
- for(j=0; j<16 && j<l-(row<<4); j++)
- PyList_Append(data1, PyString_FromFormat("0x%02x", s[(row<<4)+j]));
- }
- fprintf(stderr, "\"%s\"|", s);
- }
- else fprintf(stderr, "%s|", s);
- */
- PyList_Append(data1, PyString_FromFormat("%s", s));
- }
- PyDict_SetItemString(data, "Strings", data2);
- }
- return data;
+const char *dmi_string(const struct dmi_header *dm, u8 s)
+{
+ char *bp = (char *)dm->data;
+ size_t i, len;
+
+ if(s == 0)
+ return "Not Specified";
+
+ bp += dm->length;
+ while(s > 1 && *bp) {
+ bp += strlen(bp);
+ bp++;
+ s--;
+ }
+
+ if(!*bp)
+ return NULL;
+
+ /* ASCII filtering */
+ len = strlen(bp);
+ for(i = 0; i < len; i++)
+ if(bp[i] < 32 || bp[i] == 127)
+ bp[i] = '.';
+
+ return bp;
+}
+
+xmlNode *dmi_smbios_structure_type(xmlNode *node, u8 code)
+{
+ static struct {
+ const char *descr;
+ const char *tagname;
+ const char *attrname;
+ const char *attrvalue;
+ } types[] = {
+ /* *INDENT-OFF* */
+ {"BIOS", "BIOS", NULL, NULL}, /* 0 */
+ {"System", "System", NULL, NULL},
+ {"Base Board", "BaseBoard", NULL, NULL},
+ {"Chassis", "Chassis", NULL, NULL},
+ {"Processor", "Processor", NULL, NULL},
+ {"Memory Controller", "Memory", "type", "controller"},
+ {"Memory Module", "Memory", "type", "module"},
+ {"Cache", "Cache", NULL, NULL},
+ {"Port Connector", "PortConnectors", NULL, NULL},
+ {"System Slots", "Slots", NULL, NULL},
+ {"On Board Devices", "OnBoardDevices", NULL, NULL},
+ {"OEM Strings", "OEMstrings", NULL, NULL},
+ {"System Configuration Options", "SysConfigOpts", NULL, NULL},
+ {"BIOS Language", "BIOS", "type", "language"},
+ {"Group Associations", "GroupAssociations", NULL, NULL},
+ {"System Event Log", "EventLog", NULL, NULL},
+ {"Physical Memory Array", "PhysicalMemoryArray", NULL, NULL},
+ {"Memory Device", "Memory", "type", "device"},
+ {"32-bit Memory Error", "MemoryError", "bit", "32"},
+ {"Memory Array Mapped Address", "MemoryAddressMap", "type", "MemoryArray"},
+ {"Memory Device Mapped Address", "MemoryAddressMap", "type", "Device"},
+ {"Built-in Pointing Device", "BuiltinPointingDevice",NULL, NULL},
+ {"Portable Battery", "PortableBattery", NULL, NULL},
+ {"System Reset", "SystemReset", NULL, NULL},
+ {"Hardware Security", "HWsecurity", NULL, NULL},
+ {"System Power Controls", "SysPowerCtrl", NULL, NULL},
+ {"Voltage Probe", "Probe", "type", "Voltage"},
+ {"Cooling Device", "CoolingDevice", NULL, NULL},
+ {"Temperature Probe", "Probe", "type", "Temperature"},
+ {"Electrical Current Probe", "Probe", "type", "ElectricalCurrent"},
+ {"Out-of-band Remote Access", "RemoteAccess", NULL, NULL},
+ {"Boot Integrity Services", "BootIntegritySrv", NULL, NULL},
+ {"System Boot", "SystemBoot", NULL, NULL},
+ {"64-bit Memory Error", "MemoryError", "bit", "64"},
+ {"Management Device", "ManagementDevice", NULL, NULL},
+ {"Management Device Component", "ManagementDevice", "type", "component"},
+ {"Management Device Threshold Data","ManagementDevice", "type", "Threshold Data"},
+ {"Memory Channel", "MemoryChannel", NULL, NULL},
+ {"IPMI Device", "IPMIdevice", NULL, NULL},
+ {"Power Supply", "PowerSupply", NULL, NULL} /* 39 */
+ /* *INDENT-ON* */
+ };
+ xmlNode *type_n = NULL;
+
+ if(code <= 39) {
+ type_n = xmlNewChild(node, NULL, (xmlChar *)types[code].tagname, NULL);
+ assert( type_n != NULL );
+
+ dmixml_AddAttribute(type_n, "flags", "0x%04x", code);
+ dmixml_AddTextChild(type_n, "Description", "%s", types[code].descr);
+
+ if( (types[code].attrname != NULL) && (types[code].attrvalue != NULL) ) {
+ dmixml_AddAttribute(type_n, types[code].attrname, "%s", types[code].attrvalue);
+ }
+ } else {
+ type_n = xmlNewChild(node, NULL, (xmlChar *) "UnknownSMBiosType", NULL);
+ dmixml_AddAttribute(type_n, "flags", "0x%04x", code);
+ }
+
+ return type_n;
+}
+
+static int dmi_bcd_range(u8 value, u8 low, u8 high)
+{
+ if(value > 0x99 || (value & 0x0F) > 0x09)
+ return 0;
+ if(value < low || value > high)
+ return 0;
+ return 1;
+}
+
+void dmi_dump(xmlNode *node, struct dmi_header * h)
+{
+ int row, i;
+ const char *s;
+ xmlNode *dump_n = NULL, *row_n = NULL;
+ char *tmp_s = NULL;
+
+ dump_n = xmlNewChild(node, NULL, (xmlChar *) "HeaderAndData", NULL);
+ assert( dump_n != NULL );
+
+ tmp_s = (char *) malloc((h->length * 2) + 2);
+ for(row = 0; row < ((h->length - 1) >> 4) + 1; row++) {
+ memset(tmp_s, 0, (h->length * 2) + 2);
+
+ for(i = 0; i < (16 && i < h->length - (row << 4)); i++) {
+ snprintf(tmp_s + strlen(tmp_s), (h->length * 2)-strlen(tmp_s),
+ "0x%02x", (h->data)[(row << 4) + i]);
+ }
+ row_n = dmixml_AddTextChild(dump_n, "Row", "%s", tmp_s);
+ dmixml_AddAttribute(row_n, "index", "%i", row);
+ row_n = NULL;
+ }
+ free(tmp_s); tmp_s = NULL;
+ dump_n = NULL;
+
+ dump_n = xmlNewChild(node, NULL, (xmlChar *) "Strings", NULL);
+ assert( dump_n != NULL );
+
+ if((h->data)[h->length] || (h->data)[h->length + 1]) {
+ i = 1;
+ while((s = dmi_string(h, i++)) != NULL) {
+ //. FIXME: DUMP
+ /*
+ * opt->flags will need to be transported to the function somehow
+ * when this feature is implemented completely.
+ *
+ * if(opt->flags & FLAG_DUMP) {
+ * int j, l = strlen(s)+1;
+ * for(row=0; row<((l-1)>>4)+1; row++) {
+ * for(j=0; j<16 && j<l-(row<<4); j++)
+ * PyList_Append(data1, PyString_FromFormat("0x%02x", s[(row<<4)+j]));
+ * }
+ * fprintf(stderr, "\"%s\"|", s);
+ * }
+ * else fprintf(stderr, "%s|", s);
+ */
+ row_n = dmixml_AddTextChild(dump_n, "String", "%s", s);
+ dmixml_AddAttribute(row_n, "index", "%i", i);
+ row_n = NULL;
+ }
+ }
+ dump_n = NULL;
}
/*******************************************************************************
** 3.3.1 BIOS Information (Type 0)
*/
-static PyObject* dmi_bios_runtime_size(u32 code) {
- if(code&0x000003FF) return PyString_FromFormat("%i bytes", code);
- else return PyString_FromFormat("%i kB", code>>10);
+void dmi_bios_runtime_size(xmlNode *node, u32 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "RuntimeSize", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code & 0x000003FF) {
+ dmixml_AddAttribute(data_n, "unit", "bytes");
+ dmixml_AddTextContent(data_n, "%i", code);
+ } else {
+ dmixml_AddAttribute(data_n, "unit", "KB");
+ dmixml_AddTextContent(data_n, "%i", code >> 10);
+ }
}
/* 3.3.1.1 */
-static PyObject* dmi_bios_characteristics(u64 code) {
- static const char *characteristics[] = {
- "BIOS characteristics not supported", /* 3 */
- "ISA is supported",
- "MCA is supported",
- "EISA is supported",
- "PCI is supported",
- "PC Card (PCMCIA) is supported",
- "PNP is supported",
- "APM is supported",
- "BIOS is upgradeable",
- "BIOS shadowing is allowed",
- "VLB is supported",
- "ESCD support is available",
- "Boot from CD is supported",
- "Selectable boot is supported",
- "BIOS ROM is socketed",
- "Boot from PC Card (PCMCIA) is supported",
- "EDD is supported",
- "Japanese floppy for NEC 9800 1.2 MB is supported (int 13h)",
- "Japanese floppy for Toshiba 1.2 MB is supported (int 13h)",
- "5.25\"/360 KB floppy services are supported (int 13h)",
- "5.25\"/1.2 MB floppy services are supported (int 13h)",
- "3.5\"/720 KB floppy services are supported (int 13h)",
- "3.5\"/2.88 MB floppy services are supported (int 13h)",
- "Print screen service is supported (int 5h)",
- "8042 keyboard services are supported (int 9h)",
- "Serial services are supported (int 14h)",
- "Printer services are supported (int 17h)",
- "CGA/mono video services are supported (int 10h)",
- "NEC PC-98" /* 31 */
- };
-
- PyObject *data;
- if(code.l&(1<<3)) {
- data = PyString_FromString(characteristics[0]);
- } else {
- int i;
- data = PyDict_New();
- for(i=4; i<=31; i++)
- PyDict_SetItemString(data, characteristics[i-3], code.l&(1<<i)?Py_True:Py_False);
- }
- return data;
+void dmi_bios_characteristics(xmlNode *node, u64 code)
+{
+ static const char *characteristics[] = {
+ "BIOS characteristics not supported", /* 3 */
+ "ISA is supported",
+ "MCA is supported",
+ "EISA is supported",
+ "PCI is supported",
+ "PC Card (PCMCIA) is supported",
+ "PNP is supported",
+ "APM is supported",
+ "BIOS is upgradeable",
+ "BIOS shadowing is allowed",
+ "VLB is supported",
+ "ESCD support is available",
+ "Boot from CD is supported",
+ "Selectable boot is supported",
+ "BIOS ROM is socketed",
+ "Boot from PC Card (PCMCIA) is supported",
+ "EDD is supported",
+ "Japanese floppy for NEC 9800 1.2 MB is supported (int 13h)",
+ "Japanese floppy for Toshiba 1.2 MB is supported (int 13h)",
+ "5.25\"/360 KB floppy services are supported (int 13h)",
+ "5.25\"/1.2 MB floppy services are supported (int 13h)",
+ "3.5\"/720 KB floppy services are supported (int 13h)",
+ "3.5\"/2.88 MB floppy services are supported (int 13h)",
+ "Print screen service is supported (int 5h)",
+ "8042 keyboard services are supported (int 9h)",
+ "Serial services are supported (int 14h)",
+ "Printer services are supported (int 17h)",
+ "CGA/mono video services are supported (int 10h)",
+ "NEC PC-98" /* 31 */
+ };
+ dmixml_AddAttribute(node, "dmispec", "3.3.1.1");
+ dmixml_AddAttribute(node, "flags", "0x%04x", code);
+
+ if(code.l&(1<<3)) {
+ dmixml_AddAttribute(node, "unavailable", "1");
+ dmixml_AddTextContent(node, characteristics[0]);
+ } else {
+ int i = 0;
+ xmlNode *flags_n = xmlNewChild(node, NULL, (xmlChar *) "flags", NULL);
+ assert( flags_n != NULL );
+
+ for(i = 4; i <= 31; i++) {
+ xmlNode *flg_n = dmixml_AddTextChild(flags_n, "flag", characteristics[i - 3]);
+ dmixml_AddAttribute(flg_n, "enabled", "%i", (code.l & (1 << i) ? 1 : 0 ));
+ }
+ }
}
/* 3.3.1.2.1 */
-static PyObject* dmi_bios_characteristics_x1(u8 code) {
- static const char *characteristics[] = {
- "ACPI", /* 0 */
- "USB legacy",
- "AGP",
- "I2O boot",
- "LS-120 boot",
- "ATAPI Zip drive boot",
- "IEEE 1394 boot",
- "Smart battery" /* 7 */
- };
-
- int i;
- PyObject *data = PyDict_New();
- for(i=0; i<=7; i++)
- PyDict_SetItemString(data, characteristics[i], code&(1<<i)?Py_True:Py_False);
- return data;
-
+void dmi_bios_characteristics_x1(xmlNode *node, u8 code)
+{
+ int i = 0;
+ static const char *characteristics[] = {
+ "ACPI", /* 0 */
+ "USB legacy",
+ "AGP",
+ "I2O boot",
+ "LS-120 boot",
+ "ATAPI Zip drive boot",
+ "IEEE 1394 boot",
+ "Smart battery" /* 7 */
+ };
+
+ dmixml_AddAttribute(node, "dmispec", "3.3.1.2.1");
+ dmixml_AddAttribute(node, "flags", "0x%04x", code);
+
+ for(i = 0; i <= 7; i++) {
+ xmlNode *chr_n = dmixml_AddTextChild(node, "characteristic", characteristics[i]);
+ dmixml_AddAttribute(chr_n, "enabled", "%i", (code & (1 << i) ? 1: 0));
+ }
}
/* 3.3.1.2.2 */
-static PyObject* dmi_bios_characteristics_x2(u8 code) {
- static const char *characteristics[]={
- "BIOS boot specification", /* 0 */
- "Function key-initiated network boot",
- "Targeted content distribution" /* 2 */
- };
-
- int i;
- PyObject *data = PyDict_New();
- for(i=0; i<=2; i++)
- PyDict_SetItemString(data, characteristics[i], code&(1<<i)?Py_True:Py_False);
- return data;
+void dmi_bios_characteristics_x2(xmlNode *node, u8 code)
+{
+ int i = 0;
+ static const char *characteristics[] = {
+ "BIOS boot specification", /* 0 */
+ "Function key-initiated network boot",
+ "Targeted content distribution" /* 2 */
+ };
+
+ dmixml_AddAttribute(node, "dmispec", "3.3.1.2.2");
+ dmixml_AddAttribute(node, "flags", "0x%04x", code);
+
+ for(i = 0; i <= 2; i++) {
+ xmlNode *chr_n = dmixml_AddTextChild(node, "characteristic", characteristics[i]);
+ dmixml_AddAttribute(chr_n, "enabled", "%i", (code & (1 << i) ? 1: 0));
+ }
}
/*******************************************************************************
** 3.3.2 System Information (Type 1)
*/
-PyObject *dmi_system_uuid_py(const u8 *p, u16 ver) {
- int only0xFF=1, only0x00=1;
- int i;
-
- for(i=0; i<16 && (only0x00 || only0xFF); i++) {
- if(p[i]!=0x00) only0x00=0;
- if(p[i]!=0xFF) only0xFF=0;
- }
-
- if(only0xFF)
- return PyString_FromString("Not Present");
-
- if(only0x00)
- return PyString_FromString("Not Settable");
-
- /*
- * As off version 2.6 of the SMBIOS specification, the first 3
- * fields of the UUID are supposed to be encoded on little-endian.
- * The specification says that this is the defacto standard,
- * however I've seen systems following RFC 4122 instead and use
- * network byte order, so I am reluctant to apply the byte-swapping
- * for older versions.
- */
- if (ver >= 0x0206)
- return PyString_FromFormat("%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
- p[3], p[2], p[1], p[0], p[5], p[4], p[7], p[6],
- p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]
- );
- else
- return PyString_FromFormat("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
- p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
- p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]
- );
+void dmi_system_uuid(xmlNode *node, const u8 * p, u16 ver)
+{
+ int only0xFF = 1, only0x00 = 1;
+ int i;
+ xmlNode *uuid_n = NULL;
+
+ for(i = 0; i < 16 && (only0x00 || only0xFF); i++) {
+ if(p[i] != 0x00)
+ only0x00 = 0;
+ if(p[i] != 0xFF)
+ only0xFF = 0;
+ }
+
+ uuid_n = xmlNewChild(node, NULL, (xmlChar *) "SystemUUID", NULL);
+ dmixml_AddAttribute(uuid_n, "dmispec", "3.3.2");
+
+ if(only0xFF ) {
+ dmixml_AddAttribute(uuid_n, "unavailable", "1");
+ dmixml_AddTextContent(uuid_n, "Not Present");
+ return;
+ }
+
+ if(only0x00){
+ dmixml_AddAttribute(uuid_n, "unavailable", "1");
+ dmixml_AddTextContent(uuid_n,"Not Settable");
+ return;
+ }
+
+ /*
+ * As off version 2.6 of the SMBIOS specification, the first 3
+ * fields of the UUID are supposed to be encoded on little-endian.
+ * The specification says that this is the defacto standard,
+ * however I've seen systems following RFC 4122 instead and use
+ * network byte order, so I am reluctant to apply the byte-swapping
+ * for older versions.
+ */
+ if(ver >= 0x0206) {
+ dmixml_AddTextContent(uuid_n,
+ "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
+ p[3], p[2], p[1], p[0], p[5], p[4], p[7], p[6], p[8], p[9], p[10],
+ p[11], p[12], p[13], p[14], p[15]);
+ } else {
+ dmixml_AddTextContent(uuid_n,
+ "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10],
+ p[11], p[12], p[13], p[14], p[15]);
+ }
}
/* 3.3.2.1 */
-static PyObject *dmi_system_wake_up_type(u8 code) {
- static const char *type[]={
- "Reserved", /* 0x00 */
- "Other",
- "Unknown",
- "APM Timer",
- "Modem Ring",
- "LAN Remote",
- "Power Switch",
- "PCI PME#",
- "AC Power Restored" /* 0x08 */
- };
-
- if(code<=0x08) return PyString_FromString(type[code]);
- return OUT_OF_SPEC;
+void dmi_system_wake_up_type(xmlNode *node, u8 code)
+{
+ static const char *type[] = {
+ "Reserved", /* 0x00 */
+ "Other",
+ "Unknown",
+ "APM Timer",
+ "Modem Ring",
+ "LAN Remote",
+ "Power Switch",
+ "PCI PME#",
+ "AC Power Restored" /* 0x08 */
+ };
+ xmlNode *swut_n = xmlNewChild(node, NULL, (xmlChar *) "SystemWakeUpType", NULL);
+ assert( swut_n != NULL );
+ dmixml_AddAttribute(swut_n, "dmispec", "3.3.2.1");
+ dmixml_AddAttribute(swut_n, "flags", "0x%04x", code);
+
+ if(code <= 0x08) {
+ dmixml_AddTextContent(swut_n, type[code]);
+ } else {
+ dmixml_AddAttribute(swut_n, "outofspec", "1");
+ }
}
/*******************************************************************************
@@ -384,64 +452,79 @@ static PyObject *dmi_system_wake_up_type(u8 code) {
*/
/* 3.3.3.1 */
-static PyObject *dmi_base_board_features(u8 code) {
- static const char *features[] = {
- "Board is a hosting board", /* 0 */
- "Board requires at least one daughter board",
- "Board is removable",
- "Board is replaceable",
- "Board is hot swappable" /* 4 */
- };
-
- PyObject *data;
- if((code&0x1F)==0) data = Py_None;
- else {
- int i;
- data = PyList_New(5);
- for(i=0; i<=4; i++) {
- if(code&(1<<i)) PyList_SET_ITEM(data, i, PyString_FromString(features[i]));
- else PyList_SET_ITEM(data, i, Py_None);
- }
- }
- return data;
-}
-
-static PyObject *dmi_base_board_type(u8 code) {
- /* 3.3.3.2 */
- static const char *type[] = {
- "Unknown", /* 0x01 */
- "Other",
- "Server Blade",
- "Connectivity Switch",
- "System Management Module",
- "Processor Module",
- "I/O Module",
- "Memory Module",
- "Daughter Board",
- "Motherboard",
- "Processor+Memory Module",
- "Processor+I/O Module",
- "Interconnect Board" /* 0x0D */
- };
-
- if(code>=0x01 && code<=0x0D)
- return PyString_FromString(type[code-0x01]);
- return OUT_OF_SPEC;
-}
-
-static PyObject *dmi_base_board_handles(u8 count, const u8 *p) {
- int i;
-
- PyObject *dict = PyDict_New();
- PyObject *list = PyList_New(count);
-
- for(i=0; i<count; i++)
- PyList_SET_ITEM(list, i, PyString_FromFormat("0x%04x", WORD(p+sizeof(u16)*i)));
-
- PyDict_SetItemString(dict, "Contained Object Handles", list);
- Py_DECREF(list);
-
- return dict;
+void dmi_base_board_features(xmlNode *node, u8 code)
+{
+ static const char *features[] = {
+ "Board is a hosting board", /* 0 */
+ "Board requires at least one daughter board",
+ "Board is removable",
+ "Board is replaceable",
+ "Board is hot swappable" /* 4 */
+ };
+
+ xmlNode *feat_n = xmlNewChild(node, NULL, (xmlChar *) "Features", NULL);
+ assert( feat_n != NULL );
+ dmixml_AddAttribute(feat_n, "dmispec", "3.3.3.1");
+ dmixml_AddAttribute(feat_n, "flags", "0x%04x", code);
+
+ if((code & 0x1F) != 0) {
+ int i;
+
+ for(i = 0; i <= 4; i++) {
+ if(code & (1 << i)) {
+ dmixml_AddTextChild(feat_n, "feature", features[i]);
+ }
+ }
+ } else {
+ dmixml_AddAttribute(feat_n, "unavailable", "1");
+ }
+}
+
+void dmi_base_board_type(xmlNode *node, const char *tagname, u8 code)
+{
+ /* 3.3.3.2 */
+ static const char *type[] = {
+ "Unknown", /* 0x01 */
+ "Other",
+ "Server Blade",
+ "Connectivity Switch",
+ "System Management Module",
+ "Processor Module",
+ "I/O Module",
+ "Memory Module",
+ "Daughter Board",
+ "Motherboard",
+ "Processor+Memory Module",
+ "Processor+I/O Module",
+ "Interconnect Board" /* 0x0D */
+ };
+ xmlNode *type_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
+ assert( type_n != NULL );
+ dmixml_AddAttribute(type_n, "dmispec", "3.3.3.2");
+ dmixml_AddAttribute(type_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x0D) {
+ dmixml_AddTextContent(type_n, "%s", type[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(type_n, "unavailable", "1");
+ }
+}
+
+void dmi_base_board_handles(xmlNode *node, u8 count, const u8 * p)
+{
+ int i;
+ xmlNode *dict_n = NULL;
+
+ dict_n = xmlNewChild(node, NULL, (xmlChar *) "ContainedObjectHandles", NULL);
+ assert( dict_n != NULL );
+
+ dmixml_AddAttribute(dict_n, "count", "%i", count);
+
+ for(i = 0; i < count; i++) {
+ xmlNode *elmt_n = xmlNewChild(dict_n, NULL, (xmlChar *) "Handle", NULL);
+ assert( elmt_n != NULL );
+ dmixml_AddTextContent(elmt_n, "0x%04x", WORD(p + sizeof(u16) * i));
+ }
}
/*******************************************************************************
@@ -449,732 +532,889 @@ static PyObject *dmi_base_board_handles(u8 count, const u8 *p) {
*/
/* 3.3.4.1 */
-const char *dmi_chassis_type(u8 code) {
- static const char *type[] = {
- "Other", /* 0x01 */
- "Unknown",
- "Desktop",
- "Low Profile Desktop",
- "Pizza Box",
- "Mini Tower",
- "Tower",
- "Portable",
- "Laptop",
- "Notebook",
- "Hand Held",
- "Docking Station",
- "All In One",
- "Sub Notebook",
- "Space-saving",
- "Lunch Box",
- "Main Server Chassis", /* CIM_Chassis.ChassisPackageType says "Main System Chassis" */
- "Expansion Chassis",
- "Sub Chassis",
- "Bus Expansion Chassis",
- "Peripheral Chassis",
- "RAID Chassis",
- "Rack Mount Chassis",
- "Sealed-case PC",
- "Multi-system",
- "CompactPCI",
- "AdvancedTCA", /* 0x1B */
- "Blade",
- "Blade Enclosing" /* 0x1D */
- };
-
- if(code>=0x01 && code<=0x1B)
- return type[code-0x01];
- return out_of_spec;
-}
-
-static PyObject *dmi_chassis_type_py(u8 code) {
- return PyString_FromString(dmi_chassis_type(code));
-}
-
-static PyObject *dmi_chassis_lock(u8 code) {
- static const char *lock[] = {
- "Not Present", /* 0x00 */
- "Present" /* 0x01 */
- };
-
- return PyString_FromString(lock[code]);
+void dmi_chassis_type(xmlNode *node, u8 code)
+{
+ static const char *type[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "Desktop",
+ "Low Profile Desktop",
+ "Pizza Box",
+ "Mini Tower",
+ "Tower",
+ "Portable",
+ "Laptop",
+ "Notebook",
+ "Hand Held",
+ "Docking Station",
+ "All In One",
+ "Sub Notebook",
+ "Space-saving",
+ "Lunch Box",
+ "Main Server Chassis", /* CIM_Chassis.ChassisPackageType says "Main System Chassis" */
+ "Expansion Chassis",
+ "Sub Chassis",
+ "Bus Expansion Chassis",
+ "Peripheral Chassis",
+ "RAID Chassis",
+ "Rack Mount Chassis",
+ "Sealed-case PC",
+ "Multi-system",
+ "CompactPCI",
+ "AdvancedTCA", /* 0x1B */
+ "Blade",
+ "Blade Enclosing" /* 0x1D */
+ };
+ xmlNode *type_n = xmlNewChild(node, NULL, (xmlChar *)"ChassisType", NULL);
+ assert( type_n != NULL );
+ dmixml_AddAttribute(type_n, "dmispec", "3.3.4.1");
+ dmixml_AddAttribute(type_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x1B) {
+ dmixml_AddAttribute(type_n, "available", "1");
+ dmixml_AddTextContent(type_n, "%s", type[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(type_n, "available", "0");
+ }
}
-/* 3.3.4.2 */
-static PyObject *dmi_chassis_state(u8 code) {
- static const char *state[]={
- "Other", /* 0x01 */
- "Unknown",
- "Safe", /* master.mif says OK */
- "Warning",
- "Critical",
- "Non-recoverable" /* 0x06 */
- };
+void dmi_chassis_lock(xmlNode *node, u8 code)
+{
+ static const char *lock[] = {
+ "Not Present", /* 0x00 */
+ "Present" /* 0x01 */
+ };
+ xmlNode *lock_n = xmlNewChild(node, NULL, (xmlChar *) "ChassisLock", NULL);
+ assert( lock_n != NULL );
+ dmixml_AddAttribute(lock_n, "dmispec", "3.3.4");
+ dmixml_AddAttribute(lock_n, "flags", "0x%04x", code);
+ dmixml_AddTextContent(lock_n, "%s", lock[code]);
+}
- if(code>=0x01 && code<=0x06)
- return PyString_FromString(state[code-0x01]);
- return OUT_OF_SPEC;
+/* 3.3.4.2 */
+void dmi_chassis_state(xmlNode *node, const char *tagname, u8 code)
+{
+ static const char *state[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "Safe", /* master.mif says OK */
+ "Warning",
+ "Critical",
+ "Non-recoverable" /* 0x06 */
+ };
+ xmlNode *state_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
+ assert( state_n != NULL );
+ dmixml_AddAttribute(state_n, "dmispec", "3.3.4.2");
+ dmixml_AddAttribute(state_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x06) {
+ dmixml_AddTextContent(state_n, "%s", state[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(state_n, "unavailable", "1");
+ }
}
/* 3.3.4.3 */
-static const char *dmi_chassis_security_status(u8 code) {
- static const char *status[]={
- "Other", /* 0x01 */
- "Unknown",
- "None",
- "External Interface Locked Out",
- "External Interface Enabled" /* 0x05 */
- };
+void dmi_chassis_security_status(xmlNode *node, u8 code)
+{
+ static const char *status[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "None",
+ "External Interface Locked Out",
+ "External Interface Enabled" /* 0x05 */
+ };
+ xmlNode *secstat_n = xmlNewChild(node, NULL, (xmlChar *) "SecurityStatus", NULL);
+ assert( secstat_n != NULL );
+ dmixml_AddAttribute(secstat_n, "dmispec", "3.3.4.3");
+ dmixml_AddAttribute(secstat_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x05) {
+ dmixml_AddTextContent(secstat_n, "%s", status[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(secstat_n, "unavailable", "1");
+ }
+}
+
+void dmi_chassis_height(xmlNode *node, u8 code)
+{
+ xmlNode *hght_n = xmlNewChild(node, NULL, (xmlChar *) "ChassisHeight", NULL);
+ assert( hght_n != NULL );
- if(code>=0x01 && code<=0x05)
- return(status[code-0x01]);
- return out_of_spec;
+ if(code == 0x00) {
+ dmixml_AddAttribute(hght_n, "unspecified", "1");
+ } else {
+ dmixml_AddAttribute(hght_n, "unit", "U");
+ dmixml_AddTextContent(hght_n, "%i", code);
+ }
}
-static PyObject *dmi_chassis_height(u8 code) {
- if(code==0x00) return PyString_FromString("Unspecified");
- else return PyString_FromFormat("%i U", code);
+void dmi_chassis_power_cords(xmlNode *node, u8 code)
+{
+ xmlNode *pwrc_n = xmlNewChild(node, NULL, (xmlChar *) "PowerCords", NULL);
+ assert( pwrc_n != NULL );
+
+ if(code == 0x00) {
+ dmixml_AddAttribute(pwrc_n, "unspecified", "1");
+ } else {
+ dmixml_AddTextContent(pwrc_n, "%i", code);
+ }
}
-static PyObject *dmi_chassis_power_cords(u8 code) {
- if(code==0x00) return PyString_FromString("Unspecified");
- else return PyString_FromFormat("%i", code);
+void dmi_chassis_elements(xmlNode *node, u8 count, u8 len, const u8 * p)
+{
+ int i;
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "ChassisElements", NULL);
+ assert( data_n != NULL );
+
+ dmixml_AddAttribute(data_n, "count", "%i", count);
+
+ for(i = 0; i < count; i++) {
+ if(len >= 0x03) {
+ xmlNode *key_n = NULL;
+
+ if( p[i * len] & 0x80 ) {
+ key_n = dmi_smbios_structure_type(data_n, p[i * len] & 0x7F);
+ } else {
+ key_n = xmlNewChild(data_n, NULL, (xmlChar *) "BaseboardElement", NULL);
+ dmi_base_board_type(key_n, "Description", p[i * len] & 0x7F);
+ }
+ assert( key_n != NULL );
+
+ if(p[1 + i * len] == p[2 + i * len]) {
+ dmixml_AddTextChild(key_n, "Value", "%i", p[1 + i * len]);
+ } else {
+ dmixml_AddTextChild(key_n, "Value", "%i-%i", p[1 + i * len], p[2 + i * len]);
+ }
+ }
+ }
}
-static PyObject *dmi_chassis_elements(u8 count, u8 len, const u8 *p) {
- int i;
+/*******************************************************************************
+** 3.3.5 Processor Information (Type 4)
+*/
- PyObject *data = PyDict_New();
- PyDict_SetItemString(data, "Contained Elements", PyInt_FromLong(count));
+void dmi_processor_type(xmlNode *node, u8 code)
+{
+ /* 3.3.5.1 */
+ static const char *type[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "Central Processor",
+ "Math Processor",
+ "DSP Processor",
+ "Video Processor" /* 0x06 */
+ };
+ xmlNode *proct_n = xmlNewChild(node, NULL, (xmlChar *) "Type", NULL);
+ assert( proct_n != NULL );
+ dmixml_AddAttribute(proct_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x06) {
+ dmixml_AddTextContent(proct_n, type[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(proct_n, "outofspec", "1");
+ }
+}
- PyObject *_key, *_val;
- for(i=0; i<count; i++) {
- if(len>=0x03) {
+void dmi_processor_family(xmlNode *node, const struct dmi_header *h)
+{
+ const u8 *data = h->data;
+ unsigned int i, low, high;
+ u16 code;
+
+ /* 3.3.5.2 */
+ static struct {
+ int value;
+ const char *name;
+ } family2[] = {
+ /* *INDENT-OFF* */
+ { 0x01, "Other" },
+ { 0x02, "Unknown" },
+ { 0x03, "8086" },
+ { 0x04, "80286" },
+ { 0x05, "80386" },
+ { 0x06, "80486" },
+ { 0x07, "8087" },
+ { 0x08, "80287" },
+ { 0x09, "80387" },
+ { 0x0A, "80487" },
+ { 0x0B, "Pentium" },
+ { 0x0C, "Pentium Pro" },
+ { 0x0D, "Pentium II" },
+ { 0x0E, "Pentium MMX" },
+ { 0x0F, "Celeron" },
+ { 0x10, "Pentium II Xeon" },
+ { 0x11, "Pentium III" },
+ { 0x12, "M1" },
+ { 0x13, "M2" },
+ { 0x14, "Celeron M" }, /* From CIM_Processor.Family */
+ { 0x15, "Pentium 4 HT" }, /* From CIM_Processor.Family */
+
+ { 0x18, "Duron" },
+ { 0x19, "K5" },
+ { 0x1A, "K6" },
+ { 0x1B, "K6-2" },
+ { 0x1C, "K6-3" },
+ { 0x1D, "Athlon" },
+ { 0x1E, "AMD29000" },
+ { 0x1F, "K6-2+" },
+ { 0x20, "Power PC" },
+ { 0x21, "Power PC 601" },
+ { 0x22, "Power PC 603" },
+ { 0x23, "Power PC 603+" },
+ { 0x24, "Power PC 604" },
+ { 0x25, "Power PC 620" },
+ { 0x26, "Power PC x704" },
+ { 0x27, "Power PC 750" },
+ { 0x28, "Core Duo" }, /* From CIM_Processor.Family */
+ { 0x29, "Core Duo Mobile" }, /* From CIM_Processor.Family */
+ { 0x2A, "Core Solo Mobile" }, /* From CIM_Processor.Family */
+ { 0x2B, "Atom" }, /* From CIM_Processor.Family */
+
+ { 0x30, "Alpha" },
+ { 0x31, "Alpha 21064" },
+ { 0x32, "Alpha 21066" },
+ { 0x33, "Alpha 21164" },
+ { 0x34, "Alpha 21164PC" },
+ { 0x35, "Alpha 21164a" },
+ { 0x36, "Alpha 21264" },
+ { 0x37, "Alpha 21364" },
+
+ { 0x40, "MIPS" },
+ { 0x41, "MIPS R4000" },
+ { 0x42, "MIPS R4200" },
+ { 0x43, "MIPS R4400" },
+ { 0x44, "MIPS R4600" },
+ { 0x45, "MIPS R10000" },
+
+ { 0x50, "SPARC" },
+ { 0x51, "SuperSPARC" },
+ { 0x52, "MicroSPARC II" },
+ { 0x53, "MicroSPARC IIep" },
+ { 0x54, "UltraSPARC" },
+ { 0x55, "UltraSPARC II" },
+ { 0x56, "UltraSPARC IIi" },
+ { 0x57, "UltraSPARC III" },
+ { 0x58, "UltraSPARC IIIi" },
+
+ { 0x60, "68040" },
+ { 0x61, "68xxx" },
+ { 0x62, "68000" },
+ { 0x63, "68010" },
+ { 0x64, "68020" },
+ { 0x65, "68030" },
+
+ { 0x70, "Hobbit" },
+
+ { 0x78, "Crusoe TM5000" },
+ { 0x79, "Crusoe TM3000" },
+ { 0x7A, "Efficeon TM8000" },
+
+ { 0x80, "Weitek" },
+
+ { 0x82, "Itanium" },
+ { 0x83, "Athlon 64" },
+ { 0x84, "Opteron" },
+ { 0x85, "Sempron" },
+ { 0x86, "Turion 64" },
+ { 0x87, "Dual-Core Opteron" },
+ { 0x88, "Athlon 64 X2" },
+ { 0x89, "Turion 64 X2" },
+ { 0x8A, "Quad-Core Opteron" }, /* From CIM_Processor.Family */
+ { 0x8B, "Third-Generation Opteron" }, /* From CIM_Processor.Family */
+ { 0x8C, "Phenom FX" }, /* From CIM_Processor.Family */
+ { 0x8D, "Phenom X4" }, /* From CIM_Processor.Family */
+ { 0x8E, "Phenom X2" }, /* From CIM_Processor.Family */
+ { 0x8F, "Athlon X2" }, /* From CIM_Processor.Family */
+ { 0x90, "PA-RISC" },
+ { 0x91, "PA-RISC 8500" },
+ { 0x92, "PA-RISC 8000" },
+ { 0x93, "PA-RISC 7300LC" },
+ { 0x94, "PA-RISC 7200" },
+ { 0x95, "PA-RISC 7100LC" },
+ { 0x96, "PA-RISC 7100" },
+
+ { 0xA0, "V30" },
+ { 0xA1, "Quad-Core Xeon 3200" }, /* From CIM_Processor.Family */
+ { 0xA2, "Dual-Core Xeon 3000" }, /* From CIM_Processor.Family */
+ { 0xA3, "Quad-Core Xeon 5300" }, /* From CIM_Processor.Family */
+ { 0xA4, "Dual-Core Xeon 5100" }, /* From CIM_Processor.Family */
+ { 0xA5, "Dual-Core Xeon 5000" }, /* From CIM_Processor.Family */
+ { 0xA6, "Dual-Core Xeon LV" }, /* From CIM_Processor.Family */
+ { 0xA7, "Dual-Core Xeon ULV" }, /* From CIM_Processor.Family */
+ { 0xA8, "Dual-Core Xeon 7100" }, /* From CIM_Processor.Family */
+ { 0xA9, "Quad-Core Xeon 5400" }, /* From CIM_Processor.Family */
+ { 0xAA, "Quad-Core Xeon" }, /* From CIM_Processor.Family */
+
+ { 0xB0, "Pentium III Xeon" },
+ { 0xB1, "Pentium III Speedstep" },
+ { 0xB2, "Pentium 4" },
+ { 0xB3, "Xeon" },
+ { 0xB4, "AS400" },
+ { 0xB5, "Xeon MP" },
+ { 0xB6, "Athlon XP" },
+ { 0xB7, "Athlon MP" },
+ { 0xB8, "Itanium 2" },
+ { 0xB9, "Pentium M" },
+ { 0xBA, "Celeron D" },
+ { 0xBB, "Pentium D" },
+ { 0xBC, "Pentium EE" },
+ { 0xBD, "Core Solo" },
+ /* 0xBE handled as a special case */
+ { 0xBF, "Core 2 Duo" },
+ { 0xC0, "Core 2 Solo" }, /* From CIM_Processor.Family */
+ { 0xC1, "Core 2 Extreme" }, /* From CIM_Processor.Family */
+ { 0xC2, "Core 2 Quad" }, /* From CIM_Processor.Family */
+ { 0xC3, "Core 2 Extreme Mobile" }, /* From CIM_Processor.Family */
+ { 0xC4, "Core 2 Duo Mobile" }, /* From CIM_Processor.Family */
+ { 0xC5, "Core 2 Solo Mobile" }, /* From CIM_Processor.Family */
+
+ { 0xC8, "IBM390" },
+ { 0xC9, "G4" },
+ { 0xCA, "G5" },
+ { 0xCB, "ESA/390 G6" },
+ { 0xCC, "z/Architectur" },
+
+ { 0xD2, "C7-M" },
+ { 0xD3, "C7-D" },
+ { 0xD4, "C7" },
+ { 0xD5, "Eden" },
+
+ { 0xFA, "i860" },
+ { 0xFB, "i960" },
+
+ { 0x104, "SH-3" },
+ { 0x105, "SH-4" },
+
+ { 0x118, "ARM" },
+ { 0x119, "StrongARM" },
+
+ { 0x12C, "6x86" },
+ { 0x12D, "MediaGX" },
+ { 0x12E, "MII" },
+
+ { 0x140, "WinChip" },
+
+ { 0x15E, "DSP" },
+
+ { 0x1F4, "Video Processor" },
+ /* *INDENT-ON* */
+ };
+
+ /* Linear Search - Slow
+ * for(i=0; i<ARRAY_SIZE(family2); i++)
+ * if (family2[i].value == code)
+ * return family2[i].name;
+ */
+
+ xmlNode *family_n = xmlNewChild(node, NULL, (xmlChar *) "Family", NULL);
+ assert( family_n != NULL );
+ dmixml_AddAttribute(family_n, "dmispec", "3.3.3.5");
+
+ code = (data[0x06] == 0xFE && h->length >= 0x2A) ? WORD(data + 0x28) : data[0x06];
+
+ dmixml_AddAttribute(family_n, "flags", "0x%04x", code);
+
+ /* Special case for ambiguous value 0xBE */
+ if(code == 0xBE) {
+ const char *manufacturer = dmi_string(h, data[0x07]);
+
+ /* Best bet based on manufacturer string */
+ if(strstr(manufacturer, "Intel") != NULL ||
+ strncasecmp(manufacturer, "Intel", 5) == 0) {
+ dmixml_AddTextContent(family_n, "Core 2");
+ return;
+ }
+
+ if(strstr(manufacturer, "AMD") != NULL
+ || strncasecmp(manufacturer, "AMD", 3) == 0) {
+ dmixml_AddTextContent(family_n, "K7");
+ return;
+ }
+ dmixml_AddTextContent(family_n, "Core 2 or K7");
+ return;
+ }
- _key = PyString_FromFormat("%s",
- p[i*len]&0x80?
- dmi_smbios_structure_type(p[i*len]&0x7F):
- PyString_AS_STRING(dmi_base_board_type(p[i*len]&0x7F))
- );
+ /* Perform a binary search */
+ low = 0;
+ high = ARRAY_SIZE(family2) - 1;
+ while(1) {
+ i = (low + high) / 2;
+ if(family2[i].value == code) {
+ dmixml_AddTextContent(family_n, family2[i].name);
+ return;
+ }
+
+ if(low == high) { /* Not found */
+ dmixml_AddAttribute(family_n, "outofspec", "1");
+ return;
+ }
+
+ if(code < family2[i].value)
+ high = i;
+ else
+ low = i + 1;
+ }
+
+ dmixml_AddAttribute(family_n, "outofspec", "1");
+}
- if (p[1+i*len]==p[2+i*len]) _val = PyString_FromFormat("%i", p[1+i*len]);
- else _val = PyString_FromFormat("%i-%i", p[1+i*len], p[2+i*len]);
+xmlNode *dmi_processor_id(xmlNode *node, u8 type, const u8 * p, const char *version)
+{
+ /* Intel AP-485 revision 31, table 3-4 */
+ static struct _cpuflags {
+ const char *flag;
+ const char *descr;
+ } flags[] = {
+ /* *INDENT-OFF* */
+ {"FPU", "FPU (Floating-point unit on-chip)"}, /* 0 */
+ {"VME", "VME (Virtual mode extension)"},
+ {"DE", "DE (Debugging extension)"},
+ {"PSE", "PSE (Page size extension)"},
+ {"TSC", "TSC (Time stamp counter)"},
+ {"MSR", "MSR (Model specific registers)"},
+ {"PAE", "PAE (Physical address extension)"},
+ {"MCE", "MCE (Machine check exception)"},
+ {"CX8", "CX8 (CMPXCHG8 instruction supported)"},
+ {"APIC", "APIC (On-chip APIC hardware supported)"},
+ {NULL, NULL}, /* 10 */
+ {"SEP", "SEP (Fast system call)"},
+ {"MTRR", "MTRR (Memory type range registers)"},
+ {"PGE", "PGE (Page global enable)"},
+ {"MCA", "MCA (Machine check architecture)"},
+ {"CMOV", "CMOV (Conditional move instruction supported)"},
+ {"PAT", "PAT (Page attribute table)"},
+ {"PSE-36", "PSE-36 (36-bit page size extension)"},
+ {"PSN", "PSN (Processor serial number present and enabled)"},
+ {"CLFSH", "CLFLUSH (CLFLUSH instruction supported)"},
+ {NULL, NULL }, /* 20 */
+ {"DS", "DS (Debug store)"},
+ {"ACPI", "ACPI (ACPI supported)"},
+ {"MMX", "MMX (MMX technology supported)"},
+ {"FXSR", "FXSR (Fast floating-point save and restore)"},
+ {"SSE", "SSE (Streaming SIMD extensions)"},
+ {"SSE2", "SSE2 (Streaming SIMD extensions 2)"},
+ {"SS", "SS (Self-snoop)"},
+ {"HTT", "HTT (Hyper-threading technology)"},
+ {"TM", "TM (Thermal monitor supported)"},
+ {"IA64", "IA64 (IA64 capabilities)"},
+ {"PBE", "PBE (Pending break enabled)"} /* 31 */
+ /* *INDENT-ON* */
+ };
+
+ xmlNode *flags_n = NULL;
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "CPUCore", NULL);
+ assert( data_n != NULL );
+
+ /*
+ ** Extra flags are now returned in the ECX register when one calls
+ ** the CPUID instruction. Their meaning is explained in table 3-5, but
+ ** DMI doesn't support this yet.
+ */
+ u32 eax, edx;
+ int sig = 0;
+
+ /*
+ ** This might help learn about new processors supporting the
+ ** CPUID instruction or another form of identification.
+ */
+
+ //. TODO: PyString_FromFormat does not support %x (yet?)...
+ dmixml_AddTextChild(data_n, "ID",
+ "%02x %02x %02x %02x %02x %02x %02x %02x",
+ p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+
+ if(type == 0x05) { /* 80386 */
+ u16 dx = WORD(p);
+
+ /*
+ ** 80386 have a different signature.
+ */
+ dmixml_AddTextChild(data_n, "Signature",
+ "Type %i, Family %i, Major Stepping %i, Minor Stepping %i",
+ dx >> 12, (dx >> 8) & 0xF, (dx >> 4) & 0xF, dx & 0xF);
+ return data_n;
+ }
- PyDict_SetItem(data, _key, _val);
+ if(type == 0x06) { /* 80486 */
+ u16 dx = WORD(p);
+
+ /*
+ ** Not all 80486 CPU support the CPUID instruction, we have to find
+ ** wether the one we have here does or not. Note that this trick
+ ** works only because we know that 80486 must be little-endian.
+ */
+ if( (dx & 0x0F00) == 0x0400
+ && ((dx & 0x00F0) == 0x0040 || (dx & 0x00F0) >= 0x0070)
+ && ((dx & 0x000F) >= 0x0003) ) {
+ sig = 1;
+ } else {
+ dmixml_AddTextChild(data_n, "Signature",
+ "Type %i, Family %i, Model %i, Stepping %i",
+ (dx >> 12) & 0x3, (dx >> 8) & 0xF, (dx >> 4) & 0xF,
+ dx & 0xF);
+ return data_n;
+ }
+ } else if((type >= 0x0B && type <= 0x15) /* Intel, Cyrix */
+ ||(type >= 0x28 && type <= 0x2B) /* Intel */
+ ||(type >= 0xA1 && type <= 0xAA) /* Intel */
+ ||(type >= 0xB0 && type <= 0xB3) /* Intel */
+ ||type == 0xB5 /* Intel */
+ || (type >= 0xB9 && type <= 0xC5) /* Intel */
+ ||(type >= 0xD2 && type <= 0xD5) /* VIA */
+ ) {
+
+ sig = 1;
+
+ } else if((type >= 0x18 && type <= 0x1D) /* AMD */
+ ||type == 0x1F /* AMD */
+ || (type >= 0x83 && type <= 0x8F) /* AMD */
+ ||(type >= 0xB6 && type <= 0xB7) /* AMD */
+ ||(type >= 0xE6 && type <= 0xEB) /* AMD */
+ ) {
+
+ sig = 2;
+
+ } else if(type == 0x01 || type == 0x02) {
+ /*
+ ** Some X86-class CPU have family "Other" or "Unknown". In this case,
+ ** we use the version string to determine if they are known to
+ ** support the CPUID instruction.
+ */
+ if(strncmp(version, "Pentium III MMX", 15) == 0
+ || strncmp(version, "Intel(R) Core(TM)2", 18) == 0
+ || strncmp(version, "Intel(R) Pentium(R)", 19) == 0
+ || strcmp(version, "Genuine Intel(R) CPU U1400") == 0
+ ) {
+
+ sig = 1;
+
+ } else if(strncmp(version, "AMD Athlon(TM)", 14) == 0
+ || strncmp(version, "AMD Opteron(tm)", 15) == 0
+ || strncmp(version, "Dual-Core AMD Opteron(tm)", 25) == 0) {
+
+ sig = 2;
+
+ } else {
+ return data_n;
+ }
+ } else { /* not X86-class */
+ return data_n;
+ }
- Py_DECREF(_key);
- Py_DECREF(_val);
- }
- }
+ eax = DWORD(p);
+ edx = DWORD(p + 4);
+ switch (sig) {
+ case 1: /* Intel */
+ dmixml_AddTextChild(data_n, "Signature",
+ "Type %i, Family %i, Model %i, Stepping %i",
+ (eax >> 12) & 0x3, ((eax >> 20) & 0xFF) + ((eax >> 8) & 0x0F),
+ ((eax >> 12) & 0xF0) + ((eax >> 4) & 0x0F), eax & 0xF);
+ break;
+ case 2: /* AMD, publication #25481 revision 2.28 */
+ dmixml_AddTextChild(data_n, "Signature",
+ "Family %i, Model %i, Stepping %i",
+ ((eax >> 8) & 0xF) + (((eax >> 8) & 0xF) == 0xF
+ ? (eax >> 20) & 0xFF : 0),
+ ((eax >> 4) & 0xF) | (((eax >> 8) & 0xF) == 0xF
+ ? (eax >> 12) & 0xF0 : 0),
+ eax & 0xF);
+ break;
+ }
- return data;
+ edx = DWORD(p + 4);
+ flags_n = xmlNewChild(data_n, NULL, (xmlChar *) "cpu_flags", NULL);
+ if((edx & 0xFFEFFBFF) != 0) {
+ int i;
+
+ for(i = 0; i <= 31; i++) {
+ if( flags[i].flag != NULL ) {
+ xmlNode *flg_n = dmixml_AddTextChild(flags_n, "flag", "%s", flags[i].descr);
+ dmixml_AddAttribute(flg_n, "available", "%i",
+ (edx & (1 << i) ? 1 : 0));
+ dmixml_AddAttribute(flg_n, "flag", "%s", flags[i].flag);
+ }
+ }
+ }
+ return data_n;
}
-/*******************************************************************************
-** 3.3.5 Processor Information (Type 4)
-*/
+/* 3.3.5.4 */
+void dmi_processor_voltage(xmlNode *node, u8 code)
+{
+ static const char *voltage[] = {
+ "5.0", /* 0 */
+ "3.3",
+ "2.9" /* 2 */
+ };
+ int i;
+ xmlNode *vltg_n = xmlNewChild(node, NULL, (xmlChar *) "Voltages", NULL);
+ assert( vltg_n != NULL );
+ dmixml_AddAttribute(vltg_n, "dmispec", "3.3.5.4");
+ dmixml_AddAttribute(vltg_n, "flags", "0x%04x", code);
+
+ if(code & 0x80) {
+ xmlNode *v_n = dmixml_AddTextChild(vltg_n, "Voltage", "%.1f", (float)(code & 0x7f) / 10);
+ dmixml_AddAttribute(v_n, "unit", "V");
+ } else if( code == 0x00 ) {
+ dmixml_AddAttribute(vltg_n, "unknown_value", "1");
+ } else {
+ for(i = 0; i <= 2; i++) {
+ xmlNode *v_n = dmixml_AddTextChild(vltg_n, "Voltage", "%s", voltage[i]);
+ dmixml_AddAttribute(v_n, "key_compound", "%s V", voltage[i]);
+ dmixml_AddAttribute(v_n, "available", "%i", (code & (1 << i) ? 1 : 0));
+ dmixml_AddAttribute(v_n, "unit", "V");
+ v_n = NULL;
+ }
+ }
+}
+
+int dmi_processor_frequency(const u8 * p)
+{
+ u16 code = WORD(p);
-static PyObject *dmi_processor_type(u8 code) {
- /* 3.3.5.1 */
- static const char *type[]={
- "Other", /* 0x01 */
- "Unknown",
- "Central Processor",
- "Math Processor",
- "DSP Processor",
- "Video Processor" /* 0x06 */
- };
-
- if(code>=0x01 && code<=0x06) return PyString_FromString(type[code-0x01]);
- return OUT_OF_SPEC;
-}
-
-static const char *dmi_processor_family(const struct dmi_header *h) {
- const u8 *data = h->data;
- unsigned int i, low, high;
- u16 code;
-
- /* 3.3.5.2 */
- static struct {
- int value;
- const char *name;
- } family2[] = {
- { 0x01, "Other" },
- { 0x02, "Unknown" },
- { 0x03, "8086" },
- { 0x04, "80286" },
- { 0x05, "80386" },
- { 0x06, "80486" },
- { 0x07, "8087" },
- { 0x08, "80287" },
- { 0x09, "80387" },
- { 0x0A, "80487" },
- { 0x0B, "Pentium" },
- { 0x0C, "Pentium Pro" },
- { 0x0D, "Pentium II" },
- { 0x0E, "Pentium MMX" },
- { 0x0F, "Celeron" },
- { 0x10, "Pentium II Xeon" },
- { 0x11, "Pentium III" },
- { 0x12, "M1" },
- { 0x13, "M2" },
- { 0x14, "Celeron M" }, /* From CIM_Processor.Family */
- { 0x15, "Pentium 4 HT" }, /* From CIM_Processor.Family */
-
- { 0x18, "Duron" },
- { 0x19, "K5" },
- { 0x1A, "K6" },
- { 0x1B, "K6-2" },
- { 0x1C, "K6-3" },
- { 0x1D, "Athlon" },
- { 0x1E, "AMD29000" },
- { 0x1F, "K6-2+" },
- { 0x20, "Power PC" },
- { 0x21, "Power PC 601" },
- { 0x22, "Power PC 603" },
- { 0x23, "Power PC 603+" },
- { 0x24, "Power PC 604" },
- { 0x25, "Power PC 620" },
- { 0x26, "Power PC x704" },
- { 0x27, "Power PC 750" },
- { 0x28, "Core Duo" }, /* From CIM_Processor.Family */
- { 0x29, "Core Duo Mobile" }, /* From CIM_Processor.Family */
- { 0x2A, "Core Solo Mobile" }, /* From CIM_Processor.Family */
- { 0x2B, "Atom" }, /* From CIM_Processor.Family */
-
- { 0x30, "Alpha" },
- { 0x31, "Alpha 21064" },
- { 0x32, "Alpha 21066" },
- { 0x33, "Alpha 21164" },
- { 0x34, "Alpha 21164PC" },
- { 0x35, "Alpha 21164a" },
- { 0x36, "Alpha 21264" },
- { 0x37, "Alpha 21364" },
-
- { 0x40, "MIPS" },
- { 0x41, "MIPS R4000" },
- { 0x42, "MIPS R4200" },
- { 0x43, "MIPS R4400" },
- { 0x44, "MIPS R4600" },
- { 0x45, "MIPS R10000" },
-
- { 0x50, "SPARC" },
- { 0x51, "SuperSPARC" },
- { 0x52, "MicroSPARC II" },
- { 0x53, "MicroSPARC IIep" },
- { 0x54, "UltraSPARC" },
- { 0x55, "UltraSPARC II" },
- { 0x56, "UltraSPARC IIi" },
- { 0x57, "UltraSPARC III" },
- { 0x58, "UltraSPARC IIIi" },
-
- { 0x60, "68040" },
- { 0x61, "68xxx" },
- { 0x62, "68000" },
- { 0x63, "68010" },
- { 0x64, "68020" },
- { 0x65, "68030" },
-
- { 0x70, "Hobbit" },
-
- { 0x78, "Crusoe TM5000" },
- { 0x79, "Crusoe TM3000" },
- { 0x7A, "Efficeon TM8000" },
-
- { 0x80, "Weitek" },
-
- { 0x82, "Itanium" },
- { 0x83, "Athlon 64" },
- { 0x84, "Opteron" },
- { 0x85, "Sempron" },
- { 0x86, "Turion 64" },
- { 0x87, "Dual-Core Opteron" },
- { 0x88, "Athlon 64 X2" },
- { 0x89, "Turion 64 X2" },
- { 0x8A, "Quad-Core Opteron" }, /* From CIM_Processor.Family */
- { 0x8B, "Third-Generation Opteron" }, /* From CIM_Processor.Family */
- { 0x8C, "Phenom FX" }, /* From CIM_Processor.Family */
- { 0x8D, "Phenom X4" }, /* From CIM_Processor.Family */
- { 0x8E, "Phenom X2" }, /* From CIM_Processor.Family */
- { 0x8F, "Athlon X2" }, /* From CIM_Processor.Family */
- { 0x90, "PA-RISC" },
- { 0x91, "PA-RISC 8500" },
- { 0x92, "PA-RISC 8000" },
- { 0x93, "PA-RISC 7300LC" },
- { 0x94, "PA-RISC 7200" },
- { 0x95, "PA-RISC 7100LC" },
- { 0x96, "PA-RISC 7100" },
-
- { 0xA0, "V30" },
- { 0xA1, "Quad-Core Xeon 3200" }, /* From CIM_Processor.Family */
- { 0xA2, "Dual-Core Xeon 3000" }, /* From CIM_Processor.Family */
- { 0xA3, "Quad-Core Xeon 5300" }, /* From CIM_Processor.Family */
- { 0xA4, "Dual-Core Xeon 5100" }, /* From CIM_Processor.Family */
- { 0xA5, "Dual-Core Xeon 5000" }, /* From CIM_Processor.Family */
- { 0xA6, "Dual-Core Xeon LV" }, /* From CIM_Processor.Family */
- { 0xA7, "Dual-Core Xeon ULV" }, /* From CIM_Processor.Family */
- { 0xA8, "Dual-Core Xeon 7100" }, /* From CIM_Processor.Family */
- { 0xA9, "Quad-Core Xeon 5400" }, /* From CIM_Processor.Family */
- { 0xAA, "Quad-Core Xeon" }, /* From CIM_Processor.Family */
-
- { 0xB0, "Pentium III Xeon" },
- { 0xB1, "Pentium III Speedstep" },
- { 0xB2, "Pentium 4" },
- { 0xB3, "Xeon" },
- { 0xB4, "AS400" },
- { 0xB5, "Xeon MP" },
- { 0xB6, "Athlon XP" },
- { 0xB7, "Athlon MP" },
- { 0xB8, "Itanium 2" },
- { 0xB9, "Pentium M" },
- { 0xBA, "Celeron D" },
- { 0xBB, "Pentium D" },
- { 0xBC, "Pentium EE" },
- { 0xBD, "Core Solo" },
- /* 0xBE handled as a special case */
- { 0xBF, "Core 2 Duo" },
- { 0xC0, "Core 2 Solo" }, /* From CIM_Processor.Family */
- { 0xC1, "Core 2 Extreme" }, /* From CIM_Processor.Family */
- { 0xC2, "Core 2 Quad" }, /* From CIM_Processor.Family */
- { 0xC3, "Core 2 Extreme Mobile" }, /* From CIM_Processor.Family */
- { 0xC4, "Core 2 Duo Mobile" }, /* From CIM_Processor.Family */
- { 0xC5, "Core 2 Solo Mobile" }, /* From CIM_Processor.Family */
-
- { 0xC8, "IBM390" },
- { 0xC9, "G4" },
- { 0xCA, "G5" },
- { 0xCB, "ESA/390 G6" },
- { 0xCC, "z/Architectur" },
-
- { 0xD2, "C7-M" },
- { 0xD3, "C7-D" },
- { 0xD4, "C7" },
- { 0xD5, "Eden" },
-
- { 0xFA, "i860" },
- { 0xFB, "i960" },
-
- { 0x104, "SH-3" },
- { 0x105, "SH-4" },
-
- { 0x118, "ARM" },
- { 0x119, "StrongARM" },
-
- { 0x12C, "6x86" },
- { 0x12D, "MediaGX" },
- { 0x12E, "MII" },
-
- { 0x140, "WinChip" },
-
- { 0x15E, "DSP" },
-
- { 0x1F4, "Video Processor" },
- };
-
- /* Linear Search - Slow
- for(i=0; i<ARRAY_SIZE(family2); i++)
- if (family2[i].value == code)
- return family2[i].name;
- */
-
- code = (data[0x06]==0xFE && h->length>=0x2A)?WORD(data+0x28):data[0x06];
-
- /* Special case for ambiguous value 0xBE */
- if(code == 0xBE) {
- const char *manufacturer = dmi_string(h, data[0x07]);
-
- /* Best bet based on manufacturer string */
- if(strstr(manufacturer, "Intel") != NULL || strncasecmp(manufacturer, "Intel", 5) == 0)
- return "Core 2";
- if(strstr(manufacturer, "AMD") != NULL || strncasecmp(manufacturer, "AMD", 3) == 0)
- return "K7";
- return "Core 2 or K7";
- }
-
- /* Perform a binary search */
- low = 0;
- high = ARRAY_SIZE(family2) - 1;
- while(1) {
- i = (low + high) / 2;
- if (family2[i].value == code) return family2[i].name;
- if (low == high) /* Not found */ return out_of_spec;
- if (code < family2[i].value) high = i;
- else low = i + 1;
- }
-
- return out_of_spec;
-}
-
-static PyObject *dmi_processor_id(u8 type, const u8 *p, const char *version) {
- PyObject *data = PyDict_New();
-
- /* Intel AP-485 revision 31, table 3-4 */
- static const char *flags[32]={
- "FPU (Floating-point unit on-chip)", /* 0 */
- "VME (Virtual mode extension)",
- "DE (Debugging extension)",
- "PSE (Page size extension)",
- "TSC (Time stamp counter)",
- "MSR (Model specific registers)",
- "PAE (Physical address extension)",
- "MCE (Machine check exception)",
- "CX8 (CMPXCHG8 instruction supported)",
- "APIC (On-chip APIC hardware supported)",
- NULL, /* 10 */
- "SEP (Fast system call)",
- "MTRR (Memory type range registers)",
- "PGE (Page global enable)",
- "MCA (Machine check architecture)",
- "CMOV (Conditional move instruction supported)",
- "PAT (Page attribute table)",
- "PSE-36 (36-bit page size extension)",
- "PSN (Processor serial number present and enabled)",
- "CLFSH (CLFLUSH instruction supported)",
- NULL, /* 20 */
- "DS (Debug store)",
- "ACPI (ACPI supported)",
- "MMX (MMX technology supported)",
- "FXSR (Fast floating-point save and restore)",
- "SSE (Streaming SIMD extensions)",
- "SSE2 (Streaming SIMD extensions 2)",
- "SS (Self-snoop)",
- "HTT (Hyper-threading technology)",
- "TM (Thermal monitor supported)",
- "IA64 (IA64 capabilities)",
- "PBE (Pending break enabled)" /* 31 */
- };
- /*
- ** Extra flags are now returned in the ECX register when one calls
- ** the CPUID instruction. Their meaning is explained in table 3-5, but
- ** DMI doesn't support this yet.
- */
- u32 eax, edx;
- int sig=0;
-
- /*
- ** This might help learn about new processors supporting the
- ** CPUID instruction or another form of identification.
- */
-
- //. TODO: PyString_FromFormat does not support %x (yet?)...
- PyDict_SetItemString(data, "ID",
- PyString_FromFormat("%02x %02x %02x %02x %02x %02x %02x %02x",
- p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]
- )
- );
-
- if(type==0x05) /* 80386 */ {
- u16 dx=WORD(p);
- /*
- ** 80386 have a different signature.
- */
- PyDict_SetItemString(data, "Signature",
- PyString_FromFormat(
- "Type %i, Family %i, Major Stepping %i, Minor Stepping %i",
- dx>>12, (dx>>8)&0xF, (dx>>4)&0xF, dx&0xF
- )
- );
- return data;
- }
-
- if(type==0x06) /* 80486 */ {
- u16 dx=WORD(p);
- /*
- ** Not all 80486 CPU support the CPUID instruction, we have to find
- ** wether the one we have here does or not. Note that this trick
- ** works only because we know that 80486 must be little-endian.
- */
- if((dx&0x0F00)==0x0400
- &&((dx&0x00F0)==0x0040 || (dx&0x00F0)>=0x0070)
- &&((dx&0x000F)>=0x0003)) sig=1;
- else {
- PyDict_SetItemString(data, "Signature",
- PyString_FromFormat(
- "Type %i, Family %i, Model %i, Stepping %i",
- (dx>>12)&0x3, (dx>>8)&0xF, (dx>>4)&0xF, dx&0xF
- )
- );
- return data;
- }
- } else if(
- (
- type >= 0x0B && type <= 0x15) /* Intel, Cyrix */
- || (type >= 0x28 && type <= 0x2B) /* Intel */
- || (type >= 0xA1 && type <= 0xAA) /* Intel */
- || (type >= 0xB0 && type <= 0xB3) /* Intel */
- || type == 0xB5 /* Intel */
- || (type >= 0xB9 && type <= 0xC5) /* Intel */
- || (type >= 0xD2 && type <= 0xD5) /* VIA */
- ) sig=1;
- else if(
- (
- type >= 0x18 && type <= 0x1D) /* AMD */
- || type == 0x1F /* AMD */
- || (type >= 0x83 && type <= 0x8F) /* AMD */
- || (type >= 0xB6 && type <= 0xB7) /* AMD */
- || (type >= 0xE6 && type <= 0xEB) /* AMD */
- ) sig=2;
- else if(type==0x01 || type==0x02) {
- /*
- ** Some X86-class CPU have family "Other" or "Unknown". In this case,
- ** we use the version string to determine if they are known to
- ** support the CPUID instruction.
- */
- if(
- strncmp(version, "Pentium III MMX", 15) == 0
- || strncmp(version, "Intel(R) Core(TM)2", 18) == 0
- || strncmp(version, "Intel(R) Pentium(R)", 19) == 0
- || strcmp(version, "Genuine Intel(R) CPU U1400") == 0
- ) sig = 1;
- else if(
- strncmp(version, "AMD Athlon(TM)", 14) == 0
- || strncmp(version, "AMD Opteron(tm)", 15) == 0
- || strncmp(version, "Dual-Core AMD Opteron(tm)", 25) == 0
- ) sig = 2;
- else return data;
- } else /* not X86-class */ return data;
-
- eax=DWORD(p);
- edx=DWORD(p+4);
- switch(sig) {
- case 1: /* Intel */
- PyDict_SetItemString(data, "Signature",
- PyString_FromFormat(
- "Type %i, Family %i, Model %i, Stepping %i",
- (eax>>12)&0x3, ((eax>>20)&0xFF)+((eax>>8)&0x0F),
- ((eax>>12)&0xF0)+((eax>>4)&0x0F), eax&0xF
- )
- );
- break;
- case 2: /* AMD, publication #25481 revision 2.28 */
- PyDict_SetItemString(data, "Signature",
- PyString_FromFormat(
- "Family %i, Model %i, Stepping %i",
- ((eax>>8)&0xF)+(((eax>>8)&0xF)==0xF?(eax>>20)&0xFF:0),
- ((eax>>4)&0xF)|(((eax>>8)&0xF)==0xF?(eax>>12)&0xF0:0),
- eax&0xF
- )
- );
- break;
- }
-
- edx=DWORD(p+4);
- if((edx&0xFFEFFBFF)==0) PyDict_SetItemString(data, "Flags", Py_None);
- else {
- int i;
- PyObject *subdata = PyDict_New();
- for(i=0; i<=31; i++)
- if(flags[i]!=NULL)
- PyDict_SetItemString(subdata, flags[i], (edx&(1<<i))?Py_True:Py_False);
- PyDict_SetItemString(data, "Flags", subdata);
- Py_DECREF(subdata);
- }
-
- return data;
+ if(code)
+ return code; //. Value measured in MHz
+ else
+ return -1; //. Unknown
}
-/* 3.3.5.4 */
-static PyObject *dmi_processor_voltage(u8 code) {
- static const char *voltage[]={
- "5.0 V", /* 0 */
- "3.3 V",
- "2.9 V" /* 2 */
- };
- int i;
-
- PyObject *data;
- if(code&0x80) data = PyString_FromFormat("%.1f V", (float)(code&0x7f)/10);
- else {
- data = PyDict_New();
- for(i=0; i<=2; i++)
- PyDict_SetItemString(data, voltage[i], (code&(1<<i)?Py_True:Py_False));
- if(code==0x00)
- PyDict_SetItemString(data, "VOLTAGE", PyString_FromString("Unknown"));
- }
- return data;
-}
-
-int dmi_processor_frequency(const u8 *p) {
- u16 code = WORD(p);
-
- if(code) return code; //. Value measured in MHz
- else return -1; //. Unknown
-}
-static PyObject *dmi_processor_frequency_py(const u8 *p) {
- return PyInt_FromLong(dmi_processor_frequency(p));
-}
-
-static const char *dmi_processor_status(u8 code) {
- static const char *status[] = {
- "Unknown", /* 0x00 */
- "Enabled",
- "Disabled By User",
- "Disabled By BIOS",
- "Idle", /* 0x04 */
- "Other" /* 0x07 */
- };
-
- if(code<=0x04) return status[code];
- if(code==0x07) return status[0x05];
- return out_of_spec;
-}
-
-static PyObject *dmi_processor_upgrade(u8 code) {
- /* 3.3.5.5 */
- static const char *upgrade[]={
- "Other", /* 0x01 */
- "Unknown",
- "Daughter Board",
- "ZIF Socket",
- "Replaceable Piggy Back",
- "None",
- "LIF Socket",
- "Slot 1",
- "Slot 2",
- "370-pin Socket",
- "Slot A",
- "Slot M",
- "Socket 423",
- "Socket A (Socket 462)",
- "Socket 478",
- "Socket 754",
- "Socket 940",
- "Socket 939",
- "Socket mPGA604",
- "Socket LGA771",
- "Socket LGA775", /* 0x15 */
- "Socket S1",
- "Socket AM2",
- "Socket F (1207)" /* 0x18 */
- };
-
- if(code>=0x01 && code<=0x15) return PyString_FromString(upgrade[code-0x01]);
- return OUT_OF_SPEC;
-}
-
-static PyObject *dmi_processor_cache(u16 code, const char *level, u16 ver) {
- PyObject *data;
- if(code==0xFFFF) {
- if(ver>=0x0203) data = PyString_FromString("Not Provided");
- else data = PyString_FromFormat("No %s Cache", level);
- } else data = PyString_FromFormat("0x%04x", code);
- return data;
+void dmi_processor_status(xmlNode *node, u8 code)
+{
+ static const char *status[] = {
+ "Unknown", /* 0x00 */
+ "Enabled",
+ "Disabled By User",
+ "Disabled By BIOS",
+ "Idle", /* 0x04 */
+ "Other" /* 0x07 */
+ };
+ xmlNode *prst_n = xmlNewChild(node, NULL, (xmlChar *) "Populated", NULL);
+ assert( prst_n != NULL );
+
+ dmixml_AddAttribute(prst_n, "flags", "0x%04x", code);
+
+ if(code <= 0x04) {
+ dmixml_AddTextContent(prst_n, "%s", status[code]);
+ } else if( code == 0x07 ) {
+ dmixml_AddTextContent(prst_n, "%s", status[5]);
+ } else {
+ dmixml_AddAttribute(prst_n, "outofspec", "1");
+ }
+}
+
+void dmi_processor_upgrade(xmlNode *node, u8 code)
+{
+ /* 3.3.5.5 */
+ static const char *upgrade[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "Daughter Board",
+ "ZIF Socket",
+ "Replaceable Piggy Back",
+ "None",
+ "LIF Socket",
+ "Slot 1",
+ "Slot 2",
+ "370-pin Socket",
+ "Slot A",
+ "Slot M",
+ "Socket 423",
+ "Socket A (Socket 462)",
+ "Socket 478",
+ "Socket 754",
+ "Socket 940",
+ "Socket 939",
+ "Socket mPGA604",
+ "Socket LGA771",
+ "Socket LGA775", /* 0x15 */
+ "Socket S1",
+ "Socket AM2",
+ "Socket F (1207)" /* 0x18 */
+ };
+ xmlNode *upgr_n = xmlNewChild(node, NULL, (xmlChar *) "Upgrade", NULL);
+ assert( upgr_n != NULL );
+ dmixml_AddAttribute(upgr_n, "dmispec", "3.3.5.5");
+ dmixml_AddAttribute(upgr_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x15) {
+ dmixml_AddTextContent(upgr_n, "%s", upgrade[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(upgr_n, "outofspec", "1");
+ }
+}
+
+void dmi_processor_cache(xmlNode *cache_n, u16 code, u16 ver)
+{
+ assert( cache_n != NULL );
+
+ dmixml_AddAttribute(cache_n, "ver", "0x%04x", ver);
+
+ if(code == 0xFFFF) {
+ dmixml_AddAttribute(cache_n, "flags", "0x%04x", code);
+ if(ver >= 0x0203) {
+ dmixml_AddAttribute(cache_n, "provided", "0");
+ dmixml_AddAttribute(cache_n, "available", "1");
+ } else {
+ dmixml_AddAttribute(cache_n, "available", "0");
+ }
+ } else {
+ dmixml_AddAttribute(cache_n, "provided", "1");
+ dmixml_AddAttribute(cache_n, "available", "1");
+ dmixml_AddAttribute(cache_n, "handle", "0x%04x", code);
+ }
}
/* 3.3.5.9 */
-static PyObject *dmi_processor_characteristics(u16 code) {
- static const char *characteristics[]={
- "64-bit capable" /* 2 */
- };
-
- PyObject *data;
- if((code&0x0004)==0) {
- data = Py_None;
- } else {
- data = PyList_New(1);
- int i;
- for(i=2; i<=2; i++)
- if(code&(1<<i))
- PyList_SET_ITEM(data, 0, PyString_FromString(characteristics[i-2]));
- }
- return data;
+void dmi_processor_characteristics(xmlNode *node, u16 code)
+{
+ static const char *characteristics[] = {
+ "Unknown", /* 1 */
+ "64-bit capable" /* 2 */
+ };
+
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Characteristics", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.5.9");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if((code & 0x0004) != 0) {
+ int i;
+
+ for(i = 1; i <= 2; i++) {
+ if(code & (1 << i)) {
+ dmixml_AddTextChild(data_n, "Flag", "%s", characteristics[i - 1]);
+ }
+ }
+ }
}
/*******************************************************************************
** 3.3.6 Memory Controller Information (Type 5)
*/
-static PyObject *dmi_memory_controller_ed_method(u8 code) {
- /* 3.3.6.1 */
- static const char *method[]={
- "Other", /* 0x01 */
- "Unknown",
- "None",
- "8-bit Parity",
- "32-bit ECC",
- "64-bit ECC",
- "128-bit ECC",
- "CRC" /* 0x08 */
- };
-
- if(code>=0x01 && code<=0x08) return(PyString_FromString(method[code-0x01]));
- return OUT_OF_SPEC;
+void dmi_memory_controller_ed_method(xmlNode *node, u8 code)
+{
+ /* 3.3.6.1 */
+ static const char *method[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "None",
+ "8-bit Parity",
+ "32-bit ECC",
+ "64-bit ECC",
+ "128-bit ECC",
+ "CRC" /* 0x08 */
+ };
+ xmlNode *ercm_n = xmlNewChild(node, NULL, (xmlChar *) "CorrectionMethod", NULL);
+ assert( ercm_n != NULL );
+ dmixml_AddAttribute(ercm_n, "dmispec", "3.3.6.1");
+ dmixml_AddAttribute(ercm_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x08) {
+ dmixml_AddTextContent(ercm_n, method[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(ercm_n, "outofspec", "1");
+ }
}
/* 3.3.6.2 */
-static PyObject *dmi_memory_controller_ec_capabilities(u8 code) {
- static const char *capabilities[]={
- "Other", /* 0 */
- "Unknown",
- "None",
- "Single-bit Error Correcting",
- "Double-bit Error Correcting",
- "Error Scrubbing" /* 5 */
- };
-
- PyObject *data = Py_None;
- if((code&0x3F)==0) return Py_None;
- else {
- int i;
-
- data = PyList_New(6);
- for(i=0; i<=5; i++)
- if(code&(1<<i))
- PyList_SET_ITEM(data, i, PyString_FromString(capabilities[i]));
- else
- PyList_SET_ITEM(data, i, Py_None);
- }
- return data;
-}
-
-static PyObject *dmi_memory_controller_interleave(u8 code) {
- /* 3.3.6.3 */
- static const char *interleave[]={
- "Other", /* 0x01 */
- "Unknown",
- "One-way Interleave",
- "Two-way Interleave",
- "Four-way Interleave",
- "Eight-way Interleave",
- "Sixteen-way Interleave" /* 0x07 */
- };
-
- if(code>=0x01 && code<=0x07) return PyString_FromString(interleave[code-0x01]);
- return OUT_OF_SPEC;
+void dmi_memory_controller_ec_capabilities(xmlNode *node, const char *tagname, u8 code)
+{
+ static const char *capabilities[] = {
+ "Other", /* 0 */
+ "Unknown",
+ "None",
+ "Single-bit Error Correcting",
+ "Double-bit Error Correcting",
+ "Error Scrubbing" /* 5 */
+ };
+
+ xmlNode *cap_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
+ assert( cap_n != NULL );
+ dmixml_AddAttribute(cap_n, "dmispec", "3.3.6.2");
+ dmixml_AddAttribute(cap_n, "flags", "0x%04x", code);
+
+ if((code & 0x3F) != 0) {
+ int i;
+ for(i = 0; i <= 5; i++) {
+ if(code & (1 << i)) {
+ xmlNode *c_n = dmixml_AddTextChild(cap_n, "Capability", "%s", capabilities[i]);
+ assert( c_n != NULL );
+ dmixml_AddAttribute(c_n, "index", "%i", i+1);
+ }
+ }
+ }
+}
+
+void dmi_memory_controller_interleave(xmlNode *node, const char *tagname, u8 code)
+{
+ /* 3.3.6.3 */
+ static const char *interleave[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "One-way Interleave",
+ "Two-way Interleave",
+ "Four-way Interleave",
+ "Eight-way Interleave",
+ "Sixteen-way Interleave" /* 0x07 */
+ };
+ xmlNode *mci_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
+ assert( mci_n != NULL );
+ dmixml_AddAttribute(mci_n, "dmispec", "3.3.6.3");
+ dmixml_AddAttribute(mci_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x07) {
+ dmixml_AddTextContent(mci_n, interleave[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(mci_n, "outofspec", "1");
+ }
}
/* 3.3.6.4 */
-static PyObject *dmi_memory_controller_speeds(u16 code) {
- const char *speeds[]={
- "Other", /* 0 */
- "Unknown",
- "70 ns",
- "60 ns",
- "50 ns" /* 4 */
- };
-
- PyObject *data;
- if((code&0x001F)!=0) data = Py_None;
- else {
- int i;
-
- data = PyList_New(5);
- for(i=0; i<=4; i++)
- if(code&(1<<i))
- PyList_SET_ITEM(data, i, PyString_FromString(speeds[i]));
- else
- PyList_SET_ITEM(data, i, Py_None);
- }
- return data;
-}
-
-static PyObject *dmi_memory_controller_slots(u8 count, const u8 *p) {
- int i;
-
- PyObject *data = PyList_New(count);
- for(i=0; i<count; i++)
- PyList_SET_ITEM(data, i, PyString_FromFormat("0x%04x:", WORD(p+sizeof(u16)*i)));
- return data;
+void dmi_memory_controller_speeds(xmlNode *node, u16 code)
+{
+ static struct {
+ const char *value;
+ const char *unit;
+ } const speeds[] = {
+ {"Other", NULL}, /* 0 */
+ {"Unknown", NULL},
+ {"70", "ns"},
+ {"60", "ns"},
+ {"50", "ns"} /* 4 */
+ };
+ xmlNode *mcs_n = xmlNewChild(node, NULL, (xmlChar *) "SupportedSpeeds", NULL);
+ assert( mcs_n != NULL );
+ dmixml_AddAttribute(mcs_n, "dmispec", "3.3.6.4");
+ dmixml_AddAttribute(mcs_n, "flags", "0x%04x", code);
+
+ if((code & 0x001F) == 0) {
+ int i;
+ for(i = 0; i <= 4; i++) {
+ if(code & (1 << i)) {
+ xmlNode *ms_n = dmixml_AddTextChild(mcs_n, "Speed", "%s", speeds[i].value);
+ assert( ms_n != NULL );
+ dmixml_AddAttribute(ms_n, "index", "%i", i);
+ if( speeds[i].unit != NULL ) {
+ dmixml_AddAttribute(ms_n, "unit", speeds[i].unit);
+ }
+ ms_n = NULL;
+ }
+ }
+ }
+}
+
+void dmi_memory_controller_slots(xmlNode *node, u8 count, const u8 * p)
+{
+ int i;
+ xmlNode *mslts_n = xmlNewChild(node, NULL, (xmlChar *) "AssociatedMemorySlots", NULL);
+ assert( mslts_n != NULL );
+
+ for(i = 0; i < count; i++) {
+ xmlNode *sl_n = dmixml_AddTextChild(mslts_n, "Slot", "0x%x:", WORD(p + sizeof(u16) * i));
+ dmixml_AddAttribute(sl_n, "index", "%i", i);
+ }
}
/*******************************************************************************
@@ -1182,1617 +1422,2205 @@ static PyObject *dmi_memory_controller_slots(u8 count, const u8 *p) {
*/
/* 3.3.7.1 */
-static PyObject *dmi_memory_module_types(u16 code) {
- static const char *types[]={
- "Other", /* 0 */
- "Unknown",
- "Standard",
- "FPM",
- "EDO",
- "Parity",
- "ECC",
- "SIMM",
- "DIMM",
- "Burst EDO",
- "SDRAM" /* 10 */
- };
-
- PyObject *data;
- if((code&0x07FF)==0) data = Py_None;
- else {
- int i;
-
- data = PyList_New(11);
- for(i=0; i<=10; i++)
- if(code&(1<<i))
- PyList_SET_ITEM(data, i, PyString_FromString( types[i]));
- else
- PyList_SET_ITEM(data, i, Py_None);
- }
- return data;
-}
-
-static PyObject *dmi_memory_module_connections(u8 code) {
- PyObject * data;
- if(code==0xFF) data = Py_None;
- else {
- data = PyList_New(0);
- if((code&0xF0)!=0xF0) PyList_Append(data, PyInt_FromLong(code>>4));
- if((code&0x0F)!=0x0F) PyList_Append(data, PyInt_FromLong(code&0x0F));
- }
- return data;
-}
-
-static PyObject *dmi_memory_module_speed(u8 code) {
- if(code==0) return PyString_FromString("Unknown");
- else return PyString_FromFormat("%i ns", code);
+void dmi_memory_module_types(xmlNode *node, const char *tagname, u16 code)
+{
+ static const char *types[] = {
+ "Other", /* 0 */
+ "Unknown",
+ "Standard",
+ "FPM",
+ "EDO",
+ "Parity",
+ "ECC",
+ "SIMM",
+ "DIMM",
+ "Burst EDO",
+ "SDRAM" /* 10 */
+ };
+ xmlNode *mmt_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
+ assert( mmt_n != NULL );
+ dmixml_AddAttribute(mmt_n, "dmispec", "3.3.7.1");
+ dmixml_AddAttribute(mmt_n, "flags", "0x%04x", code);
+
+ if((code & 0x07FF) != 0) {
+ int i;
+
+ for(i = 0; i <= 10; i++) {
+ if(code & (1 << i)) {
+ xmlNode *mt_n = dmixml_AddTextChild(mmt_n, "ModuleType", types[i]);
+ assert( mt_n != NULL );
+ dmixml_AddAttribute(mt_n, "index", "%i", i+1);
+ }
+ }
+ }
+}
+
+void dmi_memory_module_connections(xmlNode *node, u8 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "BankConnections", NULL);
+ assert( data_n != NULL );
+
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code != 0xFF) {
+ if((code & 0xF0) != 0xF0) {
+ dmixml_AddTextChild(data_n, "Connection", "%ld", (code >> 4));
+ }
+ if((code & 0x0F) != 0x0F) {
+ dmixml_AddTextChild(data_n, "Connection", "%ld", (code & 0x0F));
+ }
+ }
+}
+
+void dmi_memory_module_speed(xmlNode *node, const char *tagname, u8 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
+ assert( data_n != NULL );
+
+ dmixml_AddAttribute(data_n, "code", "0x%04x", code);
+
+ if(code != 0) {
+ dmixml_AddAttribute(data_n, "unit", "ns");
+ dmixml_AddTextContent(data_n, "%i", code);
+ }
}
/* 3.3.7.2 */
-static PyObject *dmi_memory_module_size(u8 code) {
- PyObject *data = PyDict_New();
- int check_conn = 1;
-
- switch(code&0x7F) {
- case 0x7D:
- PyDict_SetItemString(data, "Size", PyString_FromString("Not Determinable"));
- break;
- case 0x7E:
- PyDict_SetItemString(data, "Size", PyString_FromString("Disabled"));
- break;
- case 0x7F:
- PyDict_SetItemString(data, "Size", PyString_FromString("Not Installed"));
- check_conn = 0;
- default:
- PyDict_SetItemString(data, "Size", PyString_FromFormat("%i MB", 1<<(code&0x7F)));
- }
-
- if(check_conn) {
- if(code&0x80) PyDict_SetItemString(data, "Connection", PyString_FromString("Double-bank"));
- else PyDict_SetItemString(data, "Connection", PyString_FromString("Single-bank"));
- }
- return data;
-}
-
-static PyObject *dmi_memory_module_error(u8 code) {
- PyObject *data = NULL;
- if(code&(1<<2)) data = Py_None; //. TODO: sprintf(_, "See Event Log");
- else {
- if((code&0x03)==0) data = Py_True;
- if(code&(1<<0)) data = PyString_FromString("Uncorrectable Errors");
- if(code&(1<<1)) data = PyString_FromString("Correctable Errors");
- }
- return data;
+void dmi_memory_module_size(xmlNode *node, const char *tagname, u8 code)
+{
+ int check_conn = 1;
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
+ assert( data_n != NULL );
+
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.7.2");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ switch (code & 0x7F) {
+ case 0x7D:
+ dmixml_AddAttribute(data_n, "Error", "Size not determinable");
+ break;
+ case 0x7E:
+ dmixml_AddAttribute(data_n, "Error", "Disabled");
+ break;
+ case 0x7F:
+ dmixml_AddAttribute(data_n, "installed", "0");
+ check_conn = 0;
+ default:
+ dmixml_AddAttribute(data_n, "installed", "1");
+ dmixml_AddAttribute(data_n, "unit", "MB");
+ dmixml_AddTextContent(data_n, "%i", 1 << (code & 0x7F));
+ }
+
+ if(check_conn) {
+ dmixml_AddAttribute(data_n, "Connection", ((code & 0x80) ? "Double-bank" : "Single-bank"));
+ }
+}
+
+void dmi_memory_module_error(xmlNode *node, u8 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "ModuleErrorStatus", NULL);
+ assert( data_n != NULL );
+
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if( !(code & (1 << 2)) ) {
+ if((code & 0x03) == 0) {
+ dmixml_AddAttribute(data_n, "Error", "1");
+ }
+ if(code & (1 << 0)) {
+ dmixml_AddTextContent(data_n, "Uncorrectable Errors");
+ }
+ if(code & (1 << 1)) {
+ dmixml_AddTextContent(data_n, "Correctable Errors");
+ }
+ }
}
/*******************************************************************************
** 3.3.8 Cache Information (Type 7)
*/
-static PyObject *dmi_cache_mode(u8 code) {
- static const char *mode[]={
- "Write Through", /* 0x00 */
- "Write Back",
- "Varies With Memory Address",
- "Unknown" /* 0x03 */
- };
+static const char *dmi_cache_mode(u8 code)
+{
+ static const char *mode[] = {
+ "Write Through", /* 0x00 */
+ "Write Back",
+ "Varies With Memory Address",
+ "Unknown" /* 0x03 */
+ };
- return PyString_FromString(mode[code]);
+ return mode[code];
}
-static PyObject *dmi_cache_location(u8 code) {
- static const char *location[4]={
- "Internal", /* 0x00 */
- "External",
- NULL, /* 0x02 */
- "Unknown" /* 0x03 */
- };
-
- PyObject *data;
- if(location[code]!=NULL) data = PyString_FromString(location[code]);
- else data = OUT_OF_SPEC;
- return data;
+void dmi_cache_location(xmlNode *node, u8 code)
+{
+ static const char *location[4] = {
+ "Internal", /* 0x00 */
+ "External",
+ NULL, /* 0x02 */
+ "Unknown" /* 0x03 */
+ };
+
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "CacheLocation", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.8");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(location[code] != NULL) {
+ dmixml_AddTextContent(data_n, location[code]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
}
-static PyObject *dmi_cache_size(u16 code) {
- PyObject *data;
- if(code&0x8000) data = PyString_FromFormat("%i KB", (code&0x7FFF)<<6);
- else data = PyString_FromFormat("%i KB", code);
- return data;
+void dmi_cache_size(xmlNode *node, const char *tagname, u16 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.8");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code & 0x8000) {
+ dmixml_AddAttribute(data_n, "unit", "KB");
+ dmixml_AddTextContent(data_n, "%i", (code & 0x7FFF) << 6);
+ } else {
+ dmixml_AddAttribute(data_n, "unit", "KB");
+ dmixml_AddTextContent(data_n, "%i", code);
+ }
}
/* 3.3.8.2 */
-static PyObject *dmi_cache_types(u16 code) {
- static const char *types[] = {
- "Other", /* 0 */
- "Unknown",
- "Non-burst",
- "Burst",
- "Pipeline Burst",
- "Synchronous",
- "Asynchronous" /* 6 */
- };
- PyObject *data;
-
- if((code&0x007F)==0) data = Py_None;
- else {
- int i;
-
- data = PyList_New(7);
- for(i=0; i<=6; i++)
- if(code&(1<<i))
- PyList_SET_ITEM(data, i, PyString_FromString(types[i]));
- else
- PyList_SET_ITEM(data, i, Py_None);
- }
- return data;
-}
-
-static PyObject *dmi_cache_ec_type(u8 code) {
- /* 3.3.8.3 */
- static const char *type[]={
- "Other", /* 0x01 */
- "Unknown",
- "None",
- "Parity",
- "Single-bit ECC",
- "Multi-bit ECC" /* 0x06 */
- };
- PyObject *data;
-
- if(code>=0x01 && code<=0x06) data = PyString_FromString(type[code-0x01]);
- else data = OUT_OF_SPEC;
- return data;
-}
-
-static PyObject *dmi_cache_type(u8 code) {
- /* 3.3.8.4 */
- static const char *type[]={
- "Other", /* 0x01 */
- "Unknown",
- "Instruction",
- "Data",
- "Unified" /* 0x05 */
- };
- PyObject *data;
-
- if(code>=0x01 && code<=0x05) data = PyString_FromString(type[code-0x01]);
- else data = OUT_OF_SPEC;
- return data;
-}
-
-static PyObject *dmi_cache_associativity(u8 code) {
- /* 3.3.8.5 */
- static const char *type[]={
- "Other", /* 0x01 */
- "Unknown",
- "Direct Mapped",
- "2-way Set-associative",
- "4-way Set-associative",
- "Fully Associative",
- "8-way Set-associative",
- "16-way Set-associative" /* 0x08 */
- };
- PyObject *data;
-
- if(code>=0x01 && code<=0x08) data = PyString_FromString(type[code-0x01]);
- else data = OUT_OF_SPEC;
- return data;
+void dmi_cache_types(xmlNode *node, const char *tagname, u16 code)
+{
+ static const char *types[] = {
+ "Other", /* 0 */
+ "Unknown",
+ "Non-burst",
+ "Burst",
+ "Pipeline Burst",
+ "Synchronous",
+ "Asynchronous" /* 6 */
+ };
+
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.8.2");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+
+ if((code & 0x007F) != 0) {
+ int i;
+ for(i = 0; i <= 6; i++) {
+ if(code & (1 << i)) {
+ xmlNode *n = dmixml_AddTextChild(data_n, "CacheType", "%s", types[i]);
+ dmixml_AddAttribute(n, "index", "%i", i+1);
+ }
+ }
+ }
+}
+
+void dmi_cache_ec_type(xmlNode *node, u8 code)
+{
+ /* 3.3.8.3 */
+ static const char *type[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "None",
+ "Parity",
+ "Single-bit ECC",
+ "Multi-bit ECC" /* 0x06 */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "ErrorCorrectionType", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.8.3");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x06) {
+ dmixml_AddTextContent(data_n, type[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
+}
+
+void dmi_cache_type(xmlNode *node, u8 code)
+{
+ /* 3.3.8.4 */
+ static const char *type[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "Instruction",
+ "Data",
+ "Unified" /* 0x05 */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "SystemType", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.8.4");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x05) {
+ dmixml_AddTextContent(data_n, type[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
+}
+
+void dmi_cache_associativity(xmlNode *node, u8 code)
+{
+ /* 3.3.8.5 */
+ static const char *type[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "Direct Mapped",
+ "2-way Set-associative",
+ "4-way Set-associative",
+ "Fully Associative",
+ "8-way Set-associative",
+ "16-way Set-associative" /* 0x08 */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Associativity", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.8.5");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x08) {
+ dmixml_AddTextContent(data_n, type[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
}
/*******************************************************************************
** 3.3.9 Port Connector Information (Type 8)
*/
-static PyObject *dmi_port_connector_type(u8 code) {
- /* 3.3.9.2 */
- static const char *type[] = {
- "None", /* 0x00 */
- "Centronics",
- "Mini Centronics",
- "Proprietary",
- "DB-25 male",
- "DB-25 female",
- "DB-15 male",
- "DB-15 female",
- "DB-9 male",
- "DB-9 female",
- "RJ-11",
- "RJ-45",
- "50 Pin MiniSCSI",
- "Mini DIN",
- "Micro DIN",
- "PS/2",
- "Infrared",
- "HP-HIL",
- "Access Bus (USB)",
- "SSA SCSI",
- "Circular DIN-8 male",
- "Circular DIN-8 female",
- "On Board IDE",
- "On Board Floppy",
- "9 Pin Dual Inline (pin 10 cut)",
- "25 Pin Dual Inline (pin 26 cut)",
- "50 Pin Dual Inline",
- "68 Pin Dual Inline",
- "On Board Sound Input From CD-ROM",
- "Mini Centronics Type-14",
- "Mini Centronics Type-26",
- "Mini Jack (headphones)",
- "BNC",
- "IEEE 1394",
- "SAS/SATA Plug Receptacle" /* 0x22 */
- };
- static const char *type_0xA0[]={
- "PC-98", /* 0xA0 */
- "PC-98 Hireso",
- "PC-H98",
- "PC-98 Note",
- "PC-98 Full" /* 0xA4 */
- };
-
- if(code<=0x22) return PyString_FromString(type[code]);
- if(code>=0xA0 && code<=0xA4) return PyString_FromString(type_0xA0[code-0xA0]);
- if(code==0xFF) return PyString_FromString("Other");
- return OUT_OF_SPEC;
-}
-
-static PyObject *dmi_port_type(u8 code) {
- /* 3.3.9.3 */
- static const char *type[] = {
- "None", /* 0x00 */
- "Parallel Port XT/AT Compatible",
- "Parallel Port PS/2",
- "Parallel Port ECP",
- "Parallel Port EPP",
- "Parallel Port ECP/EPP",
- "Serial Port XT/AT Compatible",
- "Serial Port 16450 Compatible",
- "Serial Port 16550 Compatible",
- "Serial Port 16550A Compatible",
- "SCSI Port",
- "MIDI Port",
- "Joystick Port",
- "Keyboard Port",
- "Mouse Port",
- "SSA SCSI",
- "USB",
- "Firewire (IEEE P1394)",
- "PCMCIA Type I",
- "PCMCIA Type II",
- "PCMCIA Type III",
- "Cardbus",
- "Access Bus Port",
- "SCSI II",
- "SCSI Wide",
- "PC-98",
- "PC-98 Hireso",
- "PC-H98",
- "Video Port",
- "Audio Port",
- "Modem Port",
- "Network Port",
- "SATA",
- "SAS" /* 0x21 */
- };
- static const char *type_0xA0[]={
- "8251 Compatible", /* 0xA0 */
- "8251 FIFO Compatible" /* 0xA1 */
- };
-
- if(code<=0x21) return PyString_FromString(type[code]);
- if(code>=0xA0 && code<=0xA1) return PyString_FromString(type_0xA0[code-0xA0]);
- if(code==0xFF) return PyString_FromString("Other");
- return OUT_OF_SPEC;
+void dmi_port_connector_type(xmlNode *node, const char *tpref, u8 code)
+{
+ /* 3.3.9.2 */
+ static const char *type[] = {
+ "None", /* 0x00 */
+ "Centronics",
+ "Mini Centronics",
+ "Proprietary",
+ "DB-25 male",
+ "DB-25 female",
+ "DB-15 male",
+ "DB-15 female",
+ "DB-9 male",
+ "DB-9 female",
+ "RJ-11",
+ "RJ-45",
+ "50 Pin MiniSCSI",
+ "Mini DIN",
+ "Micro DIN",
+ "PS/2",
+ "Infrared",
+ "HP-HIL",
+ "Access Bus (USB)",
+ "SSA SCSI",
+ "Circular DIN-8 male",
+ "Circular DIN-8 female",
+ "On Board IDE",
+ "On Board Floppy",
+ "9 Pin Dual Inline (pin 10 cut)",
+ "25 Pin Dual Inline (pin 26 cut)",
+ "50 Pin Dual Inline",
+ "68 Pin Dual Inline",
+ "On Board Sound Input From CD-ROM",
+ "Mini Centronics Type-14",
+ "Mini Centronics Type-26",
+ "Mini Jack (headphones)",
+ "BNC",
+ "IEEE 1394",
+ "SAS/SATA Plug Receptacle" /* 0x22 */
+ };
+ static const char *type_0xA0[] = {
+ "PC-98", /* 0xA0 */
+ "PC-98 Hireso",
+ "PC-H98",
+ "PC-98 Note",
+ "PC-98 Full" /* 0xA4 */
+ };
+
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Connector", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.9.2");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+ dmixml_AddAttribute(data_n, "type", "%s", tpref);
+
+ if(code <= 0x22) {
+ dmixml_AddTextContent(data_n, type[code]);
+ } else if(code >= 0xA0 && code <= 0xA4) {
+ dmixml_AddTextContent(data_n, type_0xA0[code - 0xA0]);
+ } else if(code == 0xFF) {
+ dmixml_AddTextContent(data_n, "Other");
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
+}
+
+void dmi_port_type(xmlNode *node, u8 code)
+{
+ /* 3.3.9.3 */
+ static const char *type[] = {
+ "None", /* 0x00 */
+ "Parallel Port XT/AT Compatible",
+ "Parallel Port PS/2",
+ "Parallel Port ECP",
+ "Parallel Port EPP",
+ "Parallel Port ECP/EPP",
+ "Serial Port XT/AT Compatible",
+ "Serial Port 16450 Compatible",
+ "Serial Port 16550 Compatible",
+ "Serial Port 16550A Compatible",
+ "SCSI Port",
+ "MIDI Port",
+ "Joystick Port",
+ "Keyboard Port",
+ "Mouse Port",
+ "SSA SCSI",
+ "USB",
+ "Firewire (IEEE P1394)",
+ "PCMCIA Type I",
+ "PCMCIA Type II",
+ "PCMCIA Type III",
+ "Cardbus",
+ "Access Bus Port",
+ "SCSI II",
+ "SCSI Wide",
+ "PC-98",
+ "PC-98 Hireso",
+ "PC-H98",
+ "Video Port",
+ "Audio Port",
+ "Modem Port",
+ "Network Port",
+ "SATA",
+ "SAS" /* 0x21 */
+ };
+ static const char *type_0xA0[] = {
+ "8251 Compatible", /* 0xA0 */
+ "8251 FIFO Compatible" /* 0xA1 */
+ };
+
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "PortType", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.9.3");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code <= 0x21) {
+ dmixml_AddTextContent(data_n, type[code]);
+ } else if(code >= 0xA0 && code <= 0xA1) {
+ dmixml_AddTextContent(data_n, type_0xA0[code - 0xA0]);
+ } else if(code == 0xFF) {
+ dmixml_AddTextContent(data_n, "Other");
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
}
/*******************************************************************************
** 3.3.10 System Slots (Type 9)
*/
-static PyObject *dmi_slot_type(u8 code) {
- /* 3.3.10.1 */
- static const char *type[] = {
- "Other", /* 0x01 */
- "Unknown",
- "ISA",
- "MCA",
- "EISA",
- "PCI",
- "PC Card (PCMCIA)",
- "VLB",
- "Proprietary",
- "Processor Card",
- "Proprietary Memory Card",
- "I/O Riser Card",
- "NuBus",
- "PCI-66",
- "AGP",
- "AGP 2x",
- "AGP 4x",
- "PCI-X",
- "AGP 8x" /* 0x13 */
- };
- static const char *type_0xA0[]={
- "PC-98/C20", /* 0xA0 */
- "PC-98/C24",
- "PC-98/E",
- "PC-98/Local Bus",
- "PC-98/Card",
- "PCI Express",
- "PCI Express x1",
- "PCI Express x2",
- "PCI Express x4",
- "PCI Express x8",
- "PCI Express x16" /* 0xAA */
- };
-
- if(code>=0x01 && code<=0x13) return PyString_FromString(type[code-0x01]);
- if(code>=0xA0 && code<=0xAA) return PyString_FromString(type_0xA0[code-0xA0]);
- return OUT_OF_SPEC;
-}
-
-static PyObject *dmi_slot_bus_width(u8 code) {
- /* 3.3.10.2 */
- static const char *width[]={
- "", /* 0x01, "Other" */
- "", /* "Unknown" */
- "8-bit ",
- "16-bit ",
- "32-bit ",
- "64-bit ",
- "128-bit ",
- "x1 ",
- "x2 ",
- "x4 ",
- "x8 ",
- "x12 ",
- "x16 ",
- "x32 " /* 0x0E */
- };
-
- if(code>=0x01 && code<=0x0E) return PyString_FromString(width[code-0x01]);
- return OUT_OF_SPEC;
-}
-
-static PyObject *dmi_slot_current_usage(u8 code) {
- /* 3.3.10.3 */
- static const char *usage[]={
- "Other", /* 0x01 */
- "Unknown",
- "Available",
- "In Use" /* 0x04 */
- };
-
- if(code>=0x01 && code<=0x04) return PyString_FromString(usage[code-0x01]);
- return OUT_OF_SPEC;
+void dmi_slot_type(xmlNode *node, u8 code)
+{
+ /* 3.3.10.1 */
+ static const char *type[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "ISA",
+ "MCA",
+ "EISA",
+ "PCI",
+ "PC Card (PCMCIA)",
+ "VLB",
+ "Proprietary",
+ "Processor Card",
+ "Proprietary Memory Card",
+ "I/O Riser Card",
+ "NuBus",
+ "PCI-66",
+ "AGP",
+ "AGP 2x",
+ "AGP 4x",
+ "PCI-X",
+ "AGP 8x" /* 0x13 */
+ };
+ static const char *type_0xA0[] = {
+ "PC-98/C20", /* 0xA0 */
+ "PC-98/C24",
+ "PC-98/E",
+ "PC-98/Local Bus",
+ "PC-98/Card",
+ "PCI Express",
+ "PCI Express x1",
+ "PCI Express x2",
+ "PCI Express x4",
+ "PCI Express x8",
+ "PCI Express x16" /* 0xAA */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "SlotType", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.10.1");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x13) {
+ dmixml_AddTextContent(data_n, "%s", type[code - 0x01]);
+ } else if(code >= 0xA0 && code <= 0xAA) {
+ dmixml_AddTextContent(data_n, "%s", type_0xA0[code - 0xA0]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
}
-/* 3.3.1O.4 */
-static PyObject *dmi_slot_length(u8 code) {
- static const char *length[]={
- "Other", /* 0x01 */
- "Unknown",
- "Short",
- "Long" /* 0x04 */
- };
+void dmi_slot_bus_width(xmlNode *node, u8 code)
+{
+ /* 3.3.10.2 */
+ static const char *width[] = {
+ "", /* 0x01, "Other" */
+ "", /* "Unknown" */
+ "8-bit ",
+ "16-bit ",
+ "32-bit ",
+ "64-bit ",
+ "128-bit ",
+ "x1 ",
+ "x2 ",
+ "x4 ",
+ "x8 ",
+ "x12 ",
+ "x16 ",
+ "x32 " /* 0x0E */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "SlotWidth", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.10.2");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if( (code >= 0x01) && (code <= 0x0E) ) {
+ dmixml_AddTextContent(data_n, "%s", width[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
+}
+
+void dmi_slot_current_usage(xmlNode *node, u8 code)
+{
+ /* 3.3.10.3 */
+ static const char *usage[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "Available",
+ "In Use" /* 0x04 */
+ };
+
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "CurrentUsage", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.10.3");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+
+ if(code >= 0x01 && code <= 0x04) {
+ dmixml_AddTextContent(data_n, usage[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
+}
- if(code>=0x01 && code<=0x04)
- return PyString_FromString(length[code-0x01]);
- return OUT_OF_SPEC;
+/* 3.3.1O.4 */
+void dmi_slot_length(xmlNode *node, u8 code)
+{
+ static const char *length[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "Short",
+ "Long" /* 0x04 */
+ };
+
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "SlotLength", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.10.4");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x04) {
+ dmixml_AddTextContent(data_n, length[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
}
/* 3.3.10.5 */
-static PyObject *dmi_slot_id(u8 code1, u8 code2, u8 type) {
- PyObject *data;
- switch(type) {
- case 0x04: /* MCA */
- data = PyString_FromFormat("%i", code1);
- break;
- case 0x05: /* EISA */
- data = PyString_FromFormat("%i", code1);
- break;
- case 0x06: /* PCI */
- case 0x0E: /* PCI */
- case 0x0F: /* AGP */
- case 0x10: /* AGP */
- case 0x11: /* AGP */
- case 0x12: /* PCI-X */
- case 0x13: /* AGP */
- case 0xA5: /* PCI Express */
- data = PyString_FromFormat("%i", code1);
- break;
- case 0x07: /* PCMCIA */
- data = PyString_FromFormat("Adapter %i, Socket %i", code1, code2);
- break;
- default:
- data = Py_None;
- }
- return data;
-}
-
-static PyObject *dmi_slot_characteristics(u8 code1, u8 code2) {
- /* 3.3.10.6 */
- static const char *characteristics1[]={
- "5.0 V is provided", /* 1 */
- "3.3 V is provided",
- "Opening is shared",
- "PC Card-16 is supported",
- "Cardbus is supported",
- "Zoom Video is supported",
- "Modem ring resume is supported" /* 7 */
- };
-
- /* 3.3.10.7 */
- static const char *characteristics2[]={
- "PME signal is supported", /* 0 */
- "Hot-plug devices are supported",
- "SMBus signal is supported" /* 2 */
- };
-
- PyObject *data;
- if(code1&(1<<0)) data = PyString_FromString("Unknown");
- else if((code1&0xFE)==0 && (code2&0x07)==0) data = Py_None;
- else {
- int i;
-
- data = PyList_New(7+3);
- for(i=1; i<=7; i++) {
- if(code1&(1<<i)) PyList_SET_ITEM(data, i-1, PyString_FromString(characteristics1[i-1]));
- else PyList_SET_ITEM(data, i-1, Py_None);
- }
- for(i=0; i<=2; i++) {
- if(code2&(1<<i)) PyList_SET_ITEM(data, 7+i, PyString_FromString(characteristics2[i]));
- else PyList_SET_ITEM(data, 7+i, Py_None);
- }
- }
- return data;
-}
-
-static PyObject *dmi_slot_segment_bus_func(u16 code1, u8 code2, u8 code3) {
- /* 3.3.10.8 */
- PyObject *data;
- if(!(code1 == 0xFFFF && code2 == 0xFF && code3 == 0xFF))
- data = PyString_FromFormat("%04x:%02x:%02x.%x", code1, code2, code3 >> 3, code3 & 0x7);
- else data = Py_None;
- return data;
+void inline set_slottype(xmlNode *node, u8 type) {
+ switch (type) {
+ case 0x04: /* MCA */
+ dmixml_AddAttribute(node, "slottype", "MCA");
+ break;
+ case 0x05: /* EISA */
+ dmixml_AddAttribute(node, "slottype", "EISA");
+ break;
+ case 0x06: /* PCI */
+ case 0x0E: /* PCI */
+ dmixml_AddAttribute(node, "slottype", "PCI");
+ break;
+ case 0x0F: /* AGP */
+ case 0x10: /* AGP */
+ case 0x11: /* AGP */
+ case 0x13: /* AGP */
+ dmixml_AddAttribute(node, "slottype", "");
+ break;
+ case 0x12: /* PCI-X */
+ dmixml_AddAttribute(node, "slottype", "PCI-X");
+ break;
+ case 0xA5: /* PCI Express */
+ dmixml_AddAttribute(node, "slottype", "PCI Express");
+ break;
+ case 0x07: /* PCMCIA */
+ dmixml_AddAttribute(node, "slottype", "PCMCIA");
+ break;
+ default:
+ break;
+ }
+}
+
+void dmi_slot_id(xmlNode *node, u8 code1, u8 code2, u8 type)
+{
+ xmlNode *slotid_n = xmlNewChild(node, NULL, (xmlChar *) "SlotID", NULL);
+ dmixml_AddAttribute(slotid_n, "dmispec", "3.3.10.5");
+ dmixml_AddAttribute(slotid_n, "flags1", "0x%04x", code1);
+ dmixml_AddAttribute(slotid_n, "flags2", "0x%04x", code2);
+ dmixml_AddAttribute(slotid_n, "type", "0x%04x", type);
+ switch (type) {
+ case 0x04: /* MCA */
+ dmixml_AddAttribute(slotid_n, "id", "%i", code1);
+ break;
+ case 0x05: /* EISA */
+ dmixml_AddAttribute(slotid_n, "id", "%i", code1);
+ break;
+ case 0x06: /* PCI */
+ case 0x0E: /* PCI */
+ case 0x0F: /* AGP */
+ case 0x10: /* AGP */
+ case 0x11: /* AGP */
+ case 0x12: /* PCI-X */
+ case 0x13: /* AGP */
+ case 0xA5: /* PCI Express */
+ dmixml_AddAttribute(slotid_n, "id", "%i", code1);
+ break;
+ case 0x07: /* PCMCIA */
+ dmixml_AddAttribute(slotid_n, "adapter", "%i", code1);
+ dmixml_AddAttribute(slotid_n, "id", "%i", code2);
+ break;
+ default:
+ break;
+ }
+ set_slottype(slotid_n, type);
+}
+
+void dmi_slot_characteristics(xmlNode *node, u8 code1, u8 code2)
+{
+ /* 3.3.10.6 */
+ static const char *characteristics1[] = {
+ "5.0 V is provided", /* 1 */
+ "3.3 V is provided",
+ "Opening is shared",
+ "PC Card-16 is supported",
+ "Cardbus is supported",
+ "Zoom Video is supported",
+ "Modem ring resume is supported" /* 7 */
+ };
+
+ /* 3.3.10.7 */
+ static const char *characteristics2[] = {
+ "PME signal is supported", /* 0 */
+ "Hot-plug devices are supported",
+ "SMBus signal is supported" /* 2 */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "SlotCharacteristics", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.10.6");
+ dmixml_AddAttribute(data_n, "flags1", "0x%04x", code1);
+ dmixml_AddAttribute(data_n, "flags2", "0x%04x", code2);
+
+ if(code1 & (1 << 0)) {
+ dmixml_AddAttribute(data_n, "unknown", "1");
+ } else if((code1 & 0xFE) == 0 && (code2 & 0x07) == 0) {
+ // Nothing - empty tag
+ } else {
+ int i;
+
+ for(i = 1; i <= 7; i++) {
+ if(code1 & (1 << i)) {
+ xmlNode *c_n = dmixml_AddTextChild(data_n, "Characteristic", "%s",
+ characteristics1[i - 1]);
+ dmixml_AddAttribute(c_n, "index", "%i", i);
+ c_n = NULL;
+ }
+ }
+ for(i = 0; i <= 2; i++) {
+ if(code2 & (1 << i)) {
+ xmlNode *c_n = dmixml_AddTextChild(data_n, "Characteristic", "%s",
+ characteristics2[i]);
+ dmixml_AddAttribute(c_n, "index", "%i", i+8);
+ c_n = NULL;
+ }
+ }
+ }
+}
+
+void dmi_slot_segment_bus_func(xmlNode *node, u16 code1, u8 code2, u8 code3)
+{
+ /* 3.3.10.8 */
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "BusAddress", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.10.8");
+
+ if(!(code1 == 0xFFFF && code2 == 0xFF && code3 == 0xFF)) {
+ dmixml_AddTextContent(data_n, "%04x:%02x:%02x.%x", code1, code2, code3 >> 3, code3 & 0x7);
+ }
}
/*******************************************************************************
** 3.3.11 On Board Devices Information (Type 10)
*/
-static const char *dmi_on_board_devices_type(u8 code) {
- /* 3.3.11.1 */
- static const char *type[]={
- "Other", /* 0x01 */
- "Unknown",
- "Video",
- "SCSI Controller",
- "Ethernet",
- "Token Ring",
- "Sound",
- "PATA Controller",
- "SATA Controller",
- "SAS Controller" /* 0x0A */
- };
-
- if(code>=0x01 && code<=0x0A) return type[code-0x01];
- return out_of_spec;
-}
-
-static PyObject *dmi_on_board_devices(struct dmi_header *h) {
- PyObject *data = NULL;
- u8 *p = h->data+4;
- u8 count = (h->length-0x04)/2;
- int i;
-
- if((data = PyList_New(count))) {
- PyObject *_pydict;
- PyObject *_val;
- for(i=0; i<count; i++) {
- _pydict = PyDict_New();
-
- _val = PyString_FromString(dmi_on_board_devices_type(p[2*i]&0x7F));
- PyDict_SetItemString(_pydict, "Type", _val);
- Py_DECREF(_val);
-
- _val = p[2*i]&0x80?Py_True:Py_False;
- PyDict_SetItemString(_pydict, "Enabled", _val);
- Py_DECREF(_val);
-
- _val = dmi_string_py(h, p[2*i+1]);
- PyDict_SetItemString(_pydict, "Description", _val);
- Py_DECREF(_val);
-
- PyList_SET_ITEM(data, i, _pydict);
- }
- }
-
- assert(data != NULL);
- Py_INCREF(data);
- return data;
+void dmi_on_board_devices_type(xmlNode *node, u8 code)
+{
+ /* 3.3.11.1 */
+ static const char *type[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "Video",
+ "SCSI Controller",
+ "Ethernet",
+ "Token Ring",
+ "Sound",
+ "PATA Controller",
+ "SATA Controller",
+ "SAS Controller" /* 0x0A */
+ };
+
+ dmixml_AddAttribute(node, "dmispec", "3.3.11.1");
+ dmixml_AddAttribute(node, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x0A) {
+ dmixml_AddTextChild(node, "Type", "%s", type[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(node, "outofspec", "1");
+ }
+}
+
+void dmi_on_board_devices(xmlNode *node, const char *tagname, struct dmi_header *h)
+{
+ u8 *p = h->data + 4;
+ u8 count = (h->length - 0x04) / 2;
+ int i;
+
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.11");
+
+ for(i = 0; i < count; i++) {
+ xmlNode *dev_n = xmlNewChild(data_n, NULL, (xmlChar *) "Device", NULL);
+ assert( dev_n != NULL );
+
+ dmi_on_board_devices_type(dev_n, p[2 * i] & 0x7F);
+ dmixml_AddAttribute(dev_n, "Enabled", "%i", ((p[2 * i] & 0x80) ? 1 : 0));
+ dmixml_AddTextChild(dev_n, "Description", "%s", dmi_string(h, p[2 * i + 1]));
+ dev_n = NULL;
+ }
}
/*******************************************************************************
* 3.3.12 OEM Strings (Type 11)
*/
-static PyObject *dmi_oem_strings(struct dmi_header *h) {
- u8 *p=h->data+4;
- u8 count=p[0x00];
- int i;
-
- PyObject *data = PyDict_New();
- PyObject *val;
+void dmi_oem_strings(xmlNode *node, struct dmi_header *h)
+{
+ u8 *p = h->data + 4;
+ u8 count = p[0x00];
+ int i;
- for(i=1; i<=count; i++) {
- val = dmi_string_py(h, i);
- PyDict_SetItem(data, PyInt_FromLong(i), val);
- Py_DECREF(val);
- }
+ dmixml_AddAttribute(node, "count", "%i", count);
- return data;
+ for(i = 1; i <= count; i++) {
+ xmlNode *str_n = dmixml_AddTextChild(node, "Record", "%s", dmi_string(h, i));
+ assert( str_n != NULL );
+ dmixml_AddAttribute(str_n, "index", "%i", i);
+ }
}
/*******************************************************************************
** 3.3.13 System Configuration Options (Type 12)
*/
-static PyObject *dmi_system_configuration_options(struct dmi_header *h) {
- u8 *p=h->data+4;
- u8 count=p[0x00];
- int i;
+void dmi_system_configuration_options(xmlNode *node, struct dmi_header *h)
+{
+ u8 *p = h->data + 4;
+ u8 count = p[0x00];
+ int i;
+
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Options", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.13");
+ dmixml_AddAttribute(data_n, "count", "%i", count);
- PyObject *data = PyDict_New();
- PyObject *val;
- for(i=1; i<=count; i++) {
- val = dmi_string_py(h, i);
- PyDict_SetItem(data, PyInt_FromLong(i), val);
- Py_DECREF(val);
- }
+ for(i = 1; i <= count; i++) {
+ xmlNode *o_n = dmixml_AddTextChild(data_n, "Option", "%s", dmi_string(h, i));
+ assert( o_n != NULL );
- return data;
+ dmixml_AddAttribute(o_n, "index", "%ld", i);
+ }
}
/*******************************************************************************
** 3.3.14 BIOS Language Information (Type 13)
*/
-static PyObject *dmi_bios_languages(struct dmi_header *h) {
- u8 *p = h->data+4;
- u8 count = p[0x00];
- int i;
-
- PyObject *data = PyList_New(count + 1);
- for(i=1; i<=count; i++)
- PyList_SET_ITEM(data, i, dmi_string_py(h, i));
-
- return data;
+void dmi_bios_languages(xmlNode *node, struct dmi_header *h)
+{
+ u8 *p = h->data + 4;
+ u8 count = p[0x00];
+ int i;
+
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Installed", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.14");
+ dmixml_AddAttribute(data_n, "count", "%i", count);
+
+ for(i = 1; i <= count; i++) {
+ xmlNode *l_n = dmixml_AddTextChild(data_n, "Language", "%s", dmi_string(h, i));
+ assert( l_n != NULL );
+ dmixml_AddAttribute(l_n, "index", "%i", i);
+ }
}
/*******************************************************************************
** 3.3.15 Group Associations (Type 14)
*/
-static PyObject *dmi_group_associations_items(u8 count, const u8 *p) {
- int i;
+void dmi_group_associations_items(xmlNode *node, u8 count, const u8 * p)
+{
+ dmixml_AddAttribute(node, "dmispec", "3.3.15");
+ dmixml_AddAttribute(node, "items", "%i", count);
+
+ int i;
+ for(i = 0; i < count; i++) {
+ xmlNode *grp_n = xmlNewChild(node, NULL, (xmlChar *) "Group", NULL);
+ assert( grp_n != NULL );
- PyObject *data = PyList_New(count);
- PyObject *val;
- for(i=0; i<count; i++) {
- val = PyString_FromFormat("0x%04x (%s)",
- WORD(p+3*i+1),
- dmi_smbios_structure_type(p[3*i])
- );
- PyList_SET_ITEM(data, i, val);
- }
- return data;
+ dmixml_AddAttribute(grp_n, "handle", "0x%04x", WORD(p + 3 * i + 1));
+ dmi_smbios_structure_type(grp_n, p[3 * i]);
+ }
}
/*******************************************************************************
** 3.3.16 System Event Log (Type 15)
*/
-static const char *dmi_event_log_method(u8 code) {
- static const char *method[]={
- "Indexed I/O, one 8-bit index port, one 8-bit data port", /* 0x00 */
- "Indexed I/O, two 8-bit index ports, one 8-bit data port",
- "Indexed I/O, one 16-bit index port, one 8-bit data port",
- "Memory-mapped physical 32-bit address",
- "General-purpose non-volatile data functions" /* 0x04 */
- };
-
- if(code<=0x04) return method[code];
- if(code>=0x80) return "OEM-specific";
- return out_of_spec;
-}
-
-static PyObject *dmi_event_log_status_py(u8 code) {
- static const char *valid[]={
- "Invalid", /* 0 */
- "Valid" /* 1 */
- };
- static const char *full[]={
- "Not Full", /* 0 */
- "Full" /* 1 */
- };
-
- return PyString_FromFormat("%s, %s", valid[(code>>0)&1], full[(code>>1)&1]);
-}
-
-static PyObject *dmi_event_log_address_py(u8 method, const u8 *p) {
- /* 3.3.16.3 */
- switch(method) {
- case 0x00:
- case 0x01:
- case 0x02:
- return PyString_FromFormat("Index 0x%04x, Data 0x%04x", WORD(p), WORD(p+2));
- break;
- case 0x03:
- return PyString_FromFormat("0x%08x", DWORD(p));
- break;
- case 0x04:
- return PyString_FromFormat("0x%04x", WORD(p));
- break;
- default:
- return PyString_FromString("Unknown");
- }
-}
-
-static const char *dmi_event_log_header_type(u8 code) {
- static const char *type[]={
- "No Header", /* 0x00 */
- "Type 1" /* 0x01 */
- };
-
- if(code<=0x01) return type[code];
- if(code>=0x80) return "OEM-specific";
- return out_of_spec;
-}
-
-static PyObject *dmi_event_log_descriptor_type(u8 code) {
- /* 3.3.16.6.1 */
- static const char *type[]={
- NULL, /* 0x00 */
- "Single-bit ECC memory error",
- "Multi-bit ECC memory error",
- "Parity memory error",
- "Bus timeout",
- "I/O channel block",
- "Software NMI",
- "POST memory resize",
- "POST error",
- "PCI parity error",
- "PCI system error",
- "CPU failure",
- "EISA failsafe timer timeout",
- "Correctable memory log disabled",
- "Logging disabled",
- NULL, /* 0x0F */
- "System limit exceeded",
- "Asynchronous hardware timer expired",
- "System configuration information",
- "Hard disk information",
- "System reconfigured",
- "Uncorrectable CPU-complex error",
- "Log area reset/cleared",
- "System boot" /* 0x17 */
- };
-
- const char *data;
- if(code<=0x17 && type[code]!=NULL) data = type[code];
- else if(code>=0x80 && code<=0xFE) data = "OEM-specific";
- else if(code==0xFF) data = "End of log";
- else data = out_of_spec;
- return PyString_FromString(data);
-}
-
-static PyObject *dmi_event_log_descriptor_format(u8 code) {
- /* 3.3.16.6.2 */
- static const char *format[]={
- "None", /* 0x00 */
- "Handle",
- "Multiple-event",
- "Multiple-event handle",
- "POST results bitmap",
- "System management",
- "Multiple-event system management" /* 0x06 */
- };
-
- const char *data;
- if(code<=0x06) data = format[code];
- else if(code>=0x80) data = "OEM-specific";
- else data = out_of_spec;
- return PyString_FromString(data);
-}
-
-static PyObject *dmi_event_log_descriptors(u8 count, const u8 len, const u8 *p) {
- /* 3.3.16.1 */
- int i;
-
- PyObject* data;
- data = PyList_New(count);
- for(i=0; i<count; i++) {
- if(len>=0x02) {
- PyObject *subdata = PyDict_New();
- PyDict_SetItemString(subdata, "Descriptor", dmi_event_log_descriptor_type(p[i*len]));
- PyDict_SetItemString(subdata, "Data Format", dmi_event_log_descriptor_format(p[i*len+1]));
- PyList_SET_ITEM(data, i, subdata);
- }
- }
- return data;
+void dmi_event_log_method(xmlNode *node, u8 code)
+{
+ static const char *method[] = {
+ "Indexed I/O, one 8-bit index port, one 8-bit data port", /* 0x00 */
+ "Indexed I/O, two 8-bit index ports, one 8-bit data port",
+ "Indexed I/O, one 16-bit index port, one 8-bit data port",
+ "Memory-mapped physical 32-bit address",
+ "General-purpose non-volatile data functions" /* 0x04 */
+ };
+
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "AccessMethod", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.16");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code <= 0x04) {
+ dmixml_AddTextContent(data_n, "%s", method[code]);
+ } else if(code >= 0x80){
+ dmixml_AddTextContent(data_n, "OEM-specific");
+ dmixml_AddAttribute(data_n, "unknown", "1");
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
+}
+
+void dmi_event_log_status(xmlNode *node, u8 code)
+{
+ static const char *valid[] = {
+ "Invalid", /* 0 */
+ "Valid" /* 1 */
+ };
+ static const char *full[] = {
+ "Not Full", /* 0 */
+ "Full" /* 1 */
+ };
+
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Status", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.16");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ // FIXME: Should we use 0/1 instead of strings?
+ dmixml_AddAttribute(data_n, "Full", "%s", full[(code >> 1) & 1]);
+ dmixml_AddAttribute(data_n, "Valid", "%s", valid[(code >> 0) & 1]);
+}
+
+void dmi_event_log_address(xmlNode *node, u8 method, const u8 * p)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Address", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.16.3");
+ dmixml_AddAttribute(data_n, "method", "0x%04x", method);
+
+ /* 3.3.16.3 */
+ switch (method) {
+ case 0x00:
+ case 0x01:
+ case 0x02:
+ dmixml_AddAttribute(data_n, "Index", "0x%04x", WORD(p));
+ dmixml_AddAttribute(data_n, "Data", "0x%04x", WORD(p + 2));
+ break;
+ case 0x03:
+ dmixml_AddAttribute(data_n, "Data", "0x%08x", DWORD(p));
+ break;
+ case 0x04:
+ dmixml_AddAttribute(data_n, "Data", "0x%04x", WORD(p));
+ break;
+ default:
+ dmixml_AddAttribute(data_n, "unknown", "1");
+ }
+}
+
+void dmi_event_log_header_type(xmlNode *node, u8 code)
+{
+ static const char *type[] = {
+ "No Header", /* 0x00 */
+ "Type 1" /* 0x01 */
+ };
+
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Format", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.16");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code <= 0x01) {
+ dmixml_AddTextContent(data_n, type[code]);
+ } else if(code >= 0x80) {
+ dmixml_AddTextContent(data_n, "OEM-specific");
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
+}
+
+void dmi_event_log_descriptor_type(xmlNode *node, u8 code)
+{
+ /* 3.3.16.6.1 */
+ static const char *type[] = {
+ NULL, /* 0x00 */
+ "Single-bit ECC memory error",
+ "Multi-bit ECC memory error",
+ "Parity memory error",
+ "Bus timeout",
+ "I/O channel block",
+ "Software NMI",
+ "POST memory resize",
+ "POST error",
+ "PCI parity error",
+ "PCI system error",
+ "CPU failure",
+ "EISA failsafe timer timeout",
+ "Correctable memory log disabled",
+ "Logging disabled",
+ NULL, /* 0x0F */
+ "System limit exceeded",
+ "Asynchronous hardware timer expired",
+ "System configuration information",
+ "Hard disk information",
+ "System reconfigured",
+ "Uncorrectable CPU-complex error",
+ "Log area reset/cleared",
+ "System boot" /* 0x17 */
+ };
+
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Descriptor", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.16.6.1");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code <= 0x17 && type[code] != NULL) {
+ dmixml_AddTextContent(data_n, "%s", type[code]);
+ } else if(code >= 0x80 && code <= 0xFE) {
+ dmixml_AddTextContent(data_n, "OEM-specific");
+ } else if(code == 0xFF) {
+ dmixml_AddTextContent(data_n, "End of log");
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
+}
+
+void dmi_event_log_descriptor_format(xmlNode *node, u8 code)
+{
+ /* 3.3.16.6.2 */
+ static const char *format[] = {
+ "None", /* 0x00 */
+ "Handle",
+ "Multiple-event",
+ "Multiple-event handle",
+ "POST results bitmap",
+ "System management",
+ "Multiple-event system management" /* 0x06 */
+ };
+
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Format", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.16.6.2");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code <= 0x06) {
+ dmixml_AddTextContent(data_n, format[code]);
+ } else if(code >= 0x80) {
+ dmixml_AddTextContent(data_n, "OEM-specific");
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
+}
+
+void dmi_event_log_descriptors(xmlNode *node, u8 count, const u8 len, const u8 * p)
+{
+ /* 3.3.16.1 */
+ int i;
+
+ dmixml_AddAttribute(node, "dmispec", "3.3.16.1");
+
+ for(i = 0; i < count; i++) {
+ if(len >= 0x02) {
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "LogType", NULL);
+ assert( data_n != NULL );
+
+ dmi_event_log_descriptor_type(data_n, p[i * len]);
+ dmi_event_log_descriptor_format(data_n, p[i * len + 1]);
+ }
+ }
}
/*******************************************************************************
** 3.3.17 Physical Memory Array (Type 16)
*/
-static PyObject *dmi_memory_array_location(u8 code) {
- /* 3.3.17.1 */
- static const char *location[]={
- "Other", /* 0x01 */
- "Unknown",
- "System Board Or Motherboard",
- "ISA Add-on Card",
- "EISA Add-on Card",
- "PCI Add-on Card",
- "MCA Add-on Card",
- "PCMCIA Add-on Card",
- "Proprietary Add-on Card",
- "NuBus" /* 0x0A, master.mif says 16 */
- };
- static const char *location_0xA0[]={
- "PC-98/C20 Add-on Card", /* 0xA0 */
- "PC-98/C24 Add-on Card",
- "PC-98/E Add-on Card",
- "PC-98/Local Bus Add-on Card",
- "PC-98/Card Slot Add-on Card" /* 0xA4, from master.mif */
- };
-
- if(code>=0x01 && code<=0x0A) return PyString_FromString(location[code-0x01]);
- if(code>=0xA0 && code<=0xA4) return PyString_FromString(location_0xA0[code-0xA0]);
- return OUT_OF_SPEC;
-}
-
-static PyObject *dmi_memory_array_use(u8 code) {
- /* 3.3.17.2 */
- static const char *use[]={
- "Other", /* 0x01 */
- "Unknown",
- "System Memory",
- "Video Memory",
- "Flash Memory",
- "Non-volatile RAM",
- "Cache Memory" /* 0x07 */
- };
-
- if(code>=0x01 && code<=0x07) return PyString_FromString(use[code-0x01]);
- return OUT_OF_SPEC;
-}
-
-static PyObject *dmi_memory_array_ec_type(u8 code) {
- /* 3.3.17.3 */
- static const char *type[]={
- "Other", /* 0x01 */
- "Unknown",
- "None",
- "Parity",
- "Single-bit ECC",
- "Multi-bit ECC",
- "CRC" /* 0x07 */
- };
-
- if(code>=0x01 && code<=0x07) return PyString_FromString(type[code-0x01]);
- return OUT_OF_SPEC;
-}
-
-static PyObject *dmi_memory_array_capacity(u32 code) {
- PyObject *data;
- if(code==0x8000000) data = PyString_FromString("Unknown");
- else {
- if((code&0x000FFFFF)==0) data = PyString_FromFormat("%i GB", code>>20);
- else if((code&0x000003FF)==0) data = PyString_FromFormat("%i MB", code>>10);
- else data = PyString_FromFormat("%i kB", code);
- }
- return data;
-}
-
-static PyObject *dmi_memory_array_error_handle(u16 code) {
- PyObject *data;
- if(code==0xFFFE) data = PyString_FromString("Not Provided");
- else if(code==0xFFFF) data = PyString_FromString("No Error");
- else data = PyString_FromFormat("0x%04x", code);
- return data;
+void dmi_memory_array_location(xmlNode *node, u8 code)
+{
+ /* 3.3.17.1 */
+ static const char *location[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "System Board Or Motherboard",
+ "ISA Add-on Card",
+ "EISA Add-on Card",
+ "PCI Add-on Card",
+ "MCA Add-on Card",
+ "PCMCIA Add-on Card",
+ "Proprietary Add-on Card",
+ "NuBus" /* 0x0A, master.mif says 16 */
+ };
+ static const char *location_0xA0[] = {
+ "PC-98/C20 Add-on Card", /* 0xA0 */
+ "PC-98/C24 Add-on Card",
+ "PC-98/E Add-on Card",
+ "PC-98/Local Bus Add-on Card",
+ "PC-98/Card Slot Add-on Card" /* 0xA4, from master.mif */
+ };
+
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Location", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.17.1");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x0A) {
+ dmixml_AddTextContent(data_n, location[code - 0x01]);
+ } else if(code >= 0xA0 && code <= 0xA4) {
+ dmixml_AddTextContent(data_n, location_0xA0[code - 0xA0]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
+}
+
+void dmi_memory_array_use(xmlNode *node, u8 code)
+{
+ /* 3.3.17.2 */
+ static const char *use[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "System Memory",
+ "Video Memory",
+ "Flash Memory",
+ "Non-volatile RAM",
+ "Cache Memory" /* 0x07 */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Use", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.17.2");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x07) {
+ dmixml_AddTextContent(data_n, use[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
+}
+
+void dmi_memory_array_ec_type(xmlNode *node, u8 code)
+{
+ /* 3.3.17.3 */
+ static const char *type[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "None",
+ "Parity",
+ "Single-bit ECC",
+ "Multi-bit ECC",
+ "CRC" /* 0x07 */
+ };
+
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "ErrorCorrectionType", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.17.3");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x07) {
+ dmixml_AddTextContent(data_n, type[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
+}
+
+void dmi_memory_array_capacity(xmlNode *node, u32 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "MaxCapacity", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code == 0x8000000) {
+ dmixml_AddAttribute(data_n, "unknown", "1");
+ } else {
+ if((code & 0x000FFFFF) == 0) {
+ dmixml_AddAttribute(data_n, "unit", "GB");
+ dmixml_AddTextContent(data_n, "%i", code >> 20);
+ } else if((code & 0x000003FF) == 0) {
+ dmixml_AddAttribute(data_n, "unit", "MB");
+ dmixml_AddTextContent(data_n, "%i", code >> 10);
+ } else {
+ dmixml_AddAttribute(data_n, "unit", "KB");
+ dmixml_AddTextContent(data_n, "%i", code);
+ }
+ }
+}
+
+void dmi_memory_array_error_handle(xmlNode *node, u16 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "ErrorInfoHandle", NULL);
+ assert( data_n != NULL );
+
+ if(code == 0xFFFE) {
+ dmixml_AddAttribute(data_n, "not_provided", "1");
+ } else if(code == 0xFFFF) {
+ dmixml_AddAttribute(data_n, "no_error", "1");
+ } else {
+ dmixml_AddTextContent(data_n, "0x%04x", code);
+ }
}
/*******************************************************************************
** 3.3.18 Memory Device (Type 17)
*/
-static PyObject *dmi_memory_device_width(u16 code) {
- /*
- ** If no memory module is present, width may be 0
- */
- PyObject *data;
- if(code==0xFFFF || code==0) data = PyString_FromString("Unknown");
- else data = PyString_FromFormat("%i bits", code);
- return data;
-}
-
-static PyObject *dmi_memory_device_size(u16 code) {
- PyObject *data = NULL;
- if(code==0) data = Py_None; //. No Module Installed
- else if(code==0xFFFF) data = PyString_FromString("Unknown"); //. Unknown
- else {
- //. Keeping this as String rather than Int as it has KB and MB representations...
- if(code&0x8000) data = PyString_FromFormat("%d KB", code&0x7FFF);
- else data = PyString_FromFormat("%d MB", code);
- }
- return data;
-}
-
-static PyObject *dmi_memory_device_form_factor(u8 code) {
- /* 3.3.18.1 */
- static const char *form_factor[]={
- "Other", /* 0x01 */
- "Unknown",
- "SIMM",
- "SIP",
- "Chip",
- "DIP",
- "ZIP",
- "Proprietary Card",
- "DIMM",
- "TSOP",
- "Row Of Chips",
- "RIMM",
- "SODIMM",
- "SRIMM",
- "FB-DIMM" /* 0x0F */
- };
- PyObject *data;
-
- if(code>=0x01 && code<=0x0F) return data = PyString_FromString(form_factor[code-0x01]);
- return data = OUT_OF_SPEC;
-}
-
-static PyObject *dmi_memory_device_set(u8 code) {
- PyObject *data;
- if(code==0) data = Py_None;
- else if(code==0xFF) data = PyString_FromString("Unknown");
- else data = PyInt_FromLong(code);
- return data;
-}
-
-static PyObject *dmi_memory_device_type(u8 code) {
- /* 3.3.18.2 */
- static const char *type[]={
- "Other", /* 0x01 */
- "Unknown",
- "DRAM",
- "EDRAM",
- "VRAM",
- "SRAM",
- "RAM",
- "ROM",
- "Flash",
- "EEPROM",
- "FEPROM",
- "EPROM",
- "CDRAM",
- "3DRAM",
- "SDRAM",
- "SGRAM",
- "RDRAM",
- "DDR",
- "DDR2",
- "DDR2 FB-DIMM" /* 0x14 */
- };
-
- if(code>=0x01 && code<=0x14) return PyString_FromString(type[code-0x01]);
- return OUT_OF_SPEC;
-}
-
-static PyObject *dmi_memory_device_type_detail(u16 code) {
- /* 3.3.18.3 */
- static const char *detail[]={
- "Other", /* 1 */
- "Unknown",
- "Fast-paged",
- "Static Column",
- "Pseudo-static",
- "RAMBus",
- "Synchronous",
- "CMOS",
- "EDO",
- "Window DRAM",
- "Cache DRAM",
- "Non-Volatile" /* 12 */
- };
-
- PyObject *data;
- if((code&0x1FFE)==0) data = Py_None;
- else {
- int i;
-
- data = PyList_New(12);
- for(i=1; i<=12; i++)
- if(code&(1<<i))
- PyList_SET_ITEM(data, i-1, PyString_FromString(detail[i-1]));
- else
- PyList_SET_ITEM(data, i-1, Py_None);
- }
- return data;
-}
-
-static PyObject *dmi_memory_device_speed(u16 code) {
- PyObject *data;
- if(code==0) data = PyString_FromString("Unknown");
- else data = PyString_FromFormat("%i MHz (%.1f ns)", code, (float)1000/code);
- return data;
+void dmi_memory_device_width(xmlNode *node, const char *tagname, u16 code)
+{
+ /*
+ ** If no memory module is present, width may be 0
+ */
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
+ assert( data_n != NULL );
+
+ if(code == 0xFFFF || code == 0) {
+ dmixml_AddAttribute(data_n, "unknown", "1");
+ } else {
+ dmixml_AddAttribute(data_n, "unit", "bit");
+ dmixml_AddTextContent(data_n, "%i", code);
+ }
+}
+
+void dmi_memory_device_size(xmlNode *node, u16 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Size", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code == 0) {
+ dmixml_AddAttribute(data_n, "empty", "1");
+ } else if(code == 0xFFFF) {
+ dmixml_AddAttribute(data_n, "unknown", "1");
+ } else {
+ //. Keeping this as String rather than Int as it has KB and MB representations...
+ dmixml_AddAttribute(data_n, "unit", "%s", (code & 0x8000 ? "KB" : "MB"));
+ dmixml_AddTextContent(data_n, "%d", (code & 0x8000 ? code & 0x7FFF : code));
+ }
+}
+
+void dmi_memory_device_form_factor(xmlNode *node, u8 code)
+{
+ /* 3.3.18.1 */
+ static const char *form_factor[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "SIMM",
+ "SIP",
+ "Chip",
+ "DIP",
+ "ZIP",
+ "Proprietary Card",
+ "DIMM",
+ "TSOP",
+ "Row Of Chips",
+ "RIMM",
+ "SODIMM",
+ "SRIMM",
+ "FB-DIMM" /* 0x0F */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "FormFactor", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.18.1");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x0F) {
+ dmixml_AddTextContent(data_n, "%s", form_factor[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
+}
+
+void dmi_memory_device_set(xmlNode *node, u8 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Set", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code == 0xFF) {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ } else if( code > 0 ) {
+ dmixml_AddTextContent(data_n, "%ld", code);
+ }
+}
+
+void dmi_memory_device_type(xmlNode *node, u8 code)
+{
+ /* 3.3.18.2 */
+ static const char *type[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "DRAM",
+ "EDRAM",
+ "VRAM",
+ "SRAM",
+ "RAM",
+ "ROM",
+ "Flash",
+ "EEPROM",
+ "FEPROM",
+ "EPROM",
+ "CDRAM",
+ "3DRAM",
+ "SDRAM",
+ "SGRAM",
+ "RDRAM",
+ "DDR",
+ "DDR2",
+ "DDR2 FB-DIMM" /* 0x14 */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Type", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.18.2");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x14) {
+ dmixml_AddTextContent(data_n, "%s", type[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
+}
+
+void dmi_memory_device_type_detail(xmlNode *node, u16 code)
+{
+ /* 3.3.18.3 */
+ static const char *detail[] = {
+ "Other", /* 1 */
+ "Unknown",
+ "Fast-paged",
+ "Static Column",
+ "Pseudo-static",
+ "RAMBus",
+ "Synchronous",
+ "CMOS",
+ "EDO",
+ "Window DRAM",
+ "Cache DRAM",
+ "Non-Volatile" /* 12 */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "TypeDetails", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.18.3");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if((code & 0x1FFE) != 0) {
+ int i;
+ for(i = 1; i <= 12; i++) {
+ if(code & (1 << i)) {
+ xmlNode *td_n = dmixml_AddTextChild(data_n, "flag", "%s", detail[i - 1]);
+ assert( td_n != NULL );
+ dmixml_AddAttribute(td_n, "index", "%i", i);
+ }
+ }
+ }
+}
+
+void dmi_memory_device_speed(xmlNode *node, u16 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Speed", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code == 0) {
+ dmixml_AddAttribute(data_n, "unkown", "1");
+ } else {
+ dmixml_AddAttribute(data_n, "speed_ns", "%.1f", (float) 1000 / code);
+ dmixml_AddAttribute(data_n, "unit", "MHz");
+ dmixml_AddTextContent(data_n, "%i", code);
+ }
}
/*******************************************************************************
* 3.3.19 32-bit Memory Error Information (Type 18)
*/
-static PyObject *dmi_memory_error_type(u8 code) {
- /* 3.3.19.1 */
- static const char *type[]={
- "Other", /* 0x01 */
- "Unknown",
- "OK",
- "Bad Read",
- "Parity Error",
- "Single-bit Error",
- "Double-bit Error",
- "Multi-bit Error",
- "Nibble Error",
- "Checksum Error",
- "CRC Error",
- "Corrected Single-bit Error",
- "Corrected Error",
- "Uncorrectable Error" /* 0x0E */
- };
- PyObject *data;
-
- if(code>=0x01 && code<=0x0E) data = PyString_FromString(type[code-0x01]);
- data = OUT_OF_SPEC;
- return data;
-}
-
-static PyObject *dmi_memory_error_granularity(u8 code) {
- /* 3.3.19.2 */
- static const char *granularity[]={
- "Other", /* 0x01 */
- "Unknown",
- "Device Level",
- "Memory Partition Level" /* 0x04 */
- };
- PyObject *data;
-
- if(code>=0x01 && code<=0x04) data = PyString_FromString(granularity[code-0x01]);
- else data = OUT_OF_SPEC;
- return data;
-}
-
-static PyObject *dmi_memory_error_operation(u8 code) {
- /* 3.3.19.3 */
- static const char *operation[]={
- "Other", /* 0x01 */
- "Unknown",
- "Read",
- "Write",
- "Partial Write" /* 0x05 */
- };
- PyObject *data;
-
- if(code>=0x01 && code<=0x05) data = PyString_FromString(operation[code-0x01]);
- else data = OUT_OF_SPEC;
- return data;
-}
-
-static PyObject *dmi_memory_error_syndrome(u32 code) {
- PyObject *data;
- if(code==0x00000000) data = PyString_FromString("Unknown");
- else data = PyString_FromFormat("0x%08x", code);
- return data;
-}
-
-static PyObject *dmi_32bit_memory_error_address(u32 code) {
- PyObject *data;
- if(code==0x80000000) data = PyString_FromString("Unknown");
- else data = PyString_FromFormat("0x%08x", code);
- return data;
+void dmi_memory_error_type(xmlNode *node, u8 code)
+{
+ /* 3.3.19.1 */
+ static const char *type[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "OK",
+ "Bad Read",
+ "Parity Error",
+ "Single-bit Error",
+ "Double-bit Error",
+ "Multi-bit Error",
+ "Nibble Error",
+ "Checksum Error",
+ "CRC Error",
+ "Corrected Single-bit Error",
+ "Corrected Error",
+ "Uncorrectable Error" /* 0x0E */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Type", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.19.1");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x0E) {
+ dmixml_AddTextContent(data_n, "%s", type[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
+}
+
+void dmi_memory_error_granularity(xmlNode *node, u8 code)
+{
+ /* 3.3.19.2 */
+ static const char *granularity[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "Device Level",
+ "Memory Partition Level" /* 0x04 */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Granularity", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.19.2");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x04) {
+ dmixml_AddTextContent(data_n, "%s", granularity[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
+}
+
+void dmi_memory_error_operation(xmlNode *node, u8 code)
+{
+ /* 3.3.19.3 */
+ static const char *operation[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "Read",
+ "Write",
+ "Partial Write" /* 0x05 */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Operation", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.19.3");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x05) {
+ dmixml_AddTextContent(data_n, "%s", operation[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
+}
+
+void dmi_memory_error_syndrome(xmlNode *node, u32 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "VendorSyndrome", NULL);
+ assert( data_n != NULL );
+
+ if(code == 0x00000000) {
+ dmixml_AddAttribute(data_n, "unknown", "1");
+ } else {
+ dmixml_AddTextContent(data_n, "0x%08x", code);
+ }
+}
+
+void dmi_32bit_memory_error_address(xmlNode *node, char *tagname, u32 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
+ assert( data_n != NULL );
+
+ if(code == 0x80000000) {
+ dmixml_AddAttribute(data_n, "unknown", "1");
+ } else {
+ dmixml_AddTextContent(data_n, "0x%08x", code);
+ }
}
/*******************************************************************************
** 3.3.20 Memory Array Mapped Address (Type 19)
*/
-static PyObject *dmi_mapped_address_size(u32 code) {
- PyObject *data;
- if(code==0) data = PyString_FromString("Invalid");
- else if((code&0x000FFFFF)==0) data = PyString_FromFormat("%i GB", code>>20);
- else if((code&0x000003FF)==0) data = PyString_FromFormat("%i MB", code>>10);
- else data = PyString_FromFormat("%i kB", code);
- return data;
+void dmi_mapped_address_size(xmlNode *node, u32 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "RangeSize", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.19.2");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code == 0) {
+ dmixml_AddAttribute(data_n, "invalid", "1");
+ } else if((code & 0x000FFFFF) == 0) {
+ dmixml_AddAttribute(data_n, "unit", "GB");
+ dmixml_AddTextContent(data_n, "%i", code >> 20);
+ } else if((code & 0x000003FF) == 0) {
+ dmixml_AddAttribute(data_n, "unit", "MB");
+ dmixml_AddTextContent(data_n, "%i", code >> 10);
+ } else {
+ dmixml_AddAttribute(data_n, "unit", "KB");
+ dmixml_AddTextContent(data_n, "%i", code);
+ }
}
/*******************************************************************************
** 3.3.21 Memory Device Mapped Address (Type 20)
*/
-static PyObject *dmi_mapped_address_row_position(u8 code) {
- PyObject *data;
- if(code==0) data = OUT_OF_SPEC;
- else if(code==0xFF) data = PyString_FromString("Unknown");
- else data = PyInt_FromLong(code);
- return data;
+void dmi_mapped_address_row_position(xmlNode *node, u8 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "PartitionRowPosition", NULL);
+ assert( data_n != NULL );
+
+ if(code == 0) {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ } else if(code == 0xFF) {
+ dmixml_AddAttribute(data_n, "unknown", "1");
+ } else {
+ dmixml_AddTextContent(data_n, "%ld", code);
+ }
}
-static PyObject *dmi_mapped_address_interleave_position(u8 code) {
- PyObject *data;
- if(code!=0) {
- data = PyDict_New();
- PyDict_SetItemString(data, "Interleave Position", (code==0xFF)?PyString_FromString("Unknown"):PyInt_FromLong(code));
- } else data = Py_None;
- return data;
+void dmi_mapped_address_interleave_position(xmlNode *node, u8 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "InterleavePosition", NULL);
+ assert( data_n != NULL );
+
+ if( code <= 0xFE ) {
+ dmixml_AddTextContent(data_n, "%i", code);
+ } else {
+ dmixml_AddAttribute(data_n, "unknown", "1");
+ }
}
-static PyObject *dmi_mapped_address_interleaved_data_depth(u8 code) {
- PyObject *data;
- if(code!=0) {
- data = PyDict_New();
- PyDict_SetItemString(data, "Interleave Data Depth", (code==0xFF)?PyString_FromString("Unknown"):PyInt_FromLong(code));
- } else data = Py_None;
- return data;
+void dmi_mapped_address_interleaved_data_depth(xmlNode *node, u8 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "InterleaveDataDepth", NULL);
+ assert( data_n != NULL );
+
+ if( code < 0xFF ) {
+ dmixml_AddTextContent(data_n, "%i", code);
+ } else {
+ dmixml_AddAttribute(data_n, "unknown", "1");
+ }
}
/*******************************************************************************
** 3.3.22 Built-in Pointing Device (Type 21)
*/
-static PyObject *dmi_pointing_device_type(u8 code) {
- /* 3.3.22.1 */
- static const char *type[]={
- "Other", /* 0x01 */
- "Unknown",
- "Mouse",
- "Track Ball",
- "Track Point",
- "Glide Point",
- "Touch Pad",
- "Touch Screen",
- "Optical Sensor" /* 0x09 */
- };
- PyObject *data;
-
- if(code>=0x01 && code<=0x09) data = PyString_FromString(type[code-0x01]);
- else data = OUT_OF_SPEC;
- return data;
-}
-
-static PyObject *dmi_pointing_device_interface(u8 code) {
- /* 3.3.22.2 */
- static const char *interface[]={
- "Other", /* 0x01 */
- "Unknown",
- "Serial",
- "PS/2",
- "Infrared",
- "HIP-HIL",
- "Bus Mouse",
- "ADB (Apple Desktop Bus)" /* 0x08 */
- };
- static const char *interface_0xA0[]={
- "Bus Mouse DB-9", /* 0xA0 */
- "Bus Mouse Micro DIN",
- "USB" /* 0xA2 */
- };
- PyObject *data;
-
- if(code>=0x01 && code<=0x08) data = PyString_FromString(interface[code-0x01]);
- else if(code>=0xA0 && code<=0xA2) data = PyString_FromString(interface_0xA0[code-0xA0]);
- else data = OUT_OF_SPEC;
- return data;
+void dmi_pointing_device_type(xmlNode *node, u8 code)
+{
+ /* 3.3.22.1 */
+ static const char *type[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "Mouse",
+ "Track Ball",
+ "Track Point",
+ "Glide Point",
+ "Touch Pad",
+ "Touch Screen",
+ "Optical Sensor" /* 0x09 */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "DeviceType", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.22.1");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x09) {
+ dmixml_AddTextContent(data_n, "%s", type[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
+}
+
+void dmi_pointing_device_interface(xmlNode *node, u8 code)
+{
+ /* 3.3.22.2 */
+ static const char *interface[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "Serial",
+ "PS/2",
+ "Infrared",
+ "HIP-HIL",
+ "Bus Mouse",
+ "ADB (Apple Desktop Bus)" /* 0x08 */
+ };
+ static const char *interface_0xA0[] = {
+ "Bus Mouse DB-9", /* 0xA0 */
+ "Bus Mouse Micro DIN",
+ "USB" /* 0xA2 */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "DeviceInterface", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.22.2");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x08) {
+ dmixml_AddTextContent(data_n, interface[code - 0x01]);
+ } else if(code >= 0xA0 && code <= 0xA2) {
+ dmixml_AddTextContent(data_n, interface_0xA0[code - 0xA0]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
}
/*******************************************************************************
** 3.3.23 Portable Battery (Type 22)
*/
-static PyObject *dmi_battery_chemistry(u8 code) {
- /* 3.3.23.1 */
- static const char *chemistry[]={
- "Other", /* 0x01 */
- "Unknown",
- "Lead Acid",
- "Nickel Cadmium",
- "Nickel Metal Hydride",
- "Lithium Ion",
- "Zinc Air",
- "Lithium Polymer" /* 0x08 */
- };
- PyObject *data;
-
- if(code>=0x01 && code<=0x08) data = PyString_FromString(chemistry[code-0x01]);
- data = OUT_OF_SPEC;
- return data;
+void dmi_battery_chemistry(xmlNode *node, u8 code)
+{
+ /* 3.3.23.1 */
+ static const char *chemistry[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "Lead Acid",
+ "Nickel Cadmium",
+ "Nickel Metal Hydride",
+ "Lithium Ion",
+ "Zinc Air",
+ "Lithium Polymer" /* 0x08 */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "BatteryChemistry", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.22.2");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x08) {
+ dmixml_AddTextContent(data_n, "%s", chemistry[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
}
-static PyObject *dmi_battery_capacity(u16 code, u8 multiplier) {
- PyObject *data;
- if(code==0) data = PyString_FromString("Unknown");
- else data = PyString_FromFormat("%i mWh", code*multiplier);
- return data;
+void dmi_battery_capacity(xmlNode *node, u16 code, u8 multiplier)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "DesignCapacity", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "value", "0x%04x", code);
+ dmixml_AddAttribute(data_n, "multiplier", "0x%04x", multiplier);
+
+ if(code != 0) {
+ dmixml_AddAttribute(data_n, "unit", "mWh");
+ dmixml_AddTextContent(data_n, "%i", code * multiplier);
+ }
}
-static PyObject *dmi_battery_voltage(u16 code) {
- PyObject *data;
- if(code==0) data = PyString_FromString("Unknown");
- else data = PyString_FromFormat("%i mV", code);
- return data;
+void dmi_battery_voltage(xmlNode *node, u16 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "DesignVoltage", NULL);
+ assert( data_n != NULL );
+
+ if(code == 0) {
+ dmixml_AddAttribute(data_n, "unknown", "1");
+ } else {
+ dmixml_AddAttribute(data_n, "unit", "mV");
+ dmixml_AddTextContent(data_n, "%i", code);
+ }
}
-static PyObject *dmi_battery_maximum_error(u8 code) {
- PyObject *data;
- if(code==0xFF) data = PyString_FromString("Unknown");
- else data = PyString_FromFormat("%i%%", code);
- return data;
+void dmi_battery_maximum_error(xmlNode *node, u8 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "MaximumError", NULL);
+ assert( data_n != NULL );
+
+ if(code == 0xFF) {
+ dmixml_AddAttribute(data_n, "unknown", "1");
+ } else {
+ dmixml_AddTextContent(data_n, "%i%%", code);
+ }
}
/*******************************************************************************
** 3.3.24 System Reset (Type 23)
*/
-static PyObject *dmi_system_reset_boot_option(u8 code) {
- static const char *option[]={
- "Operating System", /* 0x1 */
- "System Utilities",
- "Do Not Reboot" /* 0x3 */
- };
- PyObject *data;
-
- if(code>=0x1) data = PyString_FromString(option[code-0x1]);
- else data = OUT_OF_SPEC;
- return data;
+void dmi_system_reset_boot_option(xmlNode *node, const char *tagname, u8 code)
+{
+ static const char *option[] = {
+ "Operating System", /* 0x1 */
+ "System Utilities",
+ "Do Not Reboot" /* 0x3 */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if( (code > 0) && (code < 4) ) {
+ dmixml_AddTextContent(data_n, option[code - 0x1]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
}
-static PyObject *dmi_system_reset_count(u16 code) {
- PyObject *data;
- if(code==0xFFFF) data = PyString_FromString("Unknown");
- else data = PyInt_FromLong(code);
- return data;
+void dmi_system_reset_count(xmlNode *node, const char *tagname, u16 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code == 0xFFFF) {
+ dmixml_AddAttribute(data_n, "unknown", "1");
+ } else {
+ dmixml_AddTextContent(data_n, "%ld", code);
+ }
}
-static PyObject *dmi_system_reset_timer(u16 code) {
- PyObject *data;
- if(code==0xFFFF) data = PyString_FromString("Unknown");
- else data = PyString_FromFormat("%i min", code);
- return data;
+void dmi_system_reset_timer(xmlNode *node, const char *tagname, u16 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code == 0xFFFF) {
+ dmixml_AddAttribute(data_n, "unknown", "1");
+ } else {
+ dmixml_AddAttribute(data_n, "unit", "min");
+ dmixml_AddTextContent(data_n, "%i", code);
+ }
}
/*******************************************************************************
* 3.3.25 Hardware Security (Type 24)
*/
-static PyObject *dmi_hardware_security_status(u8 code) {
- static const char *status[]={
- "Disabled", /* 0x00 */
- "Enabled",
- "Not Implemented",
- "Unknown" /* 0x03 */
- };
-
- return PyString_FromString(status[code]);
+void dmi_hardware_security_status(xmlNode *node, const char *tagname, u8 code)
+{
+ static const char *status[] = {
+ "Disabled", /* 0x00 */
+ "Enabled",
+ "Not Implemented",
+ "Unknown" /* 0x03 */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+ dmixml_AddTextContent(data_n, "%s", status[code]);
}
/*******************************************************************************
** 3.3.26 System Power Controls (Type 25)
*/
-static PyObject *dmi_power_controls_power_on(const u8 *p) {
- /* 3.3.26.1 */
- PyObject *data = PyList_New(5);
+#define DMI_POWER_CTRL_TIME_STR(dest, variant, data) \
+ if( variant ) { snprintf(dest, 3, "%02x", data); } \
+ else { snprintf(dest, 3, "*"); } \
- PyList_SET_ITEM(data, 0, dmi_bcd_range(p[0], 0x01, 0x12)?PyString_FromFormat(" %02x", p[0]):PyString_FromString(" *"));
- PyList_SET_ITEM(data, 1, dmi_bcd_range(p[1], 0x01, 0x31)?PyString_FromFormat("-%02x", p[1]):PyString_FromString("-*"));
- PyList_SET_ITEM(data, 2, dmi_bcd_range(p[2], 0x00, 0x23)?PyString_FromFormat(" %02x", p[2]):PyString_FromString(" *"));
- PyList_SET_ITEM(data, 3, dmi_bcd_range(p[3], 0x00, 0x59)?PyString_FromFormat(":%02x", p[3]):PyString_FromString(":*"));
- PyList_SET_ITEM(data, 4, dmi_bcd_range(p[4], 0x00, 0x59)?PyString_FromFormat(":%02x", p[4]):PyString_FromString(":*"));
+void dmi_power_controls_power_on(xmlNode *node, const char *tagname, const u8 * p)
+{
+ /* 3.3.26.1 */
+ char timestr[5][5];
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.26.1");
+ dmixml_AddAttribute(data_n, "flags", "0x%08x", p);
- return data;
+ DMI_POWER_CTRL_TIME_STR(timestr[0], dmi_bcd_range(p[0], 0x01, 0x12), p[0])
+ DMI_POWER_CTRL_TIME_STR(timestr[1], dmi_bcd_range(p[1], 0x01, 0x31), p[1])
+ DMI_POWER_CTRL_TIME_STR(timestr[2], dmi_bcd_range(p[2], 0x01, 0x23), p[2])
+ DMI_POWER_CTRL_TIME_STR(timestr[3], dmi_bcd_range(p[3], 0x01, 0x59), p[3])
+ DMI_POWER_CTRL_TIME_STR(timestr[4], dmi_bcd_range(p[4], 0x01, 0x59), p[4])
+
+ dmixml_AddTextContent(data_n, "%s-%s %s:%s:%s",
+ timestr[0], timestr[1],
+ timestr[2], timestr[3], timestr[4]);
}
/*******************************************************************************
* 3.3.27 Voltage Probe (Type 26)
*/
-static PyObject *dmi_voltage_probe_location(u8 code) {
- /* 3.3.27.1 */
- static const char *location[]={
- "Other", /* 0x01 */
- "Unknown",
- "Processor",
- "Disk",
- "Peripheral Bay",
- "System Management Module",
- "Motherboard",
- "Memory Module",
- "Processor Module",
- "Power Unit",
- "Add-in Card" /* 0x0B */
- };
- PyObject *data;
-
- if(code>=0x01 && code<=0x0B) data = PyString_FromString(location[code-0x01]);
- else data = OUT_OF_SPEC;
- return data;
-}
-
-static PyObject *dmi_probe_status(u8 code) {
- /* 3.3.27.1 */
- static const char *status[]={
- "Other", /* 0x01 */
- "Unknown",
- "OK",
- "Non-critical",
- "Critical",
- "Non-recoverable" /* 0x06 */
- };
- PyObject *data;
-
- if(code>=0x01 && code<=0x06) data = PyString_FromString(status[code-0x01]);
- else data = OUT_OF_SPEC;
- return data;
-}
-
-static PyObject *dmi_voltage_probe_value(u16 code) {
- PyObject *data;
- if(code==0x8000) data = PyString_FromString("Unknown");
- else data = PyString_FromFormat("%.3f V", (float)(i16)code/1000);
- return data;
-}
-
-static PyObject *dmi_voltage_probe_resolution(u16 code) {
- PyObject *data;
- if(code==0x8000) data = PyString_FromString("Unknown");
- else data = PyString_FromFormat("%.1f mV", (float)code/10);
- return data;
-}
-
-static PyObject *dmi_probe_accuracy(u16 code) {
- PyObject *data;
- if(code==0x8000) data = PyString_FromString("Unknown");
- else data = PyString_FromFormat("%.2f%%", (float)code/100);
- return data;
+void dmi_voltage_probe_location(xmlNode *node, u8 code)
+{
+ /* 3.3.27.1 */
+ static const char *location[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "Processor",
+ "Disk",
+ "Peripheral Bay",
+ "System Management Module",
+ "Motherboard",
+ "Memory Module",
+ "Processor Module",
+ "Power Unit",
+ "Add-in Card" /* 0x0B */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Location", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.27.1");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x0B) {
+ dmixml_AddTextContent(data_n, "%s", location[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
+}
+
+void dmi_probe_status(xmlNode *node, u8 code)
+{
+ /* 3.3.27.1 */
+ static const char *status[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "OK",
+ "Non-critical",
+ "Critical",
+ "Non-recoverable" /* 0x06 */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Status", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.27.1");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x06) {
+ dmixml_AddTextContent(data_n, "%s", status[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
+}
+
+void dmi_voltage_probe_value(xmlNode *node, const char *tagname, u16 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code == 0x8000) {
+ dmixml_AddAttribute(data_n, "unknown", "1");
+ } else {
+ dmixml_AddAttribute(data_n, "unit", "V");
+ dmixml_AddTextContent(data_n, "%.3f", (float)(i16) code / 1000);
+ }
+}
+
+void dmi_voltage_probe_resolution(xmlNode *node, u16 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Resolution", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code == 0x8000) {
+ dmixml_AddAttribute(data_n, "unknown", "1");
+ } else {
+ dmixml_AddAttribute(data_n, "unit", "mV");
+ dmixml_AddTextContent(data_n, "%.1f", (float) code / 10);
+ }
+}
+
+void dmi_probe_accuracy(xmlNode *node, u16 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Accuracy", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code == 0x8000) {
+ dmixml_AddAttribute(data_n, "unknown", "1");
+ } else {
+ dmixml_AddAttribute(data_n, "unit", "%%");
+ dmixml_AddTextContent(data_n, "%.2f", (float)code / 100);
+ }
}
/*******************************************************************************
** 3.3.28 Cooling Device (Type 27)
*/
-static PyObject *dmi_cooling_device_type(u8 code) {
- /* 3.3.28.1 */
- static const char *type[]={
- "Other", /* 0x01 */
- "Unknown",
- "Fan",
- "Centrifugal Blower",
- "Chip Fan",
- "Cabinet Fan",
- "Power Supply Fan",
- "Heat Pipe",
- "Integrated Refrigeration" /* 0x09 */
- };
- static const char *type_0x10[]={
- "Active Cooling", /* 0x10, master.mif says 32 */
- "Passive Cooling" /* 0x11, master.mif says 33 */
- };
- PyObject *data;
-
- if(code>=0x01 && code<=0x09) data = PyString_FromString(type[code-0x01]);
- else if(code>=0x10 && code<=0x11) data = PyString_FromString(type_0x10[code-0x10]);
- else data = OUT_OF_SPEC;
- return data;
-}
-
-static PyObject *dmi_cooling_device_speed(u16 code) {
- PyObject *data;
- if(code==0x8000) data = PyString_FromString("Unknown Or Non-rotating");
- else data = PyString_FromFormat("%i rpm", code);
- return data;
+void dmi_cooling_device_type(xmlNode *node, u8 code)
+{
+ /* 3.3.28.1 */
+ static const char *type[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "Fan",
+ "Centrifugal Blower",
+ "Chip Fan",
+ "Cabinet Fan",
+ "Power Supply Fan",
+ "Heat Pipe",
+ "Integrated Refrigeration" /* 0x09 */
+ };
+ static const char *type_0x10[] = {
+ "Active Cooling", /* 0x10, master.mif says 32 */
+ "Passive Cooling" /* 0x11, master.mif says 33 */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Type", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.28.1", code);
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x09) {
+ dmixml_AddTextContent(data_n, "%s", type[code - 0x01]);
+ } else if(code >= 0x10 && code <= 0x11) {
+ dmixml_AddTextContent(data_n, "%s", type_0x10[code - 0x10]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
+}
+
+void dmi_cooling_device_speed(xmlNode *node, u16 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "NominalSpeed", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code == 0x8000) {
+ dmixml_AddAttribute(data_n, "unknown", "1");
+ }
+
+ dmixml_AddAttribute(data_n, "unit", "rpm");
+ dmixml_AddTextContent(data_n, "%i", code);
}
/*******************************************************************************
** 3.3.29 Temperature Probe (Type 28)
*/
-static PyObject *dmi_temperature_probe_location(u8 code) {
- /* 3.3.29.1 */
- static const char *location[]={
- "Other", /* 0x01 */
- "Unknown",
- "Processor",
- "Disk",
- "Peripheral Bay",
- "System Management Module", /* master.mif says SMB Master */
- "Motherboard",
- "Memory Module",
- "Processor Module",
- "Power Unit",
- "Add-in Card",
- "Front Panel Board",
- "Back Panel Board",
- "Power System Board",
- "Drive Back Plane" /* 0x0F */
- };
- PyObject *data;
-
- if(code>=0x01 && code<=0x0F) data = PyString_FromString(location[code-0x01]);
- else data = OUT_OF_SPEC;
- return data;
-}
-
-static PyObject *dmi_temperature_probe_value(u16 code) {
- PyObject *data;
- if(code==0x8000) data = PyString_FromString("Unknown");
- else data = PyString_FromFormat("%.1f deg C", (float)(i16)code/10);
- return data;
-}
-
-static PyObject *dmi_temperature_probe_resolution(u16 code) {
- PyObject *data;
- if(code==0x8000) data = PyString_FromString("Unknown");
- else data = PyString_FromFormat("%.3f deg C", (float)code/1000);
- return data;
+void dmi_temperature_probe_location(xmlNode *node, u8 code)
+{
+ /* 3.3.29.1 */
+ static const char *location[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "Processor",
+ "Disk",
+ "Peripheral Bay",
+ "System Management Module", /* master.mif says SMB Master */
+ "Motherboard",
+ "Memory Module",
+ "Processor Module",
+ "Power Unit",
+ "Add-in Card",
+ "Front Panel Board",
+ "Back Panel Board",
+ "Power System Board",
+ "Drive Back Plane" /* 0x0F */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Location", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.29.1", code);
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x0F) {
+ dmixml_AddTextContent(data_n, "%s", location[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
+}
+
+void dmi_temperature_probe_value(xmlNode *node, const char *tagname, u16 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code == 0x8000) {
+ dmixml_AddAttribute(data_n, "unknown", "1");
+ } else {
+ dmixml_AddAttribute(data_n, "unit", "C");
+ dmixml_AddTextContent(data_n, "%.1f", (float)(i16) code / 10);
+ }
+}
+
+void dmi_temperature_probe_resolution(xmlNode *node, u16 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Resolution", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code == 0x8000) {
+ dmixml_AddAttribute(data_n, "unknown", "1");
+ } else {
+ dmixml_AddAttribute(data_n, "unit", "C");
+ dmixml_AddTextContent(data_n, "%.3f", (float)code / 1000);
+ }
}
/*******************************************************************************
** 3.3.30 Electrical Current Probe (Type 29)
*/
-static PyObject *dmi_current_probe_value(u16 code) {
- PyObject *data;
- if(code==0x8000) data = PyString_FromString("Unknown");
- else data = PyString_FromFormat("%.3f A", (float)(i16)code/1000);
- return data;
+void dmi_current_probe_value(xmlNode *node, const char *tagname, u16 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code == 0x8000) {
+ dmixml_AddAttribute(data_n, "unknown", "1");
+ } else {
+ dmixml_AddAttribute(data_n, "unit", "A");
+ dmixml_AddTextContent(data_n, "%.3f", (float)(i16) code / 1000);
+ }
}
-static PyObject *dmi_current_probe_resolution(u16 code) {
- PyObject *data;
- if(code==0x8000) data = PyString_FromString("Unknown");
- else data = PyString_FromFormat("%.1f mA", (float)code/10);
- return data;
+void dmi_current_probe_resolution(xmlNode *node, u16 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Resolution", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code == 0x8000) {
+ dmixml_AddAttribute(data_n, "unknown", "1");
+ } else {
+ dmixml_AddAttribute(data_n, "unit", "mA");
+ dmixml_AddTextContent(data_n, "%.1f A", (float)code / 10);
+ }
}
/*******************************************************************************
** 3.3.33 System Boot Information (Type 32)
*/
-static PyObject *dmi_system_boot_status(u8 code) {
- static const char *status[]={
- "No errors detected", /* 0 */
- "No bootable media",
- "Operating system failed to load",
- "Firmware-detected hardware failure",
- "Operating system-detected hardware failure",
- "User-requested boot",
- "System security violation",
- "Previously-requested image",
- "System watchdog timer expired" /* 8 */
- };
- PyObject *data;
-
- if(code<=8) data = PyString_FromString(status[code]);
- else if(code>=128 && code<=191) data = PyString_FromString("OEM-specific");
- else if(code>=192) data = PyString_FromString("Product-specific");
- else data = OUT_OF_SPEC;
- return data;
+void dmi_system_boot_status(xmlNode *node, u8 code)
+{
+ static const char *status[] = {
+ "No errors detected", /* 0 */
+ "No bootable media",
+ "Operating system failed to load",
+ "Firmware-detected hardware failure",
+ "Operating system-detected hardware failure",
+ "User-requested boot",
+ "System security violation",
+ "Previously-requested image",
+ "System watchdog timer expired" /* 8 */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Status", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code <= 8) {
+ dmixml_AddTextContent(data_n, "%s", status[code]);
+ } else if(code >= 128 && code <= 191) {
+ dmixml_AddTextContent(data_n, "OEM-specific");
+ } else if(code >= 192) {
+ dmixml_AddTextContent(data_n, "Product-specific");
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
}
/*******************************************************************************
** 3.3.34 64-bit Memory Error Information (Type 33)
*/
-static PyObject *dmi_64bit_memory_error_address(u64 code) {
- PyObject *data;
- if(code.h==0x80000000 && code.l==0x00000000) data = PyString_FromString("Unknown");
- else data = PyString_FromFormat("0x%08x%08x", code.h, code.l);
- return data;
+void dmi_64bit_memory_error_address(xmlNode *node, const char *tagname, u64 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
+ assert( data_n != NULL );
+
+ if(code.h == 0x80000000 && code.l == 0x00000000) {
+ dmixml_AddAttribute(data_n, "unknown", "1");
+ } else {
+ dmixml_AddTextContent(data_n, "0x%08x%08x", code.h, code.l);
+ }
}
/*******************************************************************************
** 3.3.35 Management Device (Type 34)
*/
-static PyObject *dmi_management_device_type(u8 code) {
- /* 3.3.35.1 */
- static const char *type[]={
- "Other", /* 0x01 */
- "Unknown",
- "LM75",
- "LM78",
- "LM79",
- "LM80",
- "LM81",
- "ADM9240",
- "DS1780",
- "MAX1617",
- "GL518SM",
- "W83781D",
- "HT82H791" /* 0x0D */
- };
- PyObject *data;
-
- if(code>=0x01 && code<=0x0D) data = PyString_FromString(type[code-0x01]);
- else data = OUT_OF_SPEC;
- return data;
-}
-
-static PyObject *dmi_management_device_address_type(u8 code) {
- /* 3.3.35.2 */
- static const char *type[]={
- "Other", /* 0x01 */
- "Unknown",
- "I/O Port",
- "Memory",
- "SMBus" /* 0x05 */
- };
- PyObject *data;
-
- if(code>=0x01 && code<=0x05) data = PyString_FromString(type[code-0x01]);
- else data = OUT_OF_SPEC;
- return data;
+void dmi_management_device_type(xmlNode *node, u8 code)
+{
+ /* 3.3.35.1 */
+ static const char *type[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "LM75",
+ "LM78",
+ "LM79",
+ "LM80",
+ "LM81",
+ "ADM9240",
+ "DS1780",
+ "MAX1617",
+ "GL518SM",
+ "W83781D",
+ "HT82H791" /* 0x0D */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Type", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.35.1", code);
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x0D) {
+ dmixml_AddTextContent(data_n, "%s", type[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
+}
+
+void dmi_management_device_address_type(xmlNode *node, u8 code)
+{
+ /* 3.3.35.2 */
+ static const char *type[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "I/O Port",
+ "Memory",
+ "SMBus" /* 0x05 */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "AddressType", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.35.2", code);
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x05) {
+ dmixml_AddTextContent(data_n, "%s", type[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
}
/*******************************************************************************
** 3.3.38 Memory Channel (Type 37)
*/
-static PyObject *dmi_memory_channel_type(u8 code) {
- /* 3.3.38.1 */
- static const char *type[]={
- "Other", /* 0x01 */
- "Unknown",
- "RamBus",
- "SyncLink" /* 0x04 */
- };
- PyObject *data;
-
- if(code>=0x01 && code<=0x04) data = PyString_FromString(type[code-0x01]);
- else data = OUT_OF_SPEC;
- return data;
+void dmi_memory_channel_type(xmlNode *node, u8 code)
+{
+ /* 3.3.38.1 */
+ static const char *type[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "RamBus",
+ "SyncLink" /* 0x04 */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Type", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.38.1", code);
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x04) {
+ dmixml_AddTextContent(data_n, "%s", type[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
}
-static PyObject *dmi_memory_channel_devices(u8 count, const u8 *p) {
- PyObject *data = PyDict_New();
- PyObject *subdata, *val;
- int i;
-
- for(i=1; i<=count; i++) {
- subdata = PyList_New(2);
-
- val = PyString_FromFormat("Load: %i", p[3*i]);
- PyList_SET_ITEM(subdata, 0, val);
- Py_DECREF(val);
+void dmi_memory_channel_devices(xmlNode *node, u8 count, const u8 * p)
+{
+ int i;
- val = PyString_FromFormat("Handle: 0x%04x", WORD(p+3*i+1));
- PyList_SET_ITEM(subdata, 1, val);
- Py_DECREF(val);
+ for(i = 1; i <= count; i++) {
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Device", NULL);
+ assert( data_n != NULL );
- PyDict_SetItem(data, PyInt_FromLong(i), subdata);
- Py_DECREF(subdata);
- }
- return data;
+ dmixml_AddAttribute(data_n, "Load", "%i", p[3 * i]);
+ dmixml_AddAttribute(data_n, "Handle", "0x%04x", WORD(p + 3 * i + 1));
+ }
}
/*******************************************************************************
** 3.3.39 IPMI Device Information (Type 38)
*/
-static PyObject *dmi_ipmi_interface_type(u8 code) {
- /* 3.3.39.1 and IPMI 2.0, appendix C1, table C1-2 */
- static const char *type[]={
- "Unknown", /* 0x00 */
- "KCS (Keyboard Control Style)",
- "SMIC (Server Management Interface Chip)",
- "BT (Block Transfer)",
- "SSIF (SMBus System Interface)" /* 0x04 */
- };
- PyObject *data;
-
- if(code<=0x04) data = PyString_FromString(type[code]);
- else data = OUT_OF_SPEC;
- return data;
-}
-
-static PyObject *dmi_ipmi_base_address(u8 type, const u8 *p, u8 lsb) {
- PyObject *data;
- if(type==0x04) /* SSIF */ {
- data = PyString_FromFormat("0x%02x (SMBus)", (*p)>>1);
- } else {
- u64 address=QWORD(p);
- data = PyString_FromFormat("0x%08x%08x (%s)", address.h, (address.l&~1)|lsb, address.l&1?"I/O":"Memory-mapped");
- }
- return data;
-}
-
-static PyObject *dmi_ipmi_register_spacing(u8 code) {
- /* IPMI 2.0, appendix C1, table C1-1 */
- static const char *spacing[]={
- "Successive Byte Boundaries", /* 0x00 */
- "32-bit Boundaries",
- "16-byte Boundaries" /* 0x02 */
- };
- PyObject *data;
-
- if(code<=0x02) return data = PyString_FromString(spacing[code]);
- return data = OUT_OF_SPEC;
+void dmi_ipmi_interface_type(xmlNode *node, u8 code)
+{
+ /* 3.3.39.1 and IPMI 2.0, appendix C1, table C1-2 */
+ static const char *type[] = {
+ "Unknown", /* 0x00 */
+ "KCS (Keyboard Control Style)",
+ "SMIC (Server Management Interface Chip)",
+ "BT (Block Transfer)",
+ "SSIF (SMBus System Interface)" /* 0x04 */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "InterfaceType", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.39.1", code);
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code <= 0x04) {
+ dmixml_AddTextContent(data_n, "%s", type[code]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
+}
+
+void dmi_ipmi_base_address(xmlNode *node, u8 type, const u8 * p, u8 lsb)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "BaseAddress", NULL);
+ assert( data_n != NULL );
+
+ if(type == 0x04) { /* SSIF */
+ dmixml_AddAttribute(data_n, "interface", "SMBus-SSIF");
+ dmixml_AddTextContent(data_n, "0x%02x", (*p) >> 1);
+ } else {
+ u64 address = QWORD(p);
+ dmixml_AddAttribute(data_n, "interface", "%s",
+ address.l & 1 ? "I/O" : "Memory-mapped");
+ dmixml_AddTextContent(data_n, "0x%08x%08x",
+ address.h, (address.l & ~1) | lsb);
+ }
+}
+
+void dmi_ipmi_register_spacing(xmlNode *node, u8 code)
+{
+ /* IPMI 2.0, appendix C1, table C1-1 */
+ static const char *spacing[] = {
+ "Successive Byte Boundaries", /* 0x00 */
+ "32-bit Boundaries",
+ "16-byte Boundaries" /* 0x02 */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "RegisterSpacing", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code <= 0x02) {
+ dmixml_AddTextContent(data_n, "%s", spacing[code]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
}
/*******************************************************************************
** 3.3.40 System Power Supply (Type 39)
*/
-static PyObject *dmi_power_supply_power(u16 code) {
- PyObject *data;
- if(code==0x8000) data = PyString_FromString("Unknown");
- else data = PyString_FromFormat("%.3f W", (float)code/1000);
- return data;
-}
-
-static PyObject *dmi_power_supply_type(u8 code) {
- /* 3.3.40.1 */
- static const char *type[]={
- "Other", /* 0x01 */
- "Unknown",
- "Linear",
- "Switching",
- "Battery",
- "UPS",
- "Converter",
- "Regulator" /* 0x08 */
- };
- PyObject *data;
-
- if(code>=0x01 && code<=0x08) data = PyString_FromString(type[code-0x01]);
- else data = OUT_OF_SPEC;
- return data;
-}
-
-static PyObject *dmi_power_supply_status(u8 code) {
- /* 3.3.40.1 */
- static const char *status[]={
- "Other", /* 0x01 */
- "Unknown",
- "OK",
- "Non-critical",
- "Critical" /* 0x05 */
- };
- PyObject *data;
-
- if(code>=0x01 && code<=0x05) data = PyString_FromString(status[code-0x01]);
- else data = OUT_OF_SPEC;
- return data;
-}
-
-static PyObject *dmi_power_supply_range_switching(u8 code) {
- /* 3.3.40.1 */
- static const char *switching[]={
- "Other", /* 0x01 */
- "Unknown",
- "Manual",
- "Auto-switch",
- "Wide Range",
- "N/A" /* 0x06 */
- };
- PyObject *data;
-
- if(code>=0x01 && code<=0x06) data = PyString_FromString(switching[code-0x01]);
- else data = OUT_OF_SPEC;
- return data;
+void dmi_power_supply_power(xmlNode *node, u16 code)
+{
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "MaxPowerCapacity", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code == 0x8000) {
+ dmixml_AddAttribute(data_n, "unknown", "1");
+ } else {
+ dmixml_AddAttribute(data_n, "unit", "W");
+ dmixml_AddTextContent(data_n, "%.3f", (float)code / 1000);
+ }
+}
+
+void dmi_power_supply_type(xmlNode *node, u8 code)
+{
+ /* 3.3.40.1 */
+ static const char *type[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "Linear",
+ "Switching",
+ "Battery",
+ "UPS",
+ "Converter",
+ "Regulator" /* 0x08 */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Type", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.40.1");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x08) {
+ dmixml_AddTextContent(data_n, "%s", type[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
+}
+
+void dmi_power_supply_status(xmlNode *node, u8 code)
+{
+ /* 3.3.40.1 */
+ static const char *status[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "OK",
+ "Non-critical",
+ "Critical" /* 0x05 */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Status", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.40.1");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+ dmixml_AddAttribute(data_n, "present", "1");
+
+ if(code >= 0x01 && code <= 0x05) {
+ dmixml_AddTextContent(data_n, "%s", status[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
+}
+
+void dmi_power_supply_range_switching(xmlNode *node, u8 code)
+{
+ /* 3.3.40.1 */
+ static const char *switching[] = {
+ "Other", /* 0x01 */
+ "Unknown",
+ "Manual",
+ "Auto-switch",
+ "Wide Range",
+ "N/A" /* 0x06 */
+ };
+ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "VoltageRangeSwitching", NULL);
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "dmispec", "3.3.40.1");
+ dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
+
+ if(code >= 0x01 && code <= 0x06) {
+ dmixml_AddTextContent(data_n, "%s", switching[code - 0x01]);
+ } else {
+ dmixml_AddAttribute(data_n, "outofspec", "1");
+ }
}
/*
@@ -2803,1971 +3631,1454 @@ static PyObject *dmi_power_supply_range_switching(u8 code) {
** whether it's worth the effort.
*/
-static PyObject *dmi_additional_info(const struct dmi_header *h, const char *prefix) {
- u8 *p = h->data + 4;
- u8 count = *p++;
- u8 length;
- int i, offset = 5;
- PyObject *data = PyList_New(count);
-
- for(i=0; i<count; i++) {
- PyObject *subdata = PyDict_New();
-
- /* Check for short entries */
- if (h->length < offset + 1) break;
- length = p[0x00];
- if (length < 0x05 || h->length < offset + length) break;
-
- PyDict_SetItemString(subdata,
- "Referenced Handle",
- PyString_FromFormat("0x%04x", WORD(p + 0x01))
- );
-
- PyDict_SetItemString(subdata,
- "Referenced Offset",
- PyString_FromFormat("0x%02x", p[0x03])
- );
-
- PyDict_SetItemString(subdata,
- "String",
- dmi_string_py(h, p[0x04])
- );
-
- PyObject *_val;
- switch (length - 0x05) {
- case 1:
- _val = PyString_FromFormat("0x%02x", p[0x05]);
- break;
- case 2:
- _val = PyString_FromFormat("0x%04x", WORD(p + 0x05));
- break;
- case 4:
- _val = PyString_FromFormat("0x%08x", DWORD(p + 0x05));
- break;
- default:
- _val = PyString_FromString("Unexpected size");
- break;
- }
- PyDict_SetItemString(subdata, "Value", _val);
- Py_DECREF(_val);
-
- p += length;
- offset += length;
- PyList_SET_ITEM(data, i, subdata);
- }
- return data;
+void dmi_additional_info(xmlNode *node, const struct dmi_header *h)
+{
+ u8 *p = h->data + 4;
+ u8 count = *p++;
+ u8 length;
+ int i, offset = 5;
+
+ assert( node != NULL );
+
+ for(i = 0; i < count; i++) {
+ xmlNode *data_n = NULL, *str_n = NULL, *val_n = NULL;
+
+ /* Check for short entries */
+ if(h->length < offset + 1) {
+ break;
+ }
+
+ length = p[0x00];
+ if(length < 0x05 || h->length < offset + length)
+ break;
+
+ data_n = xmlNewChild(node, NULL, (xmlChar *) "Record", NULL);
+ assert( data_n != NULL );
+
+ dmixml_AddAttribute(data_n, "index", "%i", i);
+ dmixml_AddAttribute(data_n, "ReferenceHandle", "0x%04x", WORD(p + 0x01));
+ dmixml_AddAttribute(data_n, "ReferenceOffset", "0x%02x", p[0x03]);
+
+ str_n = dmixml_AddTextChild(data_n, "String", "%s", dmi_string(h, p[0x04]));
+
+ switch (length - 0x05) {
+ case 1:
+ dmixml_AddTextChild(data_n, "Value", "0x%02x", p[0x05]);
+ break;
+ case 2:
+ dmixml_AddTextChild(data_n, "Value", "0x%04x", WORD(p + 0x05));
+ break;
+ case 4:
+ dmixml_AddTextChild(data_n, "Value", "0x%08x", DWORD(p + 0x05));
+ break;
+ default:
+ val_n = xmlNewChild(data_n, NULL, (xmlChar *) "Value", NULL);
+ dmixml_AddAttribute(val_n, "unexpected_size", "1");
+ break;
+ }
+
+ p += length;
+ offset += length;
+ }
}
/*******************************************************************************
** Main
*/
-PyObject* dmi_decode(struct dmi_header *h, u16 ver) {
-
- const u8 *data = h->data;
-
- //. 0xF1 --> 0xF100
- //int minor = h->type<<8;
- char _[2048]; bzero(_, 2048);
- //dmi_codes_major *dmiMajor = (dmi_codes_major *)&dmiCodesMajor[map_maj[h->type]];
- dmi_codes_major *dmiMajor = (dmi_codes_major *)&dmiCodesMajor[h->type];
- PyObject *pylist = PyDict_New();
- PyDict_SetItemString(pylist, "id", PyString_FromString(dmiMajor->id));
- PyDict_SetItemString(pylist, "desc", PyString_FromString(dmiMajor->desc));
- PyObject *_val; //. A Temporary pointer (value)
- PyObject *_key; //. Another temporary pointer (key)
- PyObject *caseData = PyDict_New();
-
- switch(h->type) {
-
- case 0: /* 3.3.1 BIOS Information */
-
- if(h->length<0x12) break;
- _val = dmi_string_py(h, data[0x04]);
- PyDict_SetItemString(caseData, "Vendor", _val);
- Py_DECREF(_val);
-
- _val = dmi_string_py(h, data[0x05]);
- PyDict_SetItemString(caseData, "Version", _val);
- Py_DECREF(_val);
-
- _val = dmi_string_py(h, data[0x08]);
- PyDict_SetItemString(caseData, "Release Date", _val);
- Py_DECREF(_val);
-
- /*
- * On IA-64, the BIOS base address will read 0 because
- * there is no BIOS. Skip the base address and the
- * runtime size in this case.
- */
- if(WORD(data+0x06)!=0) {
- _val = PyString_FromFormat("0x%04x0", WORD(data+0x06));
- PyDict_SetItemString(caseData, "Address", _val);
- Py_DECREF(_val);
-
- _val = dmi_bios_runtime_size((0x10000-WORD(data+0x06))<<4);
- PyDict_SetItemString(caseData, "Runtime Size", _val);
- Py_DECREF(_val);
- }
-
- _val = PyString_FromFormat("%i kB", (data[0x09]+1)<<6);
- PyDict_SetItemString(caseData, "ROM Size", _val);
- Py_DECREF(_val);
-
- _val = dmi_bios_characteristics(QWORD(data+0x0A));
- PyDict_SetItemString(caseData, "Characteristics", _val);
- Py_DECREF(_val);
-
- if(h->length<0x13) break;
- _val = dmi_bios_characteristics_x1(data[0x12]);
- PyDict_SetItemString(caseData, "Characteristics x1", _val);
- Py_DECREF(_val);
-
- if(h->length<0x14) break;
- _val = dmi_bios_characteristics_x2(data[0x13]);
- PyDict_SetItemString(caseData, "Characteristics x2", _val);
- Py_DECREF(_val);
-
- if(h->length<0x18) break;
-
- if(data[0x14]!=0xFF && data[0x15]!=0xFF) {
- _val = PyString_FromFormat("%i.%i", data[0x14], data[0x15]);
- PyDict_SetItemString(caseData, "BIOS Revision", _val);
- Py_DECREF(_val);
- }
-
- if(data[0x16]!=0xFF && data[0x17]!=0xFF) {
- _val = PyString_FromFormat("%i.%i", data[0x16], data[0x17]);
- PyDict_SetItemString(caseData, "Firmware Revision", _val);
- Py_DECREF(_val);
- }
-
- break;
-
- case 1: /* 3.3.2 System Information */
-
- if(h->length<0x08) break;
- _val = dmi_string_py(h, data[0x04]);
- PyDict_SetItemString(caseData, "Manufacturer", _val);
- Py_DECREF(_val);
-
- _val = dmi_string_py(h, data[0x05]);
- PyDict_SetItemString(caseData, "Product Name", _val);
- Py_DECREF(_val);
-
- _val = dmi_string_py(h, data[0x06]);
- PyDict_SetItemString(caseData, "Version", _val);
- Py_DECREF(_val);
-
- _val = dmi_string_py(h, data[0x07]);
- PyDict_SetItemString(caseData, "Serial Number", _val);
- Py_DECREF(_val);
-
- if(h->length<0x19) break;
- _val = dmi_system_uuid_py(data+0x08, ver);
- PyDict_SetItemString(caseData, "UUID", _val);
- Py_DECREF(_val);
-
- _val = dmi_system_wake_up_type(data[0x18]);
- PyDict_SetItemString(caseData, "Wake-Up Type", _val);
- Py_DECREF(_val);
-
- if(h->length<0x1B) break;
- _val = dmi_string_py(h, data[0x19]);
- PyDict_SetItemString(caseData, "SKU Number", _val);
- Py_DECREF(_val);
-
- _val = dmi_string_py(h, data[0x1A]);
- PyDict_SetItemString(caseData, "Family", _val);
- Py_DECREF(_val);
- break;
-
- case 2: /* 3.3.3 Base Board Information */
-
- if(h->length<0x08) break;
- _val = dmi_string_py(h, data[0x04]);
- PyDict_SetItemString(caseData, "Manufacturer", _val);
- Py_DECREF(_val);
-
- _val = dmi_string_py(h, data[0x05]);
- PyDict_SetItemString(caseData, "Product Name", _val);
- Py_DECREF(_val);
-
- _val = dmi_string_py(h, data[0x06]);
- PyDict_SetItemString(caseData, "Version", _val);
- Py_DECREF(_val);
-
- _val = dmi_string_py(h, data[0x07]);
- PyDict_SetItemString(caseData, "Serial Number", _val);
- Py_DECREF(_val);
-
- if(h->length<0x0F) break;
- _val = dmi_string_py(h, data[0x08]);
- PyDict_SetItemString(caseData, "Asset Tag", _val);
- Py_DECREF(_val);
-
- _val = dmi_base_board_features(data[0x09]);
- PyDict_SetItemString(caseData, "Features", _val);
- Py_DECREF(_val);
+xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_header * h, u16 ver)
+{
+ const u8 *data = h->data;
+ xmlNode *sect_n = NULL, *sub_n = NULL, *sub2_n = NULL;
+ //. 0xF1 --> 0xF100
+ //int minor = h->type<<8;
+
+ sect_n = xmlNewChild(prnt_n, NULL, (xmlChar *) dmiMajor->tagname, NULL);
+ assert( sect_n != NULL );
+
+ dmixml_AddAttribute(sect_n, "dmispec", "%s", dmiMajor->id);
+ dmixml_AddAttribute(sect_n, "type", "%i", h->type);
+ dmixml_AddTextChild(sect_n, "DMIdescription", "%s", dmiMajor->desc);
+
+ switch (h->type) {
+ case 0: /* 3.3.1 BIOS Information */
+ if(h->length < 0x12) {
+ break;
+ }
+
+ dmixml_AddTextChild(sect_n, "Vendor", "%s", dmi_string(h, data[0x04]));
+ dmixml_AddTextChild(sect_n, "Version", "%s", dmi_string(h, data[0x05]));
+ dmixml_AddTextChild(sect_n, "ReleaseDate", "%s", dmi_string(h, data[0x08]));
- _val = dmi_string_py(h, data[0x0A]);
- PyDict_SetItemString(caseData, "Location In Chassis", _val);
- Py_DECREF(_val);
+ /*
+ * On IA-64, the BIOS base address will read 0 because
+ * there is no BIOS. Skip the base address and the
+ * runtime size in this case.
+ */
- _val = PyString_FromFormat("0x%04x", WORD(data+0x0B));
- PyDict_SetItemString(caseData, "Chassis Handle", _val);
- Py_DECREF(_val);
+ if(WORD(data + 0x06) != 0) {
+ dmixml_AddTextChild(sect_n, "Address", "0x%04x0", WORD(data + 0x06));
+ dmi_bios_runtime_size(sect_n, (0x10000 - WORD(data + 0x06)) << 4);
+ }
- _val = dmi_base_board_type(data[0x0D]);
- PyDict_SetItemString(caseData, "Type", _val);
- Py_DECREF(_val);
+ sub_n = dmixml_AddTextChild(sect_n, "ROMsize", "%i", (data[0x09] + 1) << 6);
+ dmixml_AddAttribute(sub_n, "unit", "KB");
+ sub_n = NULL;
- if(h->length<0x0F+data[0x0E]*sizeof(u16)) break;
- _val = dmi_base_board_handles(data[0x0E], data+0x0F);
- PyDict_SetItemString(caseData, "Type ???", _val);
- Py_DECREF(_val);
- break;
+ sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Characteristics", NULL);
+ assert( sub_n != NULL );
- case 3: /* 3.3.4 Chassis Information */
+ dmixml_AddAttribute(sub_n, "level", "0");
+ dmi_bios_characteristics(sub_n, QWORD(data + 0x0A));
+ sub_n = NULL;
- if(h->length<0x09) break;
- _val = dmi_string_py(h, data[0x04]);
- PyDict_SetItemString(caseData, "Manufacturer", _val);
- Py_DECREF(_val);
+ if(h->length < 0x13) {
+ break;
+ }
- _val = dmi_chassis_type_py(data[0x05]&0x7F);
- PyDict_SetItemString(caseData, "Type", _val);
- Py_DECREF(_val);
+ sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Characteristics", NULL);
+ assert( sub_n != NULL );
- _val = dmi_chassis_lock(data[0x05]>>7);
- PyDict_SetItemString(caseData, "Lock", _val);
- Py_DECREF(_val);
-
- _val = dmi_string_py(h, data[0x06]);
- PyDict_SetItemString(caseData, "Version", _val);
- Py_DECREF(_val);
-
- _val = dmi_string_py(h, data[0x07]);
- PyDict_SetItemString(caseData, "Serial Number", _val);
- Py_DECREF(_val);
-
- _val = dmi_string_py(h, data[0x08]);
- PyDict_SetItemString(caseData, "Asset Tag", _val);
- Py_DECREF(_val);
-
- if(h->length<0x0D) break;
- _val = dmi_chassis_state(data[0x09]);
- PyDict_SetItemString(caseData, "Boot-Up State", _val);
- Py_DECREF(_val);
-
- _val = dmi_chassis_state(data[0x0A]);
- PyDict_SetItemString(caseData, "Power Supply State", _val);
- Py_DECREF(_val);
-
- _val = dmi_chassis_state(data[0x0B]);
- PyDict_SetItemString(caseData, "Thermal State", _val);
- Py_DECREF(_val);
-
- _val = PyString_FromString(dmi_chassis_security_status(data[0x0C]));
- PyDict_SetItemString(caseData, "Security Status", _val);
- Py_DECREF(_val);
-
- if(h->length<0x11) break;
- _val = PyString_FromFormat("0x%08x", DWORD(data+0x0D));
- PyDict_SetItemString(caseData, "OEM Information", _val);
- Py_DECREF(_val);
-
- if(h->length<0x13) break;
- _val = dmi_chassis_height(data[0x11]);
- PyDict_SetItemString(caseData, "Height", _val);
- Py_DECREF(_val);
-
- _val = dmi_chassis_power_cords(data[0x12]);
- PyDict_SetItemString(caseData, "Number Of Power Cords", _val);
- Py_DECREF(_val);
-
- if(h->length < 0x15) break;
- if(h->length<0x15+data[0x13]*data[0x14]) break;
- _val = dmi_chassis_elements(data[0x13], data[0x14], data+0x15);
- PyDict_SetItemString(caseData, "Elements", _val);
- Py_DECREF(_val);
-
- break;
-
-
- case 4: /* 3.3.5 Processor Information */
-
- if(h->length<0x1A) break;
-
- _val = dmi_string_py(h, data[0x04]);
- PyDict_SetItemString(caseData, "Socket Designation", _val);
- Py_DECREF(_val);
-
- _val = dmi_processor_type(data[0x05]);
- PyDict_SetItemString(caseData, "Type", _val);
- Py_DECREF(_val);
-
- _val = PyString_FromString(dmi_processor_family(h));
- PyDict_SetItemString(caseData, "Family", _val);
- Py_DECREF(_val);
-
- _val = dmi_processor_id(data[0x06], data+8, dmi_string(h, data[0x10]));
- PyDict_SetItemString(_val, "Vendor", dmi_string_py(h, data[0x07]));
- PyDict_SetItemString(caseData, "Manufacturer", _val);
- Py_DECREF(_val);
-
- _val = dmi_string_py(h, data[0x10]);
- PyDict_SetItemString(caseData, "Version", _val);
- Py_DECREF(_val);
-
- _val = dmi_processor_voltage(data[0x11]);
- PyDict_SetItemString(caseData, "Voltage", _val);
- Py_DECREF(_val);
-
- _val = dmi_processor_frequency_py(data+0x12);
- PyDict_SetItemString(caseData, "External Clock", _val);
- Py_DECREF(_val);
-
- _val = dmi_processor_frequency_py(data+0x14);
- PyDict_SetItemString(caseData, "Max Speed", _val);
- Py_DECREF(_val);
-
- _val = dmi_processor_frequency_py(data+0x16);
- PyDict_SetItemString(caseData, "Current Speed", _val);
- Py_DECREF(_val);
-
- if(data[0x18]&(1<<6)) {
- _val = PyString_FromFormat("Populated:%s", dmi_processor_status(data[0x18]&0x07));
- PyDict_SetItemString(caseData, "Status", _val);
- Py_DECREF(_val);
- } else {
- _val = PyString_FromString("Populated:No");
- PyDict_SetItemString(caseData, "Status", _val);
- Py_DECREF(_val);
- }
- _val = dmi_processor_upgrade(data[0x19]);
- PyDict_SetItemString(caseData, "Upgrade", _val);
- Py_DECREF(_val);
-
- if(h->length<0x20) break;
- _val = dmi_processor_cache(WORD(data+0x1A), "L1", ver);
- PyDict_SetItemString(caseData, "L1 Cache Handle", _val);
- Py_DECREF(_val);
-
- _val = dmi_processor_cache(WORD(data+0x1C), "L2", ver);
- PyDict_SetItemString(caseData, "L2 Cache Handle", _val);
- Py_DECREF(_val);
-
- _val = dmi_processor_cache(WORD(data+0x1E), "L3", ver);
- PyDict_SetItemString(caseData, "L3 Cache Handle", _val);
- Py_DECREF(_val);
-
- if(h->length<0x23) break;
- _val = dmi_string_py(h, data[0x20]);
- PyDict_SetItemString(caseData, "Serial Number", _val);
- Py_DECREF(_val);
-
- _val = dmi_string_py(h, data[0x21]);
- PyDict_SetItemString(caseData, "Asset Tag", _val);
- Py_DECREF(_val);
-
- _val = dmi_string_py(h, data[0x22]);
- PyDict_SetItemString(caseData, "Part Number", _val);
- Py_DECREF(_val);
-
- if(h->length<0x28) break;
- if(data[0x23]!=0) {
- _val = PyString_FromFormat("%i", data[0x23]);
- PyDict_SetItemString(caseData, "Core Count", _val);
- Py_DECREF(_val);
- }
-
- if(data[0x24]!=0) {
- _val = PyString_FromFormat("%i", data[0x24]);
- PyDict_SetItemString(caseData, "Core Enabled", _val);
- Py_DECREF(_val);
- }
-
- if(data[0x25]!=0) {
- _val = PyString_FromFormat("%i", data[0x25]);
- PyDict_SetItemString(caseData, "Thread Count", _val);
- Py_DECREF(_val);
- }
-
- _val = dmi_processor_characteristics(WORD(data+0x26));
- PyDict_SetItemString(caseData, "Characteristics", _val);
- Py_DECREF(_val);
- break;
-
- case 5: /* 3.3.6 Memory Controller Information */
-
- if(h->length<0x0F) break;
- _val = dmi_memory_controller_ed_method(data[0x04]);
- PyDict_SetItemString(caseData, "Error Detecting Method", _val);
- Py_DECREF(_val);
-
- _val = dmi_memory_controller_ec_capabilities(data[0x05]);
- PyDict_SetItemString(caseData, "Error Correcting Capabilities", _val);
- Py_DECREF(_val);
-
- _val = dmi_memory_controller_interleave(data[0x06]);
- PyDict_SetItemString(caseData, "Supported Interleave", _val);
- Py_DECREF(_val);
-
- _val = dmi_memory_controller_interleave(data[0x07]);
- PyDict_SetItemString(caseData, "Current Interleave", _val);
- Py_DECREF(_val);
-
- _val = PyString_FromFormat("%i MB", 1<<data[0x08]);
- PyDict_SetItemString(caseData, "Maximum Memory Module Size", _val);
- Py_DECREF(_val);
-
- _val = PyString_FromFormat("%i MB", data[0x0E]*(1<<data[0x08]));
- PyDict_SetItemString(caseData, "Maximum Total Memory Size", _val);
- Py_DECREF(_val);
-
- _val = dmi_memory_controller_speeds(WORD(data+0x09));
- PyDict_SetItemString(caseData, "Supported Speeds", _val);
- Py_DECREF(_val);
-
- _val = dmi_memory_module_types(WORD(data+0x0B));
- PyDict_SetItemString(caseData, "Supported Memory Types", _val);
- Py_DECREF(_val);
-
- _val = dmi_processor_voltage(data[0x0D]);
- PyDict_SetItemString(caseData, "Memory Module Voltage", _val);
- Py_DECREF(_val);
-
- if(h->length<0x0F+data[0x0E]*sizeof(u16)) break;
- _val = dmi_memory_controller_slots(data[0x0E], data+0x0F);
- PyDict_SetItemString(caseData, "Associated Memory Sluts", _val);
- Py_DECREF(_val);
-
- if(h->length<0x10+data[0x0E]*sizeof(u16)) break;
- _val = dmi_memory_controller_ec_capabilities(data[0x0F+data[0x0E]*sizeof(u16)]);
- PyDict_SetItemString(caseData, "Enabled Error Correcting Capabilities", _val);
- Py_DECREF(_val);
- break;
-
- case 6: /* 3.3.7 Memory Module Information */
-
- if(h->length<0x0C) break;
- _val = dmi_string_py(h, data[0x04]);
- PyDict_SetItemString(caseData, "Socket Designation", _val);
- Py_DECREF(_val);
-
- _val = dmi_memory_module_connections(data[0x05]);
- PyDict_SetItemString(caseData, "Bank Connections", _val);
- Py_DECREF(_val);
-
- _val = dmi_memory_module_speed(data[0x06]);
- PyDict_SetItemString(caseData, "Current Speed", _val);
- Py_DECREF(_val);
-
- _val = dmi_memory_module_types(WORD(data+0x07));
- PyDict_SetItemString(caseData, "Type", _val);
- Py_DECREF(_val);
-
- _val = dmi_memory_module_size(data[0x09]);
- PyDict_SetItemString(caseData, "Installed Size", _val);
- Py_DECREF(_val);
-
- _val = dmi_memory_module_size(data[0x0A]);
- PyDict_SetItemString(caseData, "Enabled Size", _val);
- Py_DECREF(_val);
-
- _val = dmi_memory_module_error(data[0x0B]);
- PyDict_SetItemString(caseData, "Error Status", _val);
- Py_DECREF(_val);
- break;
-
- case 7: /* 3.3.8 Cache Information */
-
- if(h->length<0x0F) break;
- _val = dmi_string_py(h, data[0x04]);
- PyDict_SetItemString(caseData, "Socket Designation", _val);
- Py_DECREF(_val);
-
- _val = PyDict_New();
- PyDict_SetItemString(_val, "Enabled", WORD(data+0x05)&0x0080?Py_True:Py_False);
- PyDict_SetItemString(_val, "Socketed", WORD(data+0x05)&0x0008?Py_True:Py_False);
- PyDict_SetItemString(_val, "Level", PyInt_FromLong((WORD(data+0x05)&0x0007)+1));
- PyDict_SetItemString(caseData, "Configuration" , _val);
- Py_DECREF(_val);
-
- _val = dmi_cache_mode((WORD(data+0x05)>>8)&0x0003);
- PyDict_SetItemString(caseData, "Operational Mode", _val);
- Py_DECREF(_val);
+ dmixml_AddAttribute(sub_n, "level", "x1");
+ dmi_bios_characteristics_x1(sub_n, data[0x12]);
+ sub_n = NULL;
- _val = dmi_cache_location((WORD(data+0x05)>>5)&0x0003);
- PyDict_SetItemString(caseData, "Location", _val);
- Py_DECREF(_val);
+ if(h->length < 0x14) {
+ break;
+ }
- _val = dmi_cache_size(WORD(data+0x09));
- PyDict_SetItemString(caseData, "Installed Size", _val);
- Py_DECREF(_val);
+ sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Characteristics", NULL);
+ assert( sub_n != NULL );
- _val = dmi_cache_size(WORD(data+0x07));
- PyDict_SetItemString(caseData, "Maximum Size", _val);
- Py_DECREF(_val);
+ dmixml_AddAttribute(sub_n, "level", "x2");
+ dmi_bios_characteristics_x2(sub_n, data[0x13]);
+ sub_n = NULL;
- _val = dmi_cache_types(WORD(data+0x0B));
- PyDict_SetItemString(caseData, "Supported SRAM Types", _val);
- Py_DECREF(_val);
+ if(h->length < 0x18) {
+ break;
+ }
- _val = dmi_cache_types(WORD(data+0x0D));
- PyDict_SetItemString(caseData, "Installed SRAM Type", _val);
- Py_DECREF(_val);
+ if(data[0x14] != 0xFF && data[0x15] != 0xFF) {
+ dmixml_AddTextChild(sect_n, "BIOSrevision", "%i.%i", data[0x14], data[0x15]);
+ }
- if(h->length<0x13) break;
- _val = dmi_memory_module_speed(data[0x0F]);
- PyDict_SetItemString(caseData, "Speed", _val);
- Py_DECREF(_val);
+ if(data[0x16] != 0xFF && data[0x17] != 0xFF) {
+ dmixml_AddTextChild(sect_n, "FirmwareRevision", "%i.%i", data[0x16], data[0x17]);
+ }
+ break;
- _val = dmi_cache_ec_type(data[0x10]);
- PyDict_SetItemString(caseData, "Error Correction Type", _val);
- Py_DECREF(_val);
+ case 1: /* 3.3.2 System Information */
+ if(h->length < 0x08) {
+ break;
+ }
- _val = dmi_cache_type(data[0x11]);
- PyDict_SetItemString(caseData, "System Type", _val);
- Py_DECREF(_val);
+ dmixml_AddTextChild(sect_n, "Manufacturer", "%s", dmi_string(h, data[0x04]));
+ dmixml_AddTextChild(sect_n, "ProductName", "%s", dmi_string(h, data[0x05]));
+ dmixml_AddTextChild(sect_n, "Version", "%s", dmi_string(h, data[0x06]));
+ dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x07]));
- _val = dmi_cache_associativity(data[0x12]);
- PyDict_SetItemString(caseData, "Associativity", _val);
- Py_DECREF(_val);
+ if(h->length < 0x19) {
+ break;
+ }
- break;
+ dmi_system_uuid(sect_n, data + 0x08, ver);
- case 8: /* 3.3.9 Port Connector Information */
+ dmi_system_wake_up_type(sect_n, data[0x18]);
- if(h->length<0x09) break;
- _val = dmi_string_py(h, data[0x04]);
- PyDict_SetItemString(caseData, "Internal Reference Designator", _val);
- Py_DECREF(_val);
+ if(h->length < 0x1B) {
+ break;
+ }
- _val = dmi_port_connector_type(data[0x05]);
- PyDict_SetItemString(caseData, "Internal Connector Type", _val);
- Py_DECREF(_val);
+ dmixml_AddTextChild(sect_n, "SKUnumber", "%s", dmi_string(h, data[0x19]));
+ dmixml_AddTextChild(sect_n, "Family", "%s", dmi_string(h, data[0x1A]));
+ break;
- _val = dmi_string_py(h, data[0x06]);
- PyDict_SetItemString(caseData, "External Reference Designator", _val);
- Py_DECREF(_val);
+ case 2: /* 3.3.3 Base Board Information */
+ if(h->length < 0x08) {
+ break;
+ }
- _val = dmi_port_connector_type(data[0x07]);
- PyDict_SetItemString(caseData, "External Connector Type", _val);
- Py_DECREF(_val);
+ dmixml_AddTextChild(sect_n, "Manufacturer", "%s", dmi_string(h, data[0x04]));
+ dmixml_AddTextChild(sect_n, "ProductName", "%s", dmi_string(h, data[0x05]));
+ dmixml_AddTextChild(sect_n, "Version", "%s", dmi_string(h, data[0x06]));
+ dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x07]));
- _val = dmi_port_type(data[0x08]);
- PyDict_SetItemString(caseData, "Port Type", _val);
- Py_DECREF(_val);
+ if(h->length < 0x0F) {
+ break;
+ }
- break;
+ dmixml_AddTextChild(sect_n, "AssetTag", "%s", dmi_string(h, data[0x08]));
- case 9: /* 3.3.10 System Slots */
+ dmi_base_board_features(sect_n, data[0x09]);
- if(h->length<0x0C) break;
- _val = dmi_string_py(h, data[0x04]);
- PyDict_SetItemString(caseData, "Designation", _val);
- Py_DECREF(_val);
+ dmixml_AddTextChild(sect_n, "ChassisLocation", "%s", dmi_string(h, data[0x0A]));
+ dmixml_AddTextChild(sect_n, "ChassisHandle", "0x%04x", WORD(data + 0x0B));
- _val = dmi_slot_bus_width(data[0x06]);
- PyDict_SetItemString(caseData, "Type:SlotBusWidth", _val);
- Py_DECREF(_val);
- _val = dmi_slot_type(data[0x05]);
- PyDict_SetItemString(caseData, "Type:SlotType", _val);
- Py_DECREF(_val);
+ dmi_base_board_type(sect_n, "Type", data[0x0D]);
- _val = dmi_slot_current_usage(data[0x07]);
- PyDict_SetItemString(caseData, "Current Usage", _val);
- Py_DECREF(_val);
+ if(h->length < 0x0F + data[0x0E] * sizeof(u16)) {
+ break;
+ }
- _val = dmi_slot_length(data[0x08]);
- PyDict_SetItemString(caseData, "SlotLength", _val);
- Py_DECREF(_val);
- _val = dmi_slot_id(data[0x09], data[0x0A], data[0x05]);
- PyDict_SetItemString(caseData, "SlotId", _val);
- Py_DECREF(_val);
+ dmi_base_board_handles(sect_n, data[0x0E], data + 0x0F);
+ break;
- _val = (h->length<0x0D)?dmi_slot_characteristics(data[0x0B], 0x00):dmi_slot_characteristics(data[0x0B], data[0x0C]);
- PyDict_SetItemString(caseData, "Characteristics", _val);
- Py_DECREF(_val);
- break;
+ case 3: /* 3.3.4 Chassis Information */
+ if(h->length < 0x09) {
+ break;
+ }
- case 10: /* 3.3.11 On Board Devices Information */
+ dmixml_AddTextChild(sect_n, "Manufacturer", "%s", dmi_string(h, data[0x04]));
+ dmi_chassis_type(sect_n, data[0x05] & 0x7F);
+ dmi_chassis_lock(sect_n, data[0x05] >> 7);
+ dmixml_AddTextChild(sect_n, "Version", "%s", dmi_string(h, data[0x06]));
+ dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x07]));
+ dmixml_AddTextChild(sect_n, "AssetTag", "%s", dmi_string(h, data[0x08]));
- PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h));
+ if(h->length < 0x0D) {
+ break;
+ }
- break;
+ sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "ChassisStates", NULL);
+ assert( sub_n != NULL );
- case 11: /* 3.3.12 OEM Strings */
+ dmi_chassis_state(sub_n, "BootUp", data[0x09]);
+ dmi_chassis_state(sub_n, "PowerSupply", data[0x0A]);
+ dmi_chassis_state(sub_n, "Thermal", data[0x0B]);
+ sub_n = NULL;
- if(h->length<0x05) break;
- _val = dmi_oem_strings(h);
- PyDict_SetItemString(caseData, "Strings", _val);
- Py_DECREF(_val);
+ dmi_chassis_security_status(sect_n, data[0x0C]);
- break;
+ if(h->length < 0x11) {
+ break;
+ }
- case 12: /* 3.3.13 System Configuration Options */
+ dmixml_AddTextChild(sect_n, "OEMinformation", "0x%08x", DWORD(data + 0x0D));
- if(h->length<0x05) break;
- _val = dmi_system_configuration_options(h);
- PyDict_SetItemString(caseData, "Options", _val);
- Py_DECREF(_val);
+ if(h->length < 0x13) {
+ break;
+ }
- break;
+ dmi_chassis_height(sect_n, data[0x11]);
+ dmi_chassis_power_cords(sect_n, data[0x12]);
- case 13: /* 3.3.14 BIOS Language Information */
+ if((h->length < 0x15) || (h->length < 0x15 + data[0x13] * data[0x14])){
+ break;
+ }
- if(h->length<0x16) break;
- _val = PyString_FromFormat("%i", data[0x04]);
- PyDict_SetItemString(caseData, "Installable Languages", _val);
- Py_DECREF(_val);
+ dmi_chassis_elements(sect_n, data[0x13], data[0x14], data + 0x15);
+ break;
- _val = dmi_bios_languages(h);
- PyList_SET_ITEM(_val, 0, dmi_string_py(h, data[0x15]));
- PyDict_SetItemString(caseData, "Currently Installed Language", _val);
- Py_DECREF(_val);
+ case 4: /* 3.3.5 Processor Information */
+ if(h->length < 0x1A) {
+ break;
+ }
- break;
+ dmixml_AddTextChild(sect_n, "SocketDesignation", "%s", dmi_string(h, data[0x04]));
+ dmi_processor_type(sect_n, data[0x05]);
+ dmi_processor_family(sect_n, h);
- case 14: /* 3.3.15 Group Associations */
+ dmi_processor_id(sect_n, data[0x06], data + 8, dmi_string(h, data[0x10]));
- if(h->length<0x05) break;
- _val = dmi_string_py(h, data[0x04]);
- PyDict_SetItemString(caseData, "Name", _val);
- Py_DECREF(_val);
+ sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Manufacturer", NULL);
+ assert( sub_n != NULL );
+ dmixml_AddTextChild(sub_n, "Vendor", dmi_string(h, data[0x07]));
- _val = PyString_FromFormat("%i", (h->length-0x05)/3);
- PyDict_SetItemString(caseData, "Items", _val);
- Py_DECREF(_val);
+ dmixml_AddTextChild(sub_n, "Version", dmi_string(h, data[0x10]));
+ sub_n = NULL;
- _val = dmi_group_associations_items((h->length-0x05)/3, data+0x05);
- PyDict_SetItemString(caseData, "Items2", _val); //. FIXME: Title
- Py_DECREF(_val);
- break;
+ dmi_processor_voltage(sect_n, data[0x11]);
- case 15: /* 3.3.16 System Event Log */
+ sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Frequencies", NULL);
+ assert( sub_n != NULL );
- if(h->length<0x14) break;
- _val = PyString_FromFormat("%i bytes", WORD(data+0x04));
- PyDict_SetItemString(caseData, "Area Length", _val);
- Py_DECREF(_val);
+ dmixml_AddTextChild(sub_n, "ExternalClock", "%i", dmi_processor_frequency(data + 0x12));
+ dmixml_AddTextChild(sub_n, "MaxSpeed", "%i", dmi_processor_frequency(data + 0x14));
+ dmixml_AddTextChild(sub_n, "CurrentSpeed", "%i", dmi_processor_frequency(data + 0x16));
+ sub_n = NULL;
- _val = PyString_FromFormat("0x%04x", WORD(data+0x06));
- PyDict_SetItemString(caseData, "Header Start Offset", _val);
- Py_DECREF(_val);
+ /* TODO: Should CurrentSpeed be renamed to BootSpeed? Specification
+ * says this about Current Speed:
+ *
+ * This field identifies the processor's speed at
+ * system boot and the Processor ID field implies the
+ * processor's additional speed characteristics (i.e. single
+ * speed or multiple speed).
+ */
- if(WORD(data+0x08)-WORD(data+0x06)) {
- _val = PyString_FromFormat("%i byte%s", WORD(data+0x08)-WORD(data+0x06), WORD(data+0x08)-WORD(data+0x06)>1?"s":"");
- PyDict_SetItemString(caseData, "Header Length", _val);
- Py_DECREF(_val);
- }
+ if(data[0x18] & (1 << 6)) {
+ dmixml_AddAttribute(sect_n, "populated", "1");
+ dmi_processor_status(sect_n, data[0x18] & 0x07);
+ } else {
+ dmixml_AddAttribute(sect_n, "populated", "0");
+ dmixml_AddTextChild(sect_n, "Populated", "No");
+ }
- _val = PyString_FromFormat("0x%04x", WORD(data+0x08));
- PyDict_SetItemString(caseData, "Data Start Offset", _val);
- Py_DECREF(_val);
+ dmi_processor_upgrade(sect_n, data[0x19]);
- _val = PyString_FromFormat("%s", dmi_event_log_method(data[0x0A]));
- PyDict_SetItemString(caseData, "Access Method", _val);
- Py_DECREF(_val);
+ if(h->length < 0x20) {
+ break;
+ }
- _val = dmi_event_log_address_py(data[0x0A], data+0x10);
- PyDict_SetItemString(caseData, "Access Address", _val);
- Py_DECREF(_val);
+ sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Cache", NULL);
+ assert( sub_n != NULL );
- _val = dmi_event_log_status_py(data[0x0B]);
- PyDict_SetItemString(caseData, "Status", _val);
- Py_DECREF(_val);
+ sub2_n = xmlNewChild(sub_n, NULL, (xmlChar *) "Level", NULL);
+ assert( sub2_n != NULL );
- _val = PyString_FromFormat("0x%08x", DWORD(data+0x0C));
- PyDict_SetItemString(caseData, "Change Token", _val);
- Py_DECREF(_val);
+ dmixml_AddAttribute(sub2_n, "level", "1");
+ dmi_processor_cache(sub2_n, WORD(data + 0x1A), ver);
+ sub2_n = NULL;
- if(h->length<0x17) break;
- _val = PyString_FromFormat("%s", dmi_event_log_header_type(data[0x14]));
- PyDict_SetItemString(caseData, "Header Format", _val);
- Py_DECREF(_val);
- _val = PyString_FromFormat("%i", data[0x15]);
- PyDict_SetItemString(caseData, "Supported Log Type Descriptors", _val);
- Py_DECREF(_val);
+ sub2_n = xmlNewChild(sub_n, NULL, (xmlChar *) "Level", NULL);
+ assert( sub2_n != NULL );
- if(h->length<0x17+data[0x15]*data[0x16]) break;
- _val = dmi_event_log_descriptors(data[0x15], data[0x16], data+0x17);
- PyDict_SetItemString(caseData, "DMI Event Log Descriptors", _val);
- Py_DECREF(_val);
+ dmixml_AddAttribute(sub2_n, "level", "2");
+ dmi_processor_cache(sub2_n, WORD(data + 0x1C), ver);
+ sub2_n = NULL;
- break;
+ sub2_n = xmlNewChild(sub_n, NULL, (xmlChar *) "Level", NULL);
+ assert( sub2_n != NULL );
- case 16: /* 3.3.17 Physical Memory Array */
+ dmixml_AddAttribute(sub2_n, "level", "3");
+ dmi_processor_cache(sub2_n, WORD(data + 0x1E), ver);
+ sub2_n = NULL;
+ sub_n = NULL;
- if(h->length<0x0F) break;
- _val = dmi_memory_array_location(data[0x04]);
- PyDict_SetItemString(caseData, "Location", _val);
- Py_DECREF(_val);
+ if(h->length < 0x23) {
+ break;
+ }
- _val = dmi_memory_array_use(data[0x05]);
- PyDict_SetItemString(caseData, "Use", _val);
- Py_DECREF(_val);
+ dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x20]));
+ dmixml_AddTextChild(sect_n, "AssetTag", "%s", dmi_string(h, data[0x21]));
+ dmixml_AddTextChild(sect_n, "PartNumber", "%s", dmi_string(h, data[0x22]));
- _val = dmi_memory_array_ec_type(data[0x06]);
- PyDict_SetItemString(caseData, "Error Correction Type", _val);
- Py_DECREF(_val);
+ if(h->length < 0x28) {
+ break;
+ }
- _val = dmi_memory_array_capacity(DWORD(data+0x07));
- PyDict_SetItemString(caseData, "Maximum Capacity", _val);
- Py_DECREF(_val);
+ sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Cores", NULL);
+ assert( sub_n != NULL );
- _val = dmi_memory_array_error_handle(WORD(data+0x0B));
- PyDict_SetItemString(caseData, "Error Information Handle", _val);
- Py_DECREF(_val);
+ if(data[0x23] != 0) {
+ dmixml_AddTextChild(sub_n, "CoreCount", "%i", data[0x23]);
+ }
- _val = PyInt_FromLong(WORD(data+0x0D));
- PyDict_SetItemString(caseData, "Number Of Devices", _val);
- Py_DECREF(_val);
- break;
+ if(data[0x24] != 0) {
+ dmixml_AddTextChild(sub_n, "CoresEnabled", "%i", data[0x24]);
+ }
+ if(data[0x25] != 0) {
+ dmixml_AddTextChild(sub_n, "ThreadCount", "%i", data[0x25]);
+ }
- case 17: /* 3.3.18 Memory Device */
+ dmi_processor_characteristics(sub_n, WORD(data + 0x26));
+ sub_n = NULL;
+ break;
- if(h->length<0x15) break;
- _val = PyString_FromFormat("0x%04x", WORD(data+0x04));
- PyDict_SetItemString(caseData, "Array Handle", _val);
- Py_DECREF(_val);
+ case 5: /* 3.3.6 Memory Controller Information */
+ if(h->length < 0x0F) {
+ break;
+ }
+
+ sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "ErrorCorrection", NULL);
+ assert( sub_n != NULL );
+
+ dmi_memory_controller_ed_method(sub_n, data[0x04]);
+ dmi_memory_controller_ec_capabilities(sub_n, "Capabilities", data[0x05]);
+ sub_n = NULL;
+
+ dmi_memory_controller_interleave(sect_n, "SupportedInterleave", data[0x06]);
+ dmi_memory_controller_interleave(sect_n, "CurrentInterleave", data[0x07]);
+
+ sub_n = dmixml_AddTextChild(sect_n, "MaxMemoryModuleSize",
+ "%i", (1 << data[0x08]));
+ dmixml_AddAttribute(sub_n, "unit", "MB");
+ sub_n = NULL;
+
+ sub_n = dmixml_AddTextChild(sect_n, "MaxTotalMemorySize",
+ "%i", data[0x0E] * (1 << data[0x08]));
+ dmixml_AddAttribute(sub_n, "unit", "MB");
+ sub_n = NULL;
+
+ dmi_memory_controller_speeds(sect_n, WORD(data + 0x09));
+ dmi_memory_module_types(sect_n, "SupportedTypes", WORD(data + 0x0B));
+ dmi_processor_voltage(sect_n, data[0x0D]);
+
+ if(h->length < 0x0F + data[0x0E] * sizeof(u16)) {
+ break;
+ }
+
+ dmi_memory_controller_slots(sect_n, data[0x0E], data + 0x0F);
- _val = dmi_memory_array_error_handle(WORD(data+0x06));
- PyDict_SetItemString(caseData, "Error Information Handle", _val);
- Py_DECREF(_val);
+ if(h->length < 0x10 + data[0x0E] * sizeof(u16)) {
+ break;
+ }
+
+ dmi_memory_controller_ec_capabilities(sect_n, "EnabledErrorCorrection",
+ data[0x0F + data[0x0E] * sizeof(u16)]);
+ break;
- _val = dmi_memory_device_width(WORD(data+0x08));
- PyDict_SetItemString(caseData, "Total Width", _val);
- Py_DECREF(_val);
+ case 6: /* 3.3.7 Memory Module Information */
+ if(h->length < 0x0C) {
+ break;
+ }
+
+ dmixml_AddTextChild(sect_n, "SocketDesignation", "%s", dmi_string(h, data[0x04]));
+ dmi_memory_module_connections(sect_n, data[0x05]);
+ dmi_memory_module_speed(sect_n, "ModuleSpeed", data[0x06]);
+ dmi_memory_module_types(sect_n, "Type", WORD(data + 0x07));
+
+ dmi_memory_module_size(sect_n, "InstalledSize", data[0x09]);
+ dmi_memory_module_size(sect_n, "EnabledSize", data[0x0A]);
+ dmi_memory_module_error(sect_n, data[0x0B]);
+ break;
+
+ case 7: /* 3.3.8 Cache Information */
+ if(h->length < 0x0F) {
+ break;
+ }
+
+ dmixml_AddTextChild(sect_n, "SocketDesignation", dmi_string(h, data[0x04]));
+ dmixml_AddAttribute(sect_n, "Enabled", "%i", (WORD(data + 0x05) & 0x0080 ? 1 : 0));
+ dmixml_AddAttribute(sect_n, "Socketed", "%i", (WORD(data + 0x05) & 0x0008 ? 1 : 0));
+ dmixml_AddAttribute(sect_n, "Level", "%ld", ((WORD(data + 0x05) & 0x0007) + 1));
+
+ sub_n = dmixml_AddTextChild(sect_n, "OperationalMode", "%s",
+ dmi_cache_mode((WORD(data + 0x05) >> 8) & 0x0003));
+ dmixml_AddAttribute(sub_n, "flags", "0x%04x", (WORD(data + 0x05) >> 8) & 0x0003);
+ sub_n = NULL;
+
+ dmi_cache_location(sect_n, (WORD(data + 0x05) >> 5) & 0x0003);
+ dmi_cache_size(sect_n, "InstalledSize", WORD(data + 0x09));
+ dmi_cache_size(sect_n, "MaximumSize", WORD(data + 0x07));
+
+ dmi_cache_types(sect_n, "SupportedSRAMtypes", WORD(data + 0x0B));
+ dmi_cache_types(sect_n, "InstalledSRAMtypes", WORD(data + 0x0D));
+
+ if(h->length < 0x13) {
+ break;
+ }
+
+ dmi_memory_module_speed(sect_n, "Speed", data[0x0F]);
+ dmi_cache_ec_type(sect_n, data[0x10]);
+ dmi_cache_type(sect_n, data[0x11]);
+ dmi_cache_associativity(sect_n, data[0x12]);
+ break;
+
+ case 8: /* 3.3.9 Port Connector Information */
+ if(h->length < 0x09) {
+ break;
+ }
+
+ sub_n = dmixml_AddTextChild(sect_n, "DesignatorRef", dmi_string(h, data[0x04]));
+ assert( sub_n != NULL );
+ dmixml_AddAttribute(sub_n, "type", "internal");
+ sub_n = NULL;
+
+ dmi_port_connector_type(sect_n, "internal", data[0x05]);
+
+ sub_n = dmixml_AddTextChild(sect_n, "DesignatorRef", dmi_string(h, data[0x06]));
+ assert( sub_n != NULL );
+ dmixml_AddAttribute(sub_n, "type", "external");
+ sub_n = NULL;
+
+ dmi_port_connector_type(sect_n, "external", data[0x07]);
+ dmi_port_type(sect_n, data[0x08]);
+ break;
+
+ case 9: /* 3.3.10 System Slots */
+ if(h->length < 0x0C) {
+ break;
+ }
+
+ dmixml_AddTextChild(sect_n, "Designation", "%s", dmi_string(h, data[0x04]));
+
+ dmi_slot_bus_width(sect_n, data[0x06]);
+ dmi_slot_type(sect_n, data[0x05]);
+ dmi_slot_current_usage(sect_n, data[0x07]);
+ dmi_slot_length(sect_n, data[0x08]);
+ dmi_slot_id(sect_n, data[0x09], data[0x0A], data[0x05]);
- _val = dmi_memory_device_width(WORD(data+0x0A));
- PyDict_SetItemString(caseData, "Data Width", _val);
- Py_DECREF(_val);
+ if( h->length < 0x0D ) {
+ dmi_slot_characteristics(sect_n, data[0x0B], 0x00);
+ } else {
+ dmi_slot_characteristics(sect_n, data[0x0B], data[0x0C]);
+ }
+ break;
- _val = dmi_memory_device_size(WORD(data+0x0C));
- PyDict_SetItemString(caseData, "Size", _val);
- Py_DECREF(_val);
+ case 10: /* 3.3.11 On Board Devices Information */
+ dmi_on_board_devices(sect_n, "dmi_on_board_devices", h);
+ break;
+
+ case 11: /* 3.3.12 OEM Strings */
+ if(h->length < 0x05) {
+ break;
+ }
+
+ dmi_oem_strings(sect_n, h);
+ break;
+
+ case 12: /* 3.3.13 System Configuration Options */
+ if(h->length < 0x05) {
+ break;
+ }
+
+ dmi_system_configuration_options(sect_n, h);
+ break;
+
+ case 13: /* 3.3.14 BIOS Language Information */
+ if(h->length < 0x16) {
+ break;
+ }
+
+ dmixml_AddAttribute(sect_n, "installable_languages", "%i", data[0x04]);
+
+ dmi_bios_languages(sect_n, h);
+ break;
+
+ case 14: /* 3.3.15 Group Associations */
+ if(h->length < 0x05) {
+ break;
+ }
+
+ dmixml_AddTextChild(sect_n, "Name", "%s", dmi_string(h, data[0x04]));
+
+ sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Groups", NULL);
+ assert( sub_n != NULL );
+ dmi_group_associations_items(sub_n, (h->length - 0x05) / 3, data + 0x05);
+ sub_n = NULL;
+ break;
+
+ case 15: /* 3.3.16 System Event Log */
+ // SysEventLog - sect_n
+ if(h->length < 0x14) {
+ break;
+ }
+
+ dmi_event_log_status(sect_n, data[0x0B]);
+
+ // SysEventLog/Access - sub
+ sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Access", NULL);
+ assert( sub_n != NULL );
+
+ dmixml_AddAttribute(sub_n, "AreaLength", "%i", WORD(data + 0x04));
+ dmi_event_log_method(sub_n, data[0x0A]);
+ dmi_event_log_address(sub_n, data[0x0A], data + 0x10);
+
+ // SysEventLog/Access/Header - sub2
+ sub2_n = xmlNewChild(sub_n, NULL, (xmlChar *) "Header", NULL);
+ assert( sub2_n != NULL );
+
+ dmixml_AddTextChild(sub2_n, "OffsetStart", "0x%04x", WORD(data + 0x06));
+
+ if((WORD(data + 0x08) - WORD(data + 0x06)) >= 0) {
+ dmixml_AddTextChild(sub2_n, "Length", "%i", WORD(data + 0x08) - WORD(data + 0x06));
+ }
+
+ dmixml_AddTextChild(sub2_n, "DataOffset", "0x%04x", WORD(data + 0x08));
+ dmixml_AddTextChild(sub2_n, "ChangeToken", "0x%08x", DWORD(data + 0x0C));
+
+ if(h->length < 0x17) {
+ break;
+ }
+
+ // SysEventLog/Access/Header/Format - sub2_n
+ dmi_event_log_header_type(sub2_n, data[0x14]);
+
+ sub2_n = NULL;
+ sub_n = NULL;
+
+ // SysEventLog/LogTypes - resuing sub_n
+ sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "LogTypes", NULL);
+ assert( sub_n != NULL );
+
+ // SysEventLog/LogTypes/@count
+ dmixml_AddAttribute(sub_n, "count", "%i", data[0x15]);
+
+ if(h->length < 0x17 + data[0x15] * data[0x16]) {
+ break;
+ }
+
+ dmixml_AddAttribute(sub_n, "length", "%i", data[0x16]);
+
+ // SysEventLog/LogTypes/LogType
+ dmi_event_log_descriptors(sub_n, data[0x15], data[0x16], data + 0x17);
+ sub_n = NULL;
+ break;
+
+ case 16: /* 3.3.17 Physical Memory Array */
+ if(h->length < 0x0F) {
+ break;
+ }
+
+ dmixml_AddAttribute(sect_n, "NumDevices", "%ld", WORD(data + 0x0D));
+ dmi_memory_array_location(sect_n, data[0x04]);
+ dmi_memory_array_use(sect_n, data[0x05]);
+ dmi_memory_array_ec_type(sect_n, data[0x06]);
+ dmi_memory_array_capacity(sect_n, DWORD(data + 0x07));
+ dmi_memory_array_error_handle(sect_n, WORD(data + 0x0B));
+ break;
+
+ case 17: /* 3.3.18 Memory Device */
+ if(h->length < 0x15) {
+ break;
+ }
+
+ dmixml_AddAttribute(sect_n, "ArrayHandle", "0x%04x", WORD(data + 0x04));
+ dmi_memory_array_error_handle(sect_n, WORD(data + 0x06));
+
+ dmi_memory_device_width(sect_n, "TotalWidth", WORD(data + 0x08));
+ dmi_memory_device_width(sect_n, "DataWidth", WORD(data + 0x0A));
+ dmi_memory_device_size(sect_n, WORD(data + 0x0C));
+ dmi_memory_device_form_factor(sect_n, data[0x0E]);
+ dmi_memory_device_set(sect_n, data[0x0F]);
+ dmixml_AddTextChild(sect_n, "Locator", dmi_string(h, data[0x10]));
+ dmixml_AddTextChild(sect_n, "BankLocator", dmi_string(h, data[0x11]));
+
+ dmi_memory_device_type(sect_n, data[0x12]);
+ dmi_memory_device_type_detail(sect_n, WORD(data + 0x13));
+
+ if(h->length < 0x17) {
+ break;
+ }
+
+ dmi_memory_device_speed(sect_n, WORD(data + 0x15));
+
+ if(h->length < 0x1B) {
+ break;
+ }
+
+ dmixml_AddTextChild(sect_n, "Manufacturer", "%s", dmi_string(h, data[0x17]));
+ dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x18]));
+ dmixml_AddTextChild(sect_n, "AssetTag", "%s", dmi_string(h, data[0x19]));
+ dmixml_AddTextChild(sect_n, "PartNumber", "%s", dmi_string(h, data[0x1A]));
+ break;
+
+ case 18: /* 3.3.19 32-bit Memory Error Information */
+ case 33: /* 3.3.34 64-bit Memory Error Information */
+ if( h->type == 18 ) {
+ dmixml_AddAttribute(sect_n, "bits", "32");
+ } else {
+ dmixml_AddAttribute(sect_n, "bits", "64");
+ }
+
+ if( ((h->type == 18) && (h->length < 0x17)) /* 32-bit */
+ || ((h->type == 33) && (h->length < 0x1F)) ) /* 64-bit */
+ {
+ break;
+ }
+
+ dmi_memory_error_type(sect_n, data[0x04]);
+ dmi_memory_error_granularity(sect_n, data[0x05]);
+ dmi_memory_error_operation(sect_n, data[0x06]);
+ dmi_memory_error_syndrome(sect_n, DWORD(data + 0x07));
+
+ if( h->type == 18 ) {
+ /* 32-bit */
+ dmi_32bit_memory_error_address(sect_n, "MemArrayAddr", DWORD(data + 0x0B));
+ dmi_32bit_memory_error_address(sect_n, "DeviceAddr", DWORD(data + 0x0F));
+ dmi_32bit_memory_error_address(sect_n, "Resolution", DWORD(data + 0x13));
+ } else if( h->type == 33 ) {
+ /* 64-bit */
+ dmi_64bit_memory_error_address(sect_n, "MemArrayAddr", QWORD(data + 0x0B));
+ dmi_64bit_memory_error_address(sect_n, "DeviceAddr", QWORD(data + 0x13));
+ dmi_32bit_memory_error_address(sect_n, "Resolution", DWORD(data + 0x1B));
+ }
+ break;
+
+ case 19: /* 3.3.20 Memory Array Mapped Address */
+ if(h->length < 0x0F) {
+ break;
+ }
+
+ dmixml_AddTextChild(sect_n, "StartAddress", "0x%08x%03x",
+ (DWORD(data + 0x04) >> 2),
+ (DWORD(data + 0x04) & 0x3) << 10);
+ dmixml_AddTextChild(sect_n, "EndAddress", "0x%08x%03x",
+ (DWORD(data + 0x08) >> 2),
+ ((DWORD(data + 0x08) & 0x3) << 10) + 0x3FF);
+ dmi_mapped_address_size(sect_n, DWORD(data + 0x08) - DWORD(data + 0x04) + 1);
+ dmixml_AddTextChild(sect_n, "PhysicalArrayHandle", "0x%04x", WORD(data + 0x0C));
+ dmixml_AddTextChild(sect_n, "PartitionWidth", "%i", data[0x0F]);
+ break;
+
+ case 20: /* 3.3.21 Memory Device Mapped Address */
+ if(h->length < 0x13) {
+ break;
+ }
+
+ dmixml_AddTextChild(sect_n, "StartAddress", "0x%08x%03x",
+ (DWORD(data + 0x04) >> 2),
+ (DWORD(data + 0x04) & 0x3) << 10);
+
+ dmixml_AddTextChild(sect_n, "EndAddress", "0x%08x%03x",
+ (DWORD(data + 0x08) >> 2),
+ ((DWORD(data + 0x08) & 0x3) << 10) + 0x3FF);
+
+ dmi_mapped_address_size(sect_n, DWORD(data + 0x08) - DWORD(data + 0x04) + 1);
+
+ dmixml_AddTextChild(sect_n, "PhysicalDeviceHandle", "0x%04x", WORD(data + 0x0C));
+ dmixml_AddTextChild(sect_n, "MemArrayMappedAddrHandle", "0x%04x", WORD(data + 0x0E));
+
+ dmi_mapped_address_row_position(sect_n, data[0x10]);
+
+ dmi_mapped_address_interleave_position(sect_n, data[0x11]);
+ dmi_mapped_address_interleaved_data_depth(sect_n, data[0x12]);
+ break;
+
+ case 21: /* 3.3.22 Built-in Pointing Device */
+ if(h->length < 0x07) {
+ break;
+ }
+
+ dmi_pointing_device_type(sect_n, data[0x04]);
+ dmi_pointing_device_interface(sect_n, data[0x05]);
+ dmixml_AddTextChild(sect_n, "Buttons", "%i", data[0x06]);
+ break;
+
+ case 22: /* 3.3.23 Portable Battery */
+ if(h->length < 0x10) {
+ break;
+ }
+
+ dmixml_AddTextChild(sect_n, "Location", "%s", dmi_string(h, data[0x04]));
+ dmixml_AddTextChild(sect_n, "Manufacturer", "%s", dmi_string(h, data[0x05]));
+
+ if(data[0x06] || h->length < 0x1A) {
+ dmixml_AddTextChild(sect_n, "ManufactureDate", "%s", dmi_string(h, data[0x06]));
+ }
+
+ if(data[0x07] || h->length < 0x1A) {
+ dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x07]));
+ }
+
+ dmixml_AddTextChild(sect_n, "Name", "%s", dmi_string(h, data[0x08]));
+
+ if(data[0x09] != 0x02 || h->length < 0x1A) {
+ dmi_battery_chemistry(sect_n, data[0x09]);
+ }
+
+ dmi_battery_capacity(sect_n, WORD(data + 0x0A), (h->length < 0x1A ? 1 : data[0x15]));
+ dmi_battery_voltage(sect_n, WORD(data + 0x0C));
+ dmixml_AddTextChild(sect_n, "SBDSversion", "%s", dmi_string(h, data[0x0E]));
+
+ dmi_battery_maximum_error(sect_n, data[0x0F]);
+
+ if(h->length < 0x1A) {
+ break;
+ }
+
+ if(data[0x07] == 0) {
+ dmixml_AddTextChild(sect_n, "SBDSserialNumber", "%04x", WORD(data + 0x10));
+ }
+ if(data[0x06] == 0) {
+ dmixml_AddTextChild(sect_n, "SBDSmanufactureDate", "%i-%02u-%02u",
+ 1980 + (WORD(data + 0x12) >> 9),
+ (WORD(data + 0x12) >> 5) & 0x0F,
+ (WORD(data + 0x12) & 0x1F));
+ }
+ if(data[0x09] == 0x02) {
+ dmixml_AddTextChild(sect_n, "SBDSchemistry", "%s", dmi_string(h, data[0x14]));
+ }
+
+ dmixml_AddTextChild(sect_n, "OEMinformation", "0x%08x", DWORD(data + 0x16));
+ break;
- _val = dmi_memory_device_form_factor(data[0x0E]);
- PyDict_SetItemString(caseData, "Form Factor", _val);
- Py_DECREF(_val);
+ case 23: /* 3.3.24 System Reset */
+ if(h->length < 0x0D) {
+ break;
+ }
- _val = dmi_memory_device_set(data[0x0F]);
- PyDict_SetItemString(caseData, "Set", _val);
- Py_DECREF(_val);
+ sub_n = dmixml_AddTextChild(sect_n, "Status", "%s",
+ data[0x04] & (1 << 0) ? "Enabled" : "Disabled");
+ dmixml_AddAttribute(sub_n, "enabled", "%i", data[0x04] & (1 << 0) ? 1 : 0);
+ sub_n = NULL;
- _val = dmi_string_py(h, data[0x10]);
- PyDict_SetItemString(caseData, "Locator", _val);
- Py_DECREF(_val);
+ sub_n = dmixml_AddTextChild(sect_n, "WatchdogTimer", "%s",
+ data[0x04] & (1 << 5) ? "Present" : "Not Present");
+ dmixml_AddAttribute(sub_n, "present", "%i", data[0x04] & (1 << 5) ? 1 : 0);
+ sub_n = NULL;
- _val = dmi_string_py(h, data[0x11]);
- PyDict_SetItemString(caseData, "Bank Locator", _val);
- Py_DECREF(_val);
+ if(!(data[0x04] & (1 << 5))) {
+ break;
+ }
- _val = dmi_memory_device_type(data[0x12]);
- PyDict_SetItemString(caseData, "Type", _val);
- Py_DECREF(_val);
+ dmi_system_reset_boot_option(sect_n, "BootOption", (data[0x04] >> 1) & 0x3);
+ dmi_system_reset_boot_option(sect_n, "BootOptionOnLimit", (data[0x04] >> 3) & 0x3);
- _val = dmi_memory_device_type_detail(WORD(data+0x13));
- PyDict_SetItemString(caseData, "Type Detail", _val);
- Py_DECREF(_val);
+ dmi_system_reset_count(sect_n, "ResetCount", WORD(data + 0x05));
+ dmi_system_reset_count(sect_n, "ResetLimit", WORD(data + 0x07));
- if(h->length<0x17) break;
- _val = dmi_memory_device_speed(WORD(data+0x15));
- PyDict_SetItemString(caseData, "Speed", _val);
- Py_DECREF(_val);
+ dmi_system_reset_timer(sect_n, "TimerInterval", WORD(data + 0x09));
+ dmi_system_reset_timer(sect_n, "Timeout", WORD(data + 0x0B));
+ break;
- if(h->length<0x1B) break;
- _val = dmi_string_py(h, data[0x17]);
- PyDict_SetItemString(caseData, "Manufacturer", _val);
- Py_DECREF(_val);
+ case 24: /* 3.3.25 Hardware Security */
+ if(h->length < 0x05) {
+ break;
+ }
- _val = dmi_string_py(h, data[0x18]);
- PyDict_SetItemString(caseData,"Serial Number" , _val);
- Py_DECREF(_val);
+ dmi_hardware_security_status(sect_n, "PowerOnPassword", data[0x04] >> 6);
+ dmi_hardware_security_status(sect_n, "KeyboardPassword", (data[0x04] >> 4) & 0x3);
+ dmi_hardware_security_status(sect_n, "AdministratorPassword", (data[0x04] >> 2) & 0x3);
+ dmi_hardware_security_status(sect_n, "FronPanelReset", data[0x04] & 0x3);
- _val = dmi_string_py(h, data[0x19]);
- PyDict_SetItemString(caseData, "Asset Tag", _val);
- Py_DECREF(_val);
+ break;
- _val = dmi_string_py(h, data[0x1A]);
- PyDict_SetItemString(caseData, "Part Number", _val);
- Py_DECREF(_val);
- break;
+ case 25: /* 3.3.26 System Power Controls */
+ if(h->length < 0x09) {
+ break;
+ }
- case 18: /* 3.3.19 32-bit Memory Error Information */
+ dmi_power_controls_power_on(sect_n, "NextSchedPowerOn", data + 0x04);
+ break;
- if(h->length<0x17) break;
- _val = dmi_memory_error_type(data[0x04]);
- PyDict_SetItemString(caseData, "Type", _val);
- Py_DECREF(_val);
+ case 26: /* 3.3.27 Voltage Probe */
+ dmixml_AddAttribute(sect_n, "probetype", "Voltage");
- _val = dmi_memory_error_granularity(data[0x05]);
- PyDict_SetItemString(caseData, "Granularity", _val);
- Py_DECREF(_val);
+ if(h->length < 0x14) {
+ break;
+ }
- _val = dmi_memory_error_operation(data[0x06]);
- PyDict_SetItemString(caseData, "Operation", _val);
- Py_DECREF(_val);
+ dmixml_AddTextChild(sect_n, "Description", "%s", dmi_string(h, data[0x04]));
- _val = dmi_memory_error_syndrome(DWORD(data+0x07));
- PyDict_SetItemString(caseData, "Vendor Syndrome", _val);
- Py_DECREF(_val);
+ dmi_voltage_probe_location(sect_n, data[0x05] & 0x1f);
+ dmi_probe_status(sect_n, data[0x05] >> 5);
- _val = dmi_32bit_memory_error_address(DWORD(data+0x0B));
- PyDict_SetItemString(caseData, "Memory Array Address", _val);
- Py_DECREF(_val);
+ dmi_voltage_probe_value(sect_n, "MaxValue", WORD(data + 0x06));
+ dmi_voltage_probe_value(sect_n, "MinValue", WORD(data + 0x08));
+ dmi_voltage_probe_resolution(sect_n, WORD(data + 0x0A));
+ dmi_voltage_probe_value(sect_n, "Tolerance", WORD(data + 0x0C));
- _val = dmi_32bit_memory_error_address(DWORD(data+0x0F));
- PyDict_SetItemString(caseData, "Device Address", _val);
- Py_DECREF(_val);
+ dmi_probe_accuracy(sect_n, WORD(data + 0x0E));
- _val = dmi_32bit_memory_error_address(DWORD(data+0x13));
- PyDict_SetItemString(caseData, "Resolution", _val);
- Py_DECREF(_val);
- break;
-
- case 19: /* 3.3.20 Memory Array Mapped Address */
-
- if(h->length<0x0F) break;
- _val = PyString_FromFormat("0x%08x%03x", DWORD(data+0x04)>>2, (DWORD(data+0x04)&0x3)<<10);
- PyDict_SetItemString(caseData, "Starting Address", _val);
- Py_DECREF(_val);
-
- _val = PyString_FromFormat("0x%08x%03x", DWORD(data+0x08)>>2, ((DWORD(data+0x08)&0x3)<<10)+0x3FF);
- PyDict_SetItemString(caseData, "Ending Address", _val);
- Py_DECREF(_val);
-
- _val = dmi_mapped_address_size(DWORD(data+0x08)-DWORD(data+0x04)+1);
- PyDict_SetItemString(caseData, "Range Size", _val);
- Py_DECREF(_val);
-
- _val = PyString_FromFormat("0x%04x", WORD(data+0x0C));
- PyDict_SetItemString(caseData, "Physical Array Handle", _val);
- Py_DECREF(_val);
-
- _val = PyString_FromFormat("%i", data[0x0F]);
- PyDict_SetItemString(caseData, "Partition Width", _val);
- Py_DECREF(_val);
- break;
-
- case 20: /* 3.3.21 Memory Device Mapped Address */
-
- if(h->length<0x13) break;
- _val = PyString_FromFormat("0x%08x%03x", DWORD(data+0x04)>>2, (DWORD(data+0x04)&0x3)<<10);
- PyDict_SetItemString(caseData, "Starting Address", _val);
- Py_DECREF(_val);
-
- _val = PyString_FromFormat("0x%08x%03x", DWORD(data+0x08)>>2, ((DWORD(data+0x08)&0x3)<<10)+0x3FF);
- PyDict_SetItemString(caseData, "Ending Address", _val);
- Py_DECREF(_val);
-
- _val = dmi_mapped_address_size(DWORD(data+0x08)-DWORD(data+0x04)+1);
- PyDict_SetItemString(caseData, "Range Size", _val);
- Py_DECREF(_val);
-
- _val = PyString_FromFormat("0x%04x", WORD(data+0x0C));
- PyDict_SetItemString(caseData, "Physical Device Handle", _val);
- Py_DECREF(_val);
-
- _val = PyString_FromFormat("0x%04x", WORD(data+0x0E));
- PyDict_SetItemString(caseData, "Memory Array Mapped Address Handle", _val);
- Py_DECREF(_val);
-
- _val = dmi_mapped_address_row_position(data[0x10]);
- PyDict_SetItemString(caseData, "Partition Row Position", _val);
- Py_DECREF(_val);
-
- _val = dmi_mapped_address_interleave_position(data[0x11]);
- PyDict_SetItemString(caseData, ">>>", _val);
- Py_DECREF(_val);
-
- _val = dmi_mapped_address_interleaved_data_depth(data[0x12]);
- PyDict_SetItemString(caseData, ">>>", _val);
- Py_DECREF(_val);
- break;
-
- case 21: /* 3.3.22 Built-in Pointing Device */
-
- if(h->length<0x07) break;
- _val = dmi_pointing_device_type(data[0x04]);
- PyDict_SetItemString(caseData, "Type", _val);
- Py_DECREF(_val);
-
- _val = dmi_pointing_device_interface(data[0x05]);
- PyDict_SetItemString(caseData, "Interface", _val);
- Py_DECREF(_val);
-
- _val = PyString_FromFormat("%i", data[0x06]);
- PyDict_SetItemString(caseData, "Buttons", _val);
- Py_DECREF(_val);
- break;
-
- case 22: /* 3.3.23 Portable Battery */
-
- if(h->length<0x10) break;
- _val = dmi_string_py(h, data[0x04]);
- PyDict_SetItemString(caseData, "Location", _val);
- Py_DECREF(_val);
-
- _val = dmi_string_py(h, data[0x05]);
- PyDict_SetItemString(caseData, "Manufacturer", _val);
- Py_DECREF(_val);
-
- if(data[0x06] || h->length<0x1A) {
- _val = dmi_string_py(h, data[0x06]);
- PyDict_SetItemString(caseData, "Manufacture Date", _val);
- Py_DECREF(_val);
- }
-
- if(data[0x07] || h->length<0x1A) {
- _val = dmi_string_py(h, data[0x07]);
- PyDict_SetItemString(caseData, "Serial Number", _val);
- Py_DECREF(_val);
- }
-
- _val = dmi_string_py(h, data[0x08]);
- PyDict_SetItemString(caseData, "Name", _val);
- Py_DECREF(_val);
-
- if(data[0x09]!=0x02 || h->length<0x1A) {
- _val = dmi_battery_chemistry(data[0x09]);
- PyDict_SetItemString(caseData, "Chemistry", _val);
- Py_DECREF(_val);
- }
- _val = (h->length<0x1A)?dmi_battery_capacity(WORD(data+0x0A), 1):dmi_battery_capacity(WORD(data+0x0A), data[0x15]);
- PyDict_SetItemString(caseData, "Design Capacity", _val);
- Py_DECREF(_val);
-
- _val = dmi_battery_voltage(WORD(data+0x0C));
- PyDict_SetItemString(caseData, "Design Voltage", _val);
- Py_DECREF(_val);
-
- _val = dmi_string_py(h, data[0x0E]);
- PyDict_SetItemString(caseData, "SBDS Version", _val);
- Py_DECREF(_val);
-
- _val = dmi_battery_maximum_error(data[0x0F]);
- PyDict_SetItemString(caseData, "Maximum Error", _val);
- Py_DECREF(_val);
-
- if(h->length<0x1A) break;
- if(data[0x07]==0) {
- _val = PyString_FromFormat("%04x", WORD(data+0x10));
- PyDict_SetItemString(caseData, "SBDS Serial Number", _val);
- Py_DECREF(_val);
- }
- if(data[0x06]==0) {
- _val = PyString_FromFormat("%i-%02u-%02u", 1980+(WORD(data+0x12)>>9), (WORD(data+0x12)>>5)&0x0F, WORD(data+0x12)&0x1F);
- PyDict_SetItemString(caseData, "SBDS Manufacture Date", _val);
- Py_DECREF(_val);
- }
- if(data[0x09]==0x02) {
- _val = dmi_string_py(h, data[0x14]);
- PyDict_SetItemString(caseData, "SBDS Chemistry", _val);
- Py_DECREF(_val);
- }
-
- _val = PyString_FromFormat("0x%08x", DWORD(data+0x16));
- PyDict_SetItemString(caseData, "OEM-specific Information", _val);
- Py_DECREF(_val);
- break;
-
- case 23: /* 3.3.24 System Reset */
-
- if(h->length<0x0D) break;
- _val = PyString_FromFormat("%s", data[0x04]&(1<<0)?"Enabled":"Disabled");
- PyDict_SetItemString(caseData, "Status", _val);
- Py_DECREF(_val);
-
- _val = PyString_FromFormat("%s", data[0x04]&(1<<5)?"Present":"Not Present");
- PyDict_SetItemString(caseData, "Watchdog Timer", _val);
- Py_DECREF(_val);
-
- if(!(data[0x04]&(1<<5))) break;
- _val = dmi_system_reset_boot_option((data[0x04]>>1)&0x3);
- PyDict_SetItemString(caseData, "Boot Option", _val);
- Py_DECREF(_val);
-
- _val = dmi_system_reset_boot_option((data[0x04]>>3)&0x3);
- PyDict_SetItemString(caseData, "Boot Option On Limit", _val);
- Py_DECREF(_val);
-
- _val = dmi_system_reset_count(WORD(data+0x05));
- PyDict_SetItemString(caseData, "Reset Count", _val);
- Py_DECREF(_val);
-
- _val = dmi_system_reset_count(WORD(data+0x07));
- PyDict_SetItemString(caseData, "Reset Limit", _val);
- Py_DECREF(_val);
-
- _val = dmi_system_reset_timer(WORD(data+0x09));
- PyDict_SetItemString(caseData, "Timer Interval", _val);
- Py_DECREF(_val);
-
- _val = dmi_system_reset_timer(WORD(data+0x0B));
- PyDict_SetItemString(caseData, "Timeout", _val);
- Py_DECREF(_val);
-
- break;
-
- case 24: /* 3.3.25 Hardware Security */
-
- if(h->length<0x05) break;
- _val = dmi_hardware_security_status(data[0x04]>>6);
- PyDict_SetItemString(caseData, "Power-On Password Status", _val);
- Py_DECREF(_val);
-
- _val = dmi_hardware_security_status((data[0x04]>>4)&0x3);
- PyDict_SetItemString(caseData, "Keyboard Password Status", _val);
- Py_DECREF(_val);
-
- _val = dmi_hardware_security_status((data[0x04]>>2)&0x3);
- PyDict_SetItemString(caseData, "Administrator Password Status", _val);
- Py_DECREF(_val);
-
- _val = dmi_hardware_security_status(data[0x04]&0x3);
- PyDict_SetItemString(caseData, "Front Panel Reset Status", _val);
- Py_DECREF(_val);
-
- break;
-
- case 25: /* 3.3.26 System Power Controls */
-
- if(h->length<0x09) break;
- _val = dmi_power_controls_power_on(data+0x04);
- PyDict_SetItemString(caseData, "Next Scheduled Power-on", _val);
- Py_DECREF(_val);
-
- break;
-
- case 26: /* 3.3.27 Voltage Probe */
-
- if(h->length<0x14) break;
- _val = dmi_string_py(h, data[0x04]);
- PyDict_SetItemString(caseData, "Description", _val);
- Py_DECREF(_val);
-
- _val = dmi_voltage_probe_location(data[0x05]&0x1f);
- PyDict_SetItemString(caseData, "Location", _val);
- Py_DECREF(_val);
-
- _val = dmi_probe_status(data[0x05]>>5);
- PyDict_SetItemString(caseData, "Status", _val);
- Py_DECREF(_val);
+ dmixml_AddTextChild(sect_n, "OEMinformation", "0x%08x", DWORD(data + 0x10));
- _val = dmi_voltage_probe_value(WORD(data+0x06));
- PyDict_SetItemString(caseData, "Maximum Value", _val);
- Py_DECREF(_val);
+ if(h->length < 0x16) {
+ break;
+ }
- _val = dmi_voltage_probe_value(WORD(data+0x08));
- PyDict_SetItemString(caseData, "Minimum Value", _val);
- Py_DECREF(_val);
+ dmi_voltage_probe_value(sect_n, "NominalValue", WORD(data + 0x14));
+ break;
- _val = dmi_voltage_probe_resolution(WORD(data+0x0A));
- PyDict_SetItemString(caseData, "Resolution", _val);
- Py_DECREF(_val);
+ case 27: /* 3.3.28 Cooling Device */
+ if(h->length < 0x0C) {
+ break;
+ }
- _val = dmi_voltage_probe_value(WORD(data+0x0C));
- PyDict_SetItemString(caseData, "Tolerance", _val);
- Py_DECREF(_val);
+ if(WORD(data + 0x04) != 0xFFFF) {
+ dmixml_AddTextContent(sect_n, "TemperatureProbeHandle", "0x%04x", WORD(data + 0x04));
+ }
- _val = dmi_probe_accuracy(WORD(data+0x0E));
- PyDict_SetItemString(caseData, "Accuracy", _val);
- Py_DECREF(_val);
+ dmi_cooling_device_type(sect_n, data[0x06] & 0x1f);
+ dmi_probe_status(sect_n, data[0x06] >> 5);
- _val = PyString_FromFormat("0x%08x", DWORD(data+0x10));
- PyDict_SetItemString(caseData, "OEM-specific Information", _val);
- Py_DECREF(_val);
+ if(data[0x07] != 0x00) {
+ dmixml_AddTextChild(sect_n, "UnitGroup", "%i", data[0x07]);
+ }
- if(h->length<0x16) break;
- _val = dmi_voltage_probe_value(WORD(data+0x14));
- PyDict_SetItemString(caseData, "Nominal Value", _val);
- Py_DECREF(_val);
+ dmixml_AddTextChild(sect_n, "OEMinformation", "0x%08x", DWORD(data + 0x08));
- break;
+ if(h->length < 0x0E) {
+ break;
+ }
- case 27: /* 3.3.28 Cooling Device */
+ dmi_cooling_device_speed(sect_n, WORD(data + 0x0C));
+ break;
- if(h->length<0x0C) break;
- if(WORD(data+0x04)!=0xFFFF) {
- _val = PyString_FromFormat("0x%04x", WORD(data+0x04));
- PyDict_SetItemString(caseData, "Temperature Probe Handle", _val);
- Py_DECREF(_val);
- }
+ case 28: /* 3.3.29 Temperature Probe */
+ dmixml_AddAttribute(sect_n, "probetype", "Temperature");
- _val = dmi_cooling_device_type(data[0x06]&0x1f);
- PyDict_SetItemString(caseData, "Type", _val);
- Py_DECREF(_val);
+ if(h->length < 0x14) {
+ break;
+ }
- _val = dmi_probe_status(data[0x06]>>5);
- PyDict_SetItemString(caseData, "Status", _val);
- Py_DECREF(_val);
+ dmixml_AddTextChild(sect_n, "Description", "%s", dmi_string(h, data[0x04]));
+ dmi_temperature_probe_location(sect_n,data[0x05] & 0x1F);
+ dmi_probe_status(sect_n, data[0x05] >> 5);
- if(data[0x07]!=0x00) {
- _val = PyString_FromFormat("%i", data[0x07]);
- PyDict_SetItemString(caseData, "Cooling Unit Group", _val);
- Py_DECREF(_val);
- }
+ dmi_temperature_probe_value(sect_n, "MaxValue", WORD(data + 0x06));
+ dmi_temperature_probe_value(sect_n, "MinValue", WORD(data + 0x08));
+ dmi_temperature_probe_resolution(sect_n, WORD(data + 0x0A));
+ dmi_temperature_probe_value(sect_n, "Tolerance", WORD(data + 0x0C));
+ dmi_probe_accuracy(sect_n, WORD(data + 0x0E));
- _val = PyString_FromFormat("0x%08x", DWORD(data+0x08));
- PyDict_SetItemString(caseData, "OEM-specific Information", _val);
- Py_DECREF(_val);
+ dmixml_AddTextChild(sect_n, "OEMinformation", "0x%08x", DWORD(data + 0x10));
- if(h->length<0x0E) break;
- _val = dmi_cooling_device_speed(WORD(data+0x0C));
- PyDict_SetItemString(caseData, "Nominal Speed", _val);
- Py_DECREF(_val);
+ if(h->length < 0x16) {
+ break;
+ }
- break;
+ dmi_temperature_probe_value(sect_n, "NominalValue", WORD(data + 0x14));
+ break;
- case 28: /* 3.3.29 Temperature Probe */
+ case 29: /* 3.3.30 Electrical Current Probe */
+ dmixml_AddAttribute(sect_n, "probetype", "Electrical Current");
- if(h->length<0x14) break;
- _val = dmi_string_py(h, data[0x04]);
- PyDict_SetItemString(caseData, "Description", _val);
- Py_DECREF(_val);
+ if(h->length < 0x14) {
+ break;
+ }
- _val = dmi_temperature_probe_location(data[0x05]&0x1F);
- PyDict_SetItemString(caseData, "Location", _val);
- Py_DECREF(_val);
+ dmixml_AddTextChild(sect_n, "Description", dmi_string(h, data[0x04]));
+ dmi_voltage_probe_location(sect_n, data[5] & 0x1F);
+ dmi_probe_status(sect_n, data[0x05] >> 5);
- _val = dmi_probe_status(data[0x05]>>5);
- PyDict_SetItemString(caseData, "Status", _val);
- Py_DECREF(_val);
+ dmi_current_probe_value(sect_n, "MaxValue", WORD(data + 0x06));
+ dmi_current_probe_value(sect_n, "MinValue", WORD(data + 0x08));
+ dmi_current_probe_resolution(sect_n, WORD(data + 0x0A));
+ dmi_current_probe_value(sect_n, "Tolerance", WORD(data + 0x0C));
- _val = dmi_temperature_probe_value(WORD(data+0x06));
- PyDict_SetItemString(caseData, "Maximum Value", _val);
- Py_DECREF(_val);
+ dmi_probe_accuracy(sect_n, WORD(data + 0x0E));
- _val = dmi_temperature_probe_value(WORD(data+0x08));
- PyDict_SetItemString(caseData, "Minimum Value", _val);
- Py_DECREF(_val);
+ dmixml_AddTextChild(sect_n, "OEMinformation", "0x%08x", DWORD(data + 0x10));
- _val = dmi_temperature_probe_resolution(WORD(data+0x0A));
- PyDict_SetItemString(caseData, "Resolution", _val);
- Py_DECREF(_val);
+ if(h->length < 0x16) {
+ break;
+ }
- _val = dmi_temperature_probe_value(WORD(data+0x0C));
- PyDict_SetItemString(caseData, "Tolerance", _val);
- Py_DECREF(_val);
+ dmi_current_probe_value(sect_n, "NominalValue", WORD(data + 0x14));
+ break;
- _val = dmi_probe_accuracy(WORD(data+0x0E));
- PyDict_SetItemString(caseData, "Accuracy", _val);
- Py_DECREF(_val);
+ case 30: /* 3.3.31 Out-of-band Remote Access */
+ if(h->length < 0x06) {
+ break;
+ }
- _val = PyString_FromFormat("0x%08x", DWORD(data+0x10));
- PyDict_SetItemString(caseData, "OEM-specific Information", _val);
- Py_DECREF(_val);
+ dmixml_AddTextChild(sect_n, "ManufacturerName", "%s", dmi_string(h, data[0x04]));
+ dmixml_AddAttribute(sect_n, "InboundConnectionEnabled", "%i", data[0x05] & (1 << 0) ? 1 : 0);
+ dmixml_AddAttribute(sect_n, "OutboundConnectionEnabled", "%i", data[0x05] & (1 << 1) ? 1 : 0);
+ break;
- if(h->length<0x16) break;
- _val = dmi_temperature_probe_value(WORD(data+0x14));
- PyDict_SetItemString(caseData, "Nominal Value", _val);
- Py_DECREF(_val);
+ case 31: /* 3.3.32 Boot Integrity Services Entry Point */
+ dmixml_AddAttribute(sect_n, "NOT_IMPLEMENTED", "1");
+ break;
- break;
+ case 32: /* 3.3.33 System Boot Information */
+ if(h->length < 0x0B) {
+ break;
+ }
- case 29: /* 3.3.30 Electrical Current Probe */
+ dmi_system_boot_status(sect_n, data[0x0A]);
+ break;
+
+ case 34: /* 3.3.35 Management Device */
+ dmixml_AddAttribute(sect_n, "mgmtype", "");
+
+ if(h->length < 0x0B) {
+ break;
+ }
+
+ dmixml_AddTextChild(sect_n, "Description", "%s", dmi_string(h, data[0x04]));
+ dmi_management_device_type(sect_n, data[0x05]);
+ dmixml_AddTextChild(sect_n, "Address", "0x%08x", DWORD(data + 0x06));
+ dmi_management_device_address_type(sect_n, data[0x0A]);
+ break;
- if(h->length<0x14) break;
- _val = dmi_string_py(h, data[0x04]);
- PyDict_SetItemString(caseData, "Description", _val);
- Py_DECREF(_val);
+ case 35: /* 3.3.36 Management Device Component */
+ dmixml_AddAttribute(sect_n, "mgmtype", "Component");
- _val = dmi_voltage_probe_location(data[5]&0x1F);
- PyDict_SetItemString(caseData, "Location", _val);
- Py_DECREF(_val);
+ if(h->length < 0x0B) {
+ break;
+ }
+
+ dmixml_AddTextChild(sect_n, "Description", dmi_string(h, data[0x04]));
+ dmixml_AddTextChild(sect_n, "ManagementDeviceHandle", "0x%04x", WORD(data + 0x05));
+ dmixml_AddTextChild(sect_n, "ComponentHandle", "0x%04x", WORD(data + 0x07));
+
+ if(WORD(data + 0x09) != 0xFFFF) {
+ dmixml_AddTextChild(sect_n, "ThresholdHandle", "0x%04x", WORD(data + 0x09));
+ }
+ break;
+
+ case 36: /* 3.3.37 Management Device Threshold Data */
+ dmixml_AddAttribute(sect_n, "mgmtype", "Threshold Data");
+
+ if(h->length < 0x10) {
+ break;
+ }
+
+ sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Thresholds", NULL);
+ assert( sub_n != NULL );
+ dmixml_AddAttribute(sub_n, "mode", "non-critical");
+
+ if(WORD(data + 0x04) != 0x8000) {
+ dmixml_AddAttribute(sub_n, "Lower", "%d", (i16) WORD(data + 0x04));
+ }
+ if(WORD(data + 0x06) != 0x8000) {
+ dmixml_AddAttribute(sub_n, "Upper", "%d", (i16) WORD(data + 0x06));
+ }
+ sub_n = NULL;
+
+ sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Thresholds", NULL);
+ assert( sub_n != NULL );
+ dmixml_AddAttribute(sub_n, "mode", "critical");
+
+ if(WORD(data + 0x08) != 0x8000) {
+ dmixml_AddAttribute(sub_n, "Lower", "%d", (i16) WORD(data + 0x08));
+ }
+ if(WORD(data + 0x0A) != 0x8000) {
+ dmixml_AddAttribute(sub_n, "Upper", "%d", (i16) WORD(data + 0x0A));
+
+ }
+ sub_n = NULL;
+
+ sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Thresholds", NULL);
+ assert( sub_n != NULL );
+ dmixml_AddAttribute(sub_n, "mode", "non-recoverable");
+
+ if(WORD(data + 0x0C) != 0x8000) {
+ dmixml_AddAttribute(sub_n, "Lower", "%d", (i16) WORD(data + 0x0C));
+ }
+ if(WORD(data + 0x0E) != 0x8000) {
+ dmixml_AddAttribute(sub_n, "Upper", "%d", (i16) WORD(data + 0x0E));
+ }
+ sub_n = NULL;
+ break;
+
+ case 37: /* 3.3.38 Memory Channel */
+ if(h->length < 0x07) {
+ break;
+ }
+
+ dmi_memory_channel_type(sect_n, data[0x04]);
+ dmixml_AddTextChild(sect_n, "MaxLoad", "%i", data[0x05]);
+
+ sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Devices", NULL);
+ assert( sub_n != NULL );
+ dmixml_AddAttribute(sub_n, "devices", "%i", data[0x06]);
+
+ if(h->length < 0x07 + 3 * data[0x06]) {
+ sub_n = NULL;
+ break;
+ }
+
+ dmi_memory_channel_devices(sub_n, data[0x06], data + 0x07);
+ sub_n = NULL;
+ break;
+
+ case 38: /* 3.3.39 IPMI Device Information */
+ /*
+ * We use the word "Version" instead of "Revision", conforming to
+ * the IPMI specification.
+ */
+ if(h->length < 0x10) {
+ break;
+ }
+
+ dmi_ipmi_interface_type(sect_n, data[0x04]);
+
+ dmixml_AddAttribute(sect_n, "spec_version", "%i.%i", data[0x05] >> 4, data[0x05] & 0x0F);
+ dmixml_AddAttribute(sect_n, "I2CslaveAddr", "0x%02x", data[0x06] >> 1);
+
+
+ sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "NVstorageDevice", NULL);
+ assert( sub_n != NULL );
+
+ if(data[0x07] != 0xFF) {
+ dmixml_AddAttribute(sub_n, "Address", "%i", data[0x07]);
+ } else {
+ dmixml_AddAttribute(sub_n, "NotPresent", "1");
+ }
+ sub_n = NULL;
+
+ dmi_ipmi_base_address(sect_n, data[0x04], data + 0x08,
+ h->length < 0x12 ? 0 : (data[0x10] >> 5) & 1);
+
+ if(h->length < 0x12) {
+ break;
+ }
+
+ sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Interrupt", NULL);
+ assert( sub_n != NULL );
+
+ if(data[0x04] != 0x04) {
+ dmi_ipmi_register_spacing(sect_n, data[0x10] >> 6);
+
+ if(data[0x10] & (1 << 3)) {
+ sub2_n = dmixml_AddTextChild(sub_n, "Polarity", "%s",
+ data[0x10] & (1 << 1) ? "Active High" : "Active Low");
+ assert( sub2_n != NULL );
+ dmixml_AddAttribute(sub2_n, "active_high", "%i", data[0x10] & (1 << 1) ? 1: 0);
+ sub2_n = NULL;
+
+ dmixml_AddTextChild(sub_n, "TriggerMode", "%s",
+ data[0x10] & (1 << 0) ? "Level" : "Edge");
+ }
+ }
+ if(data[0x11] != 0x00) {
+ dmixml_AddTextChild(sub_n, "InterruptNumber", "%x", data[0x11]);
+ }
+ sub_n = NULL;
+ break;
+
+ case 39: /* 3.3.40 System Power Supply */
+ if(h->length < 0x10) {
+ break;
+ }
+
+ if(data[0x04] != 0x00) {
+ dmixml_AddAttribute(sect_n, "UnitGroup", "%i", data[0x04]);
+ }
+
+ dmixml_AddTextChild(sect_n, "Location", "%s", dmi_string(h, data[0x05]));
+ dmixml_AddTextChild(sect_n, "Name", "%s", dmi_string(h, data[0x06]));
+ dmixml_AddTextChild(sect_n, "Manufacturer", "%s", dmi_string(h, data[0x07]));
+ dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x08]));
+ dmixml_AddTextChild(sect_n, "AssetTag", "%s", dmi_string(h, data[0x09]));
+ dmixml_AddTextChild(sect_n, "ModelPartNumber", "%s", dmi_string(h, data[0x0A]));
+ dmixml_AddTextChild(sect_n, "Revision", "%s", dmi_string(h, data[0x0B]));
+
+ dmi_power_supply_power(sect_n, WORD(data + 0x0C));
+
+ if(WORD(data + 0x0E) & (1 << 1)) {
+ dmi_power_supply_status(sect_n, (WORD(data + 0x0E) >> 7) & 0x07);
+ } else {
+ sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Status", NULL);
+ assert( sub_n != NULL );
+ dmixml_AddAttribute(sub_n, "present", "0");
+ sub_n = NULL;
+ }
+
+ dmi_power_supply_type(sect_n, (WORD(data + 0x0E) >> 10) & 0x0F);
+
+ sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Input", NULL);
+ assert( sub_n != NULL );
+
+ dmi_power_supply_range_switching(sub_n, (WORD(data + 0x0E) >> 3) & 0x0F);
+
+ dmixml_AddAttribute(sub_n, "Plugged", "%i", WORD(data + 0x0E) & (1 << 2) ? 0 : 1);
+ dmixml_AddAttribute(sub_n, "HotReplacable", "%i", WORD(data + 0x0E) & (1 << 0) ? 1 : 0);
+
+ if(h->length < 0x16) {
+ sub_n = NULL;
+ break;
+ }
+
+ if(WORD(data + 0x10) != 0xFFFF) {
+ dmixml_AddTextChild(sub_n, "ProbeHandle", "0x%04x", WORD(data + 0x10));
+ }
+
+ if(WORD(data + 0x12) != 0xFFFF) {
+ dmixml_AddTextChild(sect_n, "CoolingDeviceHandle", "0x%04x", WORD(data + 0x12));
+ }
- _val = dmi_probe_status(data[0x05]>>5);
- PyDict_SetItemString(caseData, "Status", _val);
- Py_DECREF(_val);
+ if(WORD(data + 0x14) != 0xFFFF) {
+ dmixml_AddTextChild(sub_n, "CurrentProbeHandle", "0x%04x", WORD(data + 0x14));
+ }
- _val = dmi_current_probe_value(WORD(data+0x06));
- PyDict_SetItemString(caseData, "Maximum Value", _val);
- Py_DECREF(_val);
+ sub_n = NULL;
+ break;
- _val = dmi_current_probe_value(WORD(data+0x08));
- PyDict_SetItemString(caseData, "Minimum Value", _val);
- Py_DECREF(_val);
+ case 40: /* 3.3.41 Additional Information */
+ dmixml_AddAttribute(sect_n, "subtype", "AdditionalInformation");
+ dmixml_AddAttribute(sect_n, "dmispec", "3.3.41");
+
+ if(h->length < 0x0B) {
+ break;
+ }
+
+ dmi_additional_info(sect_n, h);
+ break;
+
+ case 41: /* 3.3.42 Onboard Device Extended Information */
+ dmixml_AddAttribute(sect_n, "subtype", "OnboardDeviceExtendedInformation");
+ dmixml_AddAttribute(sect_n, "dmispec", "3.3.42");
+
+ if(h->length < 0x0B) {
+ break;
+ }
+
+ dmixml_AddTextChild(sect_n, "ReferenceDesignation", "%s", dmi_string(h, data[0x04]));
+
+ sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "OnboardDevice", NULL);
+ dmi_on_board_devices_type(sub_n, data[0x05] & 0x7F);
+
+ dmixml_AddAttribute(sub_n, "Enabled", "%i", data[0x05] & 0x80 ? 1 : 0);
+ dmixml_AddAttribute(sub_n, "TypeInstance", "%ld", data[0x06]);
+ dmi_slot_segment_bus_func(sub_n, WORD(data + 0x07), data[0x09], data[0x0A]);
+ sub_n = NULL;
+ break;
+
+ case 126: /* 3.3.43 Inactive */
+ case 127: /* 3.3.44 End Of Table */
+ break;
+
+ default:
+ if(dmi_decode_oem(h))
+ break;
- _val = dmi_current_probe_resolution(WORD(data+0x0A));
- PyDict_SetItemString(caseData, "Resolution", _val);
- Py_DECREF(_val);
+ sect_n = xmlNewChild(sect_n, NULL, (xmlChar *) "DMIdump", NULL);
+ assert( sect_n != NULL );
- _val = dmi_current_probe_value(WORD(data+0x0C));
- PyDict_SetItemString(caseData, "Tolerance", _val);
- Py_DECREF(_val);
+ dmixml_AddAttribute(sect_n, "Type", "%i", h->type);
+ dmixml_AddAttribute(sect_n, "InfoType", "%s", h->type >= 128 ? "OEM-specific" : "Unknown");
- _val = dmi_probe_accuracy(WORD(data+0x0E));
- PyDict_SetItemString(caseData, "Accuracy", _val);
- Py_DECREF(_val);
+ dmi_dump(sect_n, h);
+ break;
+ }
+ return sect_n;
+}
- _val = PyString_FromFormat("0x%08x", DWORD(data+0x10));
- PyDict_SetItemString(caseData, "OEM-specific Information", _val);
- Py_DECREF(_val);
+void to_dmi_header(struct dmi_header *h, u8 * data)
+{
+ h->type = data[0];
+ h->length = data[1];
+ h->handle = WORD(data + 2);
+ h->data = data;
+}
- if(h->length<0x16) break;
- _val = dmi_current_probe_value(WORD(data+0x14));
- PyDict_SetItemString(caseData, "Nominal Value", _val);
- Py_DECREF(_val);
- break;
+dmi_codes_major *find_dmiMajor(const struct dmi_header *h)
+{
+ int i = 0;
+
+ for( i = 0; dmiCodesMajor[i].id != NULL; i++ ) {
+ if( h->type == dmiCodesMajor[i].code ) {
+ return (dmi_codes_major *)&dmiCodesMajor[i];
+ }
+ }
+ return NULL;
+}
- case 30: /* 3.3.31 Out-of-band Remote Access */
+static void dmi_table(int type, u32 base, u16 len, u16 num, u16 ver, const char *devmem, xmlNode *xmlnode)
+{
+ u8 *buf;
+ u8 *data;
+ int i = 0;
+ int decoding_done = 0;
- if(h->length<0x06) break;
- _val = dmi_string_py(h, data[0x04]);
- PyDict_SetItemString(caseData, "Manufacturer Name", _val);
- Py_DECREF(_val);
+ if( type == -1 ) {
+ xmlNode *info_n = NULL;
- _val = data[0x05]&(1<<0)?Py_True:Py_False;
- PyDict_SetItemString(caseData, "Inbound Connection Enabled", _val);
- Py_DECREF(_val);
+ info_n = dmixml_AddTextChild(xmlnode, "DMIinfo", "%i structures occupying %i bytes", num, len);
+ dmixml_AddAttribute(info_n, "dmi_structures", "%i", num);
+ dmixml_AddAttribute(info_n, "dmi_size", "%i", len);
- _val = data[0x05]&(1<<1)?Py_True:Py_False;
- PyDict_SetItemString(caseData, "Outbound Connection Enabled", _val);
- Py_DECREF(_val);
- break;
+ /* TODO DUMP
+ * if (!(opt->flags & FLAG_FROM_DUMP))
+ * dmixml_AddAttribute(info_n, "dmi_table_base", "0x%08x", base);
+ */
- case 31: /* 3.3.32 Boot Integrity Services Entry Point */
+ dmixml_AddAttribute(info_n, "dmi_table_base", "0x%08x", base);
+ info_n = NULL;
+ }
- break;
+ if((buf = mem_chunk(base, len, devmem)) == NULL) {
+ fprintf(stderr, "Table is unreachable, sorry."
+#ifndef USE_MMAP
+ "Try compiling dmidecode with -DUSE_MMAP.";
+#endif
+ "\n");
+ return;
+ }
- case 32: /* 3.3.33 System Boot Information */
+ data = buf;
+ while(i < num && data + 4 <= buf + len) { /* 4 is the length of an SMBIOS structure header */
+
+ u8 *next;
+ struct dmi_header h;
+
+ to_dmi_header(&h, data);
+
+ /*
+ ** If a short entry is found (less than 4 bytes), not only it
+ ** is invalid, but we cannot reliably locate the next entry.
+ ** Better stop at this point, and let the user know his/her
+ ** table is broken.
+ */
+ if(h.length < 4) {
+ fprintf(stderr, "Invalid entry length (%i). DMI table is broken! Stop.",
+ (unsigned int)h.length);
+ break;
+ }
+
+ /* In quiet mode (FLAG_QUIET - removed for python-dmidecode all together),
+ * stop decoding at end of table marker
+ */
+
+ /* assign vendor for vendor-specific decodes later */
+ if(h.type == 0 && h.length >= 5) {
+ dmi_set_vendor(dmi_string(&h, data[0x04]));
+ }
+
+ /* look for the next handle */
+ next = data + h.length;
+ while(next - buf + 1 < len && (next[0] != 0 || next[1] != 0)) {
+ next++;
+ }
+ next += 2;
+
+ xmlNode *handle_n = NULL;
+ if( h.type == type ) {
+ if(next - buf <= len) {
+ dmi_codes_major *dmiMajor = NULL;
+ /* TODO: ...
+ * if(opt->flags & FLAG_DUMP) {
+ * PyDict_SetItem(hDict, PyString_FromString("lookup"), dmi_dump(&h));
+ * } */
+
+ dmiMajor = find_dmiMajor(&h);
+ if( dmiMajor != NULL ) {
+ handle_n = dmi_decode(xmlnode, dmiMajor, &h, ver);
+ } else {
+ handle_n = xmlNewChild(xmlnode, NULL, (xmlChar *) "DMImessage", NULL);
+ assert( handle_n != NULL );
+ dmixml_AddTextContent(handle_n, "DMI/SMBIOS type 0x%02X is not supported "
+ "by dmidecode", h.type);
+ dmixml_AddAttribute(handle_n, "type", "%i", h.type);
+ dmixml_AddAttribute(handle_n, "unsupported", "1");
+ }
+ } else {
+ handle_n = xmlNewChild(xmlnode, NULL, (xmlChar *) "DMIerror", NULL);
+ assert( handle_n != NULL );
+ dmixml_AddTextContent(handle_n, "Data is truncated");
+ dmixml_AddAttribute(handle_n, "type", "%i", h.type);
+ dmixml_AddAttribute(handle_n, "truncated", "1");
+ }
+ dmixml_AddAttribute(handle_n, "handle", "0x%04x", h.handle);
+ dmixml_AddAttribute(handle_n, "size", "%d", h.length);
+ decoding_done = 1;
+ }
+ data = next;
+ i++;
+ }
- if(h->length<0x0B) break;
- _val = dmi_system_boot_status(data[0x0A]);
- PyDict_SetItemString(caseData, "Status", _val);
- Py_DECREF(_val);
+ if( decoding_done == 0 ) {
+ xmlNode *handle_n = xmlNewChild(xmlnode, NULL, (xmlChar *) "DMImessage", NULL);
+ assert( handle_n != NULL );
+ dmixml_AddTextContent(handle_n, "DMI/SMBIOS type 0x%02X is not found on this hardware",
+ type);
+ dmixml_AddAttribute(handle_n, "type", "%i", type);
+ dmixml_AddAttribute(handle_n, "notfound", "1");
+ }
- break;
+ if(i != num)
+ fprintf(stderr, "Wrong DMI structures count: %d announced, only %d decoded.\n", num,
+ i);
+ if(data - buf != len)
+ fprintf(stderr,
+ "Wrong DMI structures length: %d bytes announced, structures occupy %d bytes.\n",
+ len, (unsigned int)(data - buf));
- case 33: /* 3.3.34 64-bit Memory Error Information */
- if(h->length<0x1F) break;
-
- _val = dmi_memory_error_type(data[0x04]);
- PyDict_SetItemString(caseData, "Type", _val);
- Py_DECREF(_val);
-
- _val = dmi_memory_error_granularity(data[0x05]);
- PyDict_SetItemString(caseData, "Granularity", _val);
- Py_DECREF(_val);
-
- _val = dmi_memory_error_operation(data[0x06]);
- PyDict_SetItemString(caseData, "Operation", _val);
- Py_DECREF(_val);
-
- _val = dmi_memory_error_syndrome(DWORD(data+0x07));
- PyDict_SetItemString(caseData, "Vendor Syndrome", _val);
- Py_DECREF(_val);
-
- _val = dmi_64bit_memory_error_address(QWORD(data+0x0B));
- PyDict_SetItemString(caseData, "Memory Array Address", _val);
- Py_DECREF(_val);
-
- _val = dmi_64bit_memory_error_address(QWORD(data+0x13));
- PyDict_SetItemString(caseData, "Device Address", _val);
- Py_DECREF(_val);
-
- _val = dmi_32bit_memory_error_address(DWORD(data+0x1B));
- PyDict_SetItemString(caseData, "Resolution", _val);
- Py_DECREF(_val);
-
- break;
-
- case 34: /* 3.3.35 Management Device */
-
- if(h->length<0x0B) break;
- _val = dmi_string_py(h, data[0x04]);
- PyDict_SetItemString(caseData, "Description", _val);
- Py_DECREF(_val);
-
- _val = dmi_management_device_type(data[0x05]);
- PyDict_SetItemString(caseData, "Type", _val);
- Py_DECREF(_val);
-
- _val = PyString_FromFormat("0x%08x", DWORD(data+0x06));
- PyDict_SetItemString(caseData, "Address", _val);
- Py_DECREF(_val);
-
- _val = dmi_management_device_address_type(data[0x0A]);
- PyDict_SetItemString(caseData, "Address Type", _val);
- Py_DECREF(_val);
-
- break;
-
- case 35: /* 3.3.36 Management Device Component */
-
- if(h->length<0x0B) break;
- _val = dmi_string_py(h, data[0x04]);
- PyDict_SetItemString(caseData, "Description", _val);
- Py_DECREF(_val);
-
- _val = PyString_FromFormat("0x%04x", WORD(data+0x05));
- PyDict_SetItemString(caseData, "Management Device Handle", _val);
- Py_DECREF(_val);
-
- _val = PyString_FromFormat("0x%04x", WORD(data+0x07));
- PyDict_SetItemString(caseData, "Component Handle", _val);
- Py_DECREF(_val);
-
- if(WORD(data+0x09)!=0xFFFF) {
- _val = PyString_FromFormat("0x%04x", WORD(data+0x09));
- PyDict_SetItemString(caseData, "Threshold Handle", _val);
- Py_DECREF(_val);
- }
-
- break;
-
- case 36: /* 3.3.37 Management Device Threshold Data */
-
- if(h->length<0x10) break;
- if(WORD(data+0x04)!=0x8000) {
- _val = PyString_FromFormat("%d", (i16)WORD(data+0x04));
- PyDict_SetItemString(caseData, "Lower Non-critical Threshold", _val);
- Py_DECREF(_val);
- }
- if(WORD(data+0x06)!=0x8000) {
- _val = PyString_FromFormat("%d", (i16)WORD(data+0x06));
- PyDict_SetItemString(caseData, "Upper Non-critical Threshold", _val);
- Py_DECREF(_val);
- }
- if(WORD(data+0x08)!=0x8000) {
- _val = PyString_FromFormat("%d", (i16)WORD(data+0x08));
- PyDict_SetItemString(caseData, "Lower Critical Threshold", _val);
- Py_DECREF(_val);
- }
- if(WORD(data+0x0A)!=0x8000) {
- _val = PyString_FromFormat("%d", (i16)WORD(data+0x0A));
- PyDict_SetItemString(caseData, "Upper Critical Threshold", _val);
- Py_DECREF(_val);
- }
- if(WORD(data+0x0C)!=0x8000) {
- _val = PyString_FromFormat("%d", (i16)WORD(data+0x0C));
- PyDict_SetItemString(caseData, "Lower Non-recoverable Threshold", _val);
- Py_DECREF(_val);
- }
- if(WORD(data+0x0E)!=0x8000) {
- _val = PyString_FromFormat("%d", (i16)WORD(data+0x0E));
- PyDict_SetItemString(caseData, "Upper Non-recoverable Threshold", _val);
- Py_DECREF(_val);
- }
-
- break;
-
- case 37: /* 3.3.38 Memory Channel */
-
- if(h->length<0x07) break;
- _val = dmi_memory_channel_type(data[0x04]);
- PyDict_SetItemString(caseData, "Type", _val);
- Py_DECREF(_val);
-
- _val = PyString_FromFormat("%i", data[0x05]);
- PyDict_SetItemString(caseData, "Maximal Load", _val);
- Py_DECREF(_val);
-
- _val = PyString_FromFormat("%i", data[0x06]);
- PyDict_SetItemString(caseData, "Devices", _val);
- Py_DECREF(_val);
-
- if(h->length<0x07+3*data[0x06]) break;
- _val = dmi_memory_channel_devices(data[0x06], data+0x07);
- PyDict_SetItemString(caseData, ">>>", _val);
- Py_DECREF(_val);
-
- break;
-
- case 38: /* 3.3.39 IPMI Device Information */
- /*
- * We use the word "Version" instead of "Revision", conforming to
- * the IPMI specification.
- */
-
- if(h->length<0x10) break;
- _val = dmi_ipmi_interface_type(data[0x04]);
- PyDict_SetItemString(caseData, "Interface Type", _val);
- Py_DECREF(_val);
-
- _val = PyString_FromFormat("%i.%i", data[0x05]>>4, data[0x05]&0x0F);
- PyDict_SetItemString(caseData, "Specification Version", _val);
- Py_DECREF(_val);
-
- _val = PyString_FromFormat("0x%02x", data[0x06]>>1);
- PyDict_SetItemString(caseData, "I2C Slave Address", _val);
- Py_DECREF(_val);
-
- if(data[0x07]!=0xFF) {
- _val = PyString_FromFormat("%i", data[0x07]);
- PyDict_SetItemString(caseData, "NV Storage Device Address", _val);
- Py_DECREF(_val);
- } else {
- _val = Py_None;
- PyDict_SetItemString(caseData, "NV Storage Device: Not Present", _val);
- Py_DECREF(_val);
- }
-
- _val = dmi_ipmi_base_address(data[0x04], data+0x08, h->length<0x12?0:(data[0x10]>>5)&1);
- PyDict_SetItemString(caseData, "Base Address", _val);
- Py_DECREF(_val);
-
- if(h->length<0x12) break;
- if(data[0x04]!=0x04) {
- _val = dmi_ipmi_register_spacing(data[0x10]>>6);
- PyDict_SetItemString(caseData, "Register Spacing", _val);
- Py_DECREF(_val);
-
- if(data[0x10]&(1<<3)) {
- _val = PyString_FromFormat("%s", data[0x10]&(1<<1)?"Active High":"Active Low");
- PyDict_SetItemString(caseData, "Interrupt Polarity", _val);
- Py_DECREF(_val);
-
- _val = PyString_FromFormat("%s", data[0x10]&(1<<0)?"Level":"Edge");
- PyDict_SetItemString(caseData, "Interrupt Trigger Mode", _val);
- Py_DECREF(_val);
- }
- }
- if(data[0x11]!=0x00) {
- _val = PyString_FromFormat("%x", data[0x11]);
- PyDict_SetItemString(caseData, "Interrupt Number", _val);
- Py_DECREF(_val);
- }
- break;
-
- case 39: /* 3.3.40 System Power Supply */
-
- if(h->length<0x10) break;
- if(data[0x04]!=0x00) {
- _val = PyString_FromFormat("%i", data[0x04]);
- PyDict_SetItemString(caseData, "Power Unit Group", _val);
- Py_DECREF(_val);
- }
-
- _val = dmi_string_py(h, data[0x05]);
- PyDict_SetItemString(caseData, "Location", _val);
- Py_DECREF(_val);
-
- _val = dmi_string_py(h, data[0x06]);
- PyDict_SetItemString(caseData, "Name", _val);
- Py_DECREF(_val);
-
- _val = dmi_string_py(h, data[0x07]);
- PyDict_SetItemString(caseData, "Manufacturer", _val);
- Py_DECREF(_val);
-
- _val = dmi_string_py(h, data[0x08]);
- PyDict_SetItemString(caseData, "Serial Numberr", _val);
- Py_DECREF(_val);
-
- _val = dmi_string_py(h, data[0x09]);
- PyDict_SetItemString(caseData, "Asset Tag", _val);
- Py_DECREF(_val);
-
- _val = dmi_string_py(h, data[0x0A]);
- PyDict_SetItemString(caseData, "Model Part Number", _val);
- Py_DECREF(_val);
-
- _val = dmi_string_py(h, data[0x0B]);
- PyDict_SetItemString(caseData, "Revision", _val);
- Py_DECREF(_val);
-
- _val = dmi_power_supply_power(WORD(data+0x0C));
- PyDict_SetItemString(caseData, "Max Power Capacity", _val);
- Py_DECREF(_val);
-
- if(WORD(data+0x0E)&(1<<1)) {
- _val = dmi_power_supply_status((WORD(data+0x0E)>>7)&0x07);
- PyDict_SetItemString(caseData, "Status Present", _val);
- Py_DECREF(_val);
- } else {
- _val = PyString_FromString("Not Present");
- PyDict_SetItemString(caseData, "Status", _val);
- Py_DECREF(_val);
- }
- _val = dmi_power_supply_type((WORD(data+0x0E)>>10)&0x0F);
- PyDict_SetItemString(caseData, "Type", _val);
- Py_DECREF(_val);
-
- _val = dmi_power_supply_range_switching((WORD(data+0x0E)>>3)&0x0F);
- PyDict_SetItemString(caseData, "Input Voltage Range Switching", _val);
- Py_DECREF(_val);
-
- _val = PyString_FromFormat("%s", WORD(data+0x0E)&(1<<2)?"No":"Yes");
- PyDict_SetItemString(caseData, "Plugged", _val);
- Py_DECREF(_val);
-
- _val = PyString_FromFormat("%s", WORD(data+0x0E)&(1<<0)?"Yes":"No");
- PyDict_SetItemString(caseData, "Hot Replaceable", _val);
- Py_DECREF(_val);
-
- if(h->length<0x16) break;
- if(WORD(data+0x10)!=0xFFFF) {
- _val = PyString_FromFormat("0x%04x", WORD(data+0x10));
- PyDict_SetItemString(caseData, "Input Voltage Probe Handle", _val);
- Py_DECREF(_val);
- }
-
- if(WORD(data+0x12)!=0xFFFF) {
- _val = PyString_FromFormat("0x%04x", WORD(data+0x12));
- PyDict_SetItemString(caseData, "Cooling Device Handle", _val);
- Py_DECREF(_val);
- }
-
- if(WORD(data+0x14)!=0xFFFF) {
- _val = PyString_FromFormat("0x%04x", WORD(data+0x14));
- PyDict_SetItemString(caseData, "Input Current Probe Handle", _val);
- Py_DECREF(_val);
- }
-
- break;
-
- case 40: /* 3.3.41 Additional Information */
- if(h->length < 0x0B) break;
- _key = PyString_FromFormat("Additional Information");
- _val = dmi_additional_info(h, "");
- PyDict_SetItem(caseData, _key, _val);
- Py_DECREF(_key);
- Py_DECREF(_val);
- break;
-
- case 41: /* 3.3.42 Onboard Device Extended Information */
- if (h->length < 0x0B) break;
- PyObject *subdata = PyDict_New();
-
- _val = dmi_string_py(h, data[0x04]);
- PyDict_SetItemString(subdata, "Reference Designation", _val);
- Py_DECREF(_val);
-
- _val = PyString_FromString(dmi_on_board_devices_type(data[0x05] & 0x7F));
- PyDict_SetItemString(subdata, "Type", _val);
- Py_DECREF(_val);
-
- _val = PyString_FromString(data[0x05]&0x80 ? "Enabled" : "Disabled");
- PyDict_SetItemString(subdata, "Status", _val);
- Py_DECREF(_val);
-
- _val = PyInt_FromLong(data[0x06]);
- PyDict_SetItemString(subdata, "Type Instance", _val);
- Py_DECREF(_val);
-
- _val = dmi_slot_segment_bus_func(WORD(data + 0x07), data[0x09], data[0x0A]);
- PyDict_SetItemString(subdata, "Bus Address", _val);
- Py_DECREF(_val);
-
- PyDict_SetItemString(caseData, "Onboard Device", subdata);
- Py_DECREF(subdata);
- break;
-
- case 126: /* 3.3.43 Inactive */
- _val = Py_None;
- PyDict_SetItemString(caseData, "Inactive", _val);
- Py_DECREF(_val);
- break;
-
- case 127: /* 3.3.44 End Of Table */
- _val = Py_None;
- PyDict_SetItemString(caseData, "End Of Table", _val);
- Py_DECREF(_val);
- break;
-
- default:
- if(dmi_decode_oem(h)) break;
- _key = PyString_FromFormat("%s Type", h->type>=128?"OEM-specific":"Unknown");
- _val = dmi_dump(h);
- PyDict_SetItem(caseData, _key, _val);
- Py_DECREF(_key);
- Py_DECREF(_val);
- }
-
- Py_INCREF(caseData);
- return caseData;
-}
-
-void to_dmi_header(struct dmi_header *h, u8 *data) {
- h->type=data[0];
- h->length=data[1];
- h->handle=WORD(data+2);
- h->data=data;
-}
-
-static void dmi_table_string_py(const struct dmi_header *h, const u8 *data, PyObject *hDict, u16 ver) {
- int key;
- u8 offset = opt.string->offset;
-
- if (offset >= h->length) return;
-
- //. TODO: These should have more meaningful dictionary names
- key = (opt.string->type << 8) | offset;
- PyObject *_val;
- switch(key) {
- case 0x108:
- _val = dmi_system_uuid_py(data+offset, ver);
- PyDict_SetItemString(hDict, "0x108", _val);
- break;
- case 0x305:
- _val = dmi_chassis_type_py(data[offset]);
- PyDict_SetItemString(hDict, "0x305", _val);
- case 0x406:
- _val = PyString_FromString(dmi_processor_family(h));
- PyDict_SetItemString(hDict, "0x406", _val);
- break;
- case 0x416:
- _val = dmi_processor_frequency_py((u8 *)data + offset);
- PyDict_SetItemString(hDict, "0x416", _val);
- break;
- default:
- _val = dmi_string_py(h, data[offset]);
- PyDict_SetItemString(hDict, "0x???", _val);
- }
- Py_DECREF(_val);
+ free(buf);
}
-/*
-static void dmi_table_dump(u32 base, u16 len, const char *devmem)
+int _smbios_decode_check(u8 * buf)
{
- u8 *buf;
+ int check = (!checksum(buf, buf[0x05]) || memcmp(buf + 0x10, "_DMI_", 5) != 0 ||
+ !checksum(buf + 0x10, 0x0F)) ? 0 : 1;
+ return check;
+}
- if ((buf = mem_chunk(base, len, devmem)) == NULL)
- {
- fprintf(stderr, "Failed to read table, sorry.\n");
- return;
+xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem)
+{
+ int check = _smbios_decode_check(buf);
+
+ xmlNode *data_n = xmlNewNode(NULL, (xmlChar *) "DMIversion");
+ assert( data_n != NULL );
+
+ dmixml_AddAttribute(data_n, "type", "SMBIOS");
+
+ if(check == 1) {
+ u16 ver = (buf[0x06] << 8) + buf[0x07];
+
+ /* Some BIOS report weird SMBIOS version, fix that up */
+ int _m, _M;
+
+ _m = 0;
+ _M = 0;
+ switch (ver) {
+ case 0x021F:
+ _m = 31;
+ _M = 3;
+ ver = 0x0203;
+ break;
+ case 0x0233:
+ _m = 51;
+ _M = 6;
+ ver = 0x0206;
+ break;
+ }
+ if(_m || _M) {
+ dmixml_AddTextContent(data_n, "SMBIOS %i.%i present (Version fixup 2.%d -> 2.%d)",
+ ver >> 8, ver & 0xFF, _m, _M);
+ dmixml_AddAttribute(data_n, "version", "%i.%i", ver >> 8, ver & 0xFF);
+ dmixml_AddAttribute(data_n, "fixup_version", "2.%d_2.%d", _m, _M);
+ } else {
+ dmixml_AddTextContent(data_n, "SMBIOS %i.%i present", ver >> 8, ver & 0xFF);
+ dmixml_AddAttribute(data_n, "version", "%i.%i", ver >> 8, ver & 0xFF);
+ }
+ } else if(check == 0) {
+ dmixml_AddTextContent(data_n, "No SMBIOS nor DMI entry point found");
+ dmixml_AddAttribute(data_n, "unknown", "1");
}
+ return data_n;
+}
- printf("# Writing %d bytes to %s.\n", len, PyString_AS_STRING(opt.dumpfile));
- write_dump(32, len, buf, PyString_AS_STRING(opt.dumpfile), 0);
- free(buf);
+int smbios_decode(int type, u8 *buf, const char *devmem, xmlNode *xmlnode)
+{
+ int check = _smbios_decode_check(buf);
+
+ if(check == 1) {
+ u16 ver = (buf[0x06] << 8) + buf[0x07];
+
+ switch (ver) {
+ case 0x021F:
+ ver = 0x0203;
+ break;
+ case 0x0233:
+ ver = 0x0206;
+ break;
+ }
+ //printf(">>%d @ %d, %d<<\n", DWORD(buf+0x18), WORD(buf+0x16), WORD(buf+0x1C));
+ dmi_table(type, DWORD(buf + 0x18), WORD(buf + 0x16), WORD(buf + 0x1C), ver, devmem,
+ xmlnode);
+ }
+ return check;
}
-*/
-/*
- * Build a crafted entry point with table address hard-coded to 32,
- * as this is where we will put it in the output file. We adjust the
- * DMI checksum appropriately. The SMBIOS checksum needs no adjustment.
- */
-static void overwrite_dmi_address(u8 *buf) {
- buf[0x05] += buf[0x08] + buf[0x09] + buf[0x0A] + buf[0x0B] - 32;
- buf[0x08] = 32;
- buf[0x09] = 0;
- buf[0x0A] = 0;
- buf[0x0B] = 0;
-}
-
-
-#define NON_LEGACY 0
-#define LEGACY 1
-int dumpling(u8 *buf, const char *dumpfile, u8 mode) {
- u32 base;
- u16 len;
- if(mode == NON_LEGACY) {
- if(!checksum(buf, buf[0x05]) || !memcmp(buf+0x10, "_DMI_", 5)==0 || !checksum(buf+0x10, 0x0F)) return 0;
- base = DWORD(buf+0x18);
- len = WORD(buf+0x16);
- } else {
- if(!checksum(buf, 0x0F)) return 0;
- base = DWORD(buf+0x08);
- len = WORD(buf+0x06);
- }
-
- u8 *buff;
- if((buff = mem_chunk(base, len, DEFAULT_MEM_DEV)) != NULL) {
- //. Part 1.
- printf("# Writing %d bytes to %s.\n", len, dumpfile);
- write_dump(32, len, buff, dumpfile, 0);
- free(buff);
-
- //. Part 2.
- if(mode != LEGACY) {
- u8 crafted[32];
- memcpy(crafted, buf, 32);
- overwrite_dmi_address(crafted+0x10);
- printf("# Writing %d bytes to %s.\n", crafted[0x05], dumpfile);
- write_dump(0, crafted[0x05], crafted, dumpfile, 1);
- } else {
- u8 crafted[16];
- memcpy(crafted, buf, 16);
- overwrite_dmi_address(crafted);
- printf("# Writing %d bytes to %s.\n", 0x0F, dumpfile);
- write_dump(0, 0x0F, crafted, dumpfile, 1);
- }
- } else {
- fprintf(stderr, "Failed to read table, sorry.\n");
- }
-
- //. TODO: Cleanup
- return 1;
-}
-
-int dump(const char *dumpfile) {
- /* On success, return found, otherwise return -1 */
- int ret=0;
- int found=0;
- size_t fp;
- int efi;
- u8 *buf;
-
- /* First try EFI (ia64, Intel-based Mac) */
- efi = address_from_efi(&fp);
- if(efi == EFI_NOT_FOUND) {
- /* Fallback to memory scan (x86, x86_64) */
- if((buf=mem_chunk(0xF0000, 0x10000, DEFAULT_MEM_DEV))!=NULL) {
- for(fp=0; fp<=0xFFF0; fp+=16) {
- if(memcmp(buf+fp, "_SM_", 4)==0 && fp<=0xFFE0) {
- if(dumpling(buf+fp, dumpfile, NON_LEGACY)) found++;
- fp+=16;
- } else if(memcmp(buf+fp, "_DMI_", 5)==0) {
- if(dumpling(buf+fp, dumpfile, LEGACY)) found++;
- }
- }
- } else ret = -1;
- } else if(efi == EFI_NO_SMBIOS) {
- ret = -1;
- } else {
- if((buf=mem_chunk(fp, 0x20, DEFAULT_MEM_DEV))==NULL) ret = -1;
- else if(dumpling(buf, dumpfile, NON_LEGACY)) found++;
- }
-
- if(ret==0) {
- free(buf);
-
- //. TODO: Exception
- //dmiSetItem(pydata, "detect", "No SMBIOS nor DMI entry point found, sorry G.");
- if(!found) ret = -1;
- }
-
- return ret==0?found:ret;
-}
-
-
-
-static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, PyObject *pydata) {
- u8 *buf;
- u8 *data;
- int i=0;
-
- if(opt.type==NULL) {
- dmiSetItem(pydata, "dmi_table_size", "%i structures occupying %i bytes", num, len);
- /* TODO DUMP
- if (!(opt.flags & FLAG_FROM_DUMP))
- dmiSetItem(pydata, "dmi_table_base", "Table at 0x%08x", base);
- */
- dmiSetItem(pydata, "dmi_table_base", "Table at 0x%08x", base);
- }
-
- if((buf=mem_chunk(base, len, devmem))==NULL) {
- fprintf(stderr, "Table is unreachable, sorry."
-#ifndef USE_MMAP
- "Try compiling dmidecode with -DUSE_MMAP.";
-#endif
- "\n");
- return;
- }
-
- data=buf;
- while(i<num && data+4<=buf+len) /* 4 is the length of an SMBIOS structure header */ {
-
- u8 *next;
- struct dmi_header h;
- int display;
-
- to_dmi_header(&h, data);
- display=((opt.type==NULL || opt.type[h.type])
-// && !(h.type>39 && h.type<=127)
- && !opt.string);
-
- /*
- ** If a short entry is found (less than 4 bytes), not only it
- ** is invalid, but we cannot reliably locate the next entry.
- ** Better stop at this point, and let the user know his/her
- ** table is broken.
- */
- if(h.length<4) {
- fprintf(stderr, "Invalid entry length (%i). DMI table is broken! Stop.", (unsigned int)h.length);
- break;
- }
-
- /* In quiet mode (FLAG_QUIET - removed for python-dmidecode all together), stop decoding at end of table marker */
-
- char hid[7];
- sprintf(hid, "0x%04x", h.handle);
- PyObject *hDict = PyDict_New();
- dmiSetItem(hDict, "dmi_handle", hid);
- dmiSetItem(hDict, "dmi_type", "%d", h.type);
- dmiSetItem(hDict, "dmi_size", "%d", h.length);
-
- /* assign vendor for vendor-specific decodes later */
- if(h.type==0 && h.length>=5)
- dmi_set_vendor(dmi_string(&h, data[0x04]));
-
- /* look for the next handle */
- next=data+h.length;
- while(next-buf+1<len && (next[0]!=0 || next[1]!=0))
- next++;
-
- next+=2;
-
- if(display) {
- if(next-buf<=len) {
- /* TODO: ...
- if(opt.flags & FLAG_DUMP) {
- PyDict_SetItem(hDict, PyString_FromString("lookup"), dmi_dump(&h));
- } else {
- //. TODO: //. Is the value of `i' important?...
- //. TODO: PyDict_SetItem(hDict, PyInt_FromLong(i), dmi_decode(&h, ver));
- //. TODO: ...removed and replaced with `data'...
- PyDict_SetItem(hDict, PyString_FromString("data"), dmi_decode(&h, ver));
- PyDict_SetItem(pydata, PyString_FromString(hid), hDict);
- }*/
- PyDict_SetItem(hDict, PyString_FromString("data"), dmi_decode(&h, ver));
- PyDict_SetItem(pydata, PyString_FromString(hid), hDict);
- } else fprintf(stderr, "<TRUNCATED>");
- } else if(opt.string!=NULL && opt.string->type==h.type) {
- dmi_table_string_py(&h, data, hDict, ver);
- }
-
- data=next;
- i++;
- }
-
- if(i!=num)
- fprintf(stderr, "Wrong DMI structures count: %d announced, only %d decoded.\n", num, i);
- if(data-buf!=len)
- fprintf(stderr, "Wrong DMI structures length: %d bytes announced, structures occupy %d bytes.\n",
- len, (unsigned int)(data-buf));
-
- free(buf);
-}
-
-
-
-
-int _smbios_decode_check(u8 *buf) {
- int check = (!checksum(buf, buf[0x05]) || memcmp(buf + 0x10, "_DMI_", 5)!=0 || !checksum(buf+0x10, 0x0F)) ? 0 : 1;
- return check;
-}
-int smbios_decode_set_version(u8 *buf, const char *devmem, PyObject** pydata) {
- int check = _smbios_decode_check(buf);
- char vbuf[64]; bzero(vbuf, 64);
- if(check == 1) {
- u16 ver = (buf[0x06] << 8) + buf[0x07];
- /* Some BIOS report weird SMBIOS version, fix that up */
- int _m, _M;
- _m = 0;
- _M = 0;
- switch(ver) {
- case 0x021F:
- _m = 31;
- _M = 3;
- ver = 0x0203;
- break;
- case 0x0233:
- _m = 51;
- _M = 6;
- ver = 0x0206;
- break;
- }
- if(_m || _M) sprintf(vbuf, "SMBIOS %i.%i present (Version fixup 2.%d -> 2.%d)", ver>>8, ver&0xFF, _m, _M);
- else sprintf(vbuf, "SMBIOS %i.%i present", ver>>8, ver&0xFF);
- } else if(check == 0) {
- sprintf(vbuf, "No SMBIOS nor DMI entry point found");
- }
- if(check == 1) {
- if(*pydata) { Py_DECREF(*pydata); }
- *pydata = PyString_FromString(vbuf);
- Py_INCREF(*pydata);
- }
- return check;
-}
-int smbios_decode(u8 *buf, const char *devmem, PyObject* pydata) {
- int check = _smbios_decode_check(buf);
- if(check == 1) {
- u16 ver = (buf[0x06] << 8) + buf[0x07];
- switch(ver) {
- case 0x021F:
- ver = 0x0203;
- break;
- case 0x0233:
- ver = 0x0206;
- break;
- }
- //printf(">>%d @ %d, %d<<\n", DWORD(buf+0x18), WORD(buf+0x16), WORD(buf+0x1C));
- dmi_table(DWORD(buf+0x18), WORD(buf+0x16), WORD(buf+0x1C), ver, devmem, pydata);
- }
- return check;
-}
-
-
-
-
-int _legacy_decode_check(u8 *buf) {
- int check;
- if(!checksum(buf, 0x0F)) check = 0; //. Bad
- else check = 1; //. Good
- return check;
-}
-int legacy_decode_set_version(u8 *buf, const char *devmem, PyObject** pydata) {
- int check = _legacy_decode_check(buf);
- char vbuf[64]; bzero(vbuf, 64);
- if(check == 1) {
- sprintf(vbuf, "Legacy DMI %i.%i present", buf[0x0E]>>4, buf[0x0E]&0x0F);
- } else if(check == 0) {
- sprintf(vbuf, "No SMBIOS nor DMI entry point found");
- }
- if(check == 1) {
- if(*pydata) { Py_DECREF(*pydata); }
- *pydata = PyString_FromString(vbuf);
- Py_INCREF(*pydata);
- }
- return check;
-}
-int legacy_decode(u8 *buf, const char *devmem, PyObject* pydata) {
- int check = _legacy_decode_check(buf);
- if(check == 1)
- dmi_table(DWORD(buf+0x08), WORD(buf+0x06), WORD(buf+0x0C), ((buf[0x0E]&0xF0)<<4)+(buf[0x0E]&0x0F), devmem, pydata);
- return check;
+int _legacy_decode_check(u8 * buf)
+{
+ int check;
+
+ if(!checksum(buf, 0x0F))
+ check = 0; //. Bad
+ else
+ check = 1; //. Good
+ return check;
}
+xmlNode *legacy_decode_get_version(u8 * buf, const char *devmem)
+{
+ int check = _legacy_decode_check(buf);
+
+ xmlNode *data_n = xmlNewNode(NULL, (xmlChar *) "DMIversion");
+ assert( data_n != NULL );
+ dmixml_AddAttribute(data_n, "type", "legacy");
+ if(check == 1) {
+ dmixml_AddTextContent(data_n, "Legacy DMI %i.%i present",
+ buf[0x0E] >> 4, buf[0x0E] & 0x0F);
+ dmixml_AddAttribute(data_n, "version", "%i.%i",
+ buf[0x0E] >> 4, buf[0x0E] & 0x0F);
+ } else if(check == 0) {
+ dmixml_AddTextContent(data_n, "No SMBIOS nor DMI entry point found");
+ dmixml_AddAttribute(data_n, "unknown", "1");
+ }
-/*******************************************************************************
-** Probe for EFI interface
-*/
-int address_from_efi(size_t *address) {
- FILE *efi_systab;
- const char *filename;
- char linebuf[64];
- int ret;
-
- *address = 0; /* Prevent compiler warning */
-
- /*
- ** Linux <= 2.6.6: /proc/efi/systab
- ** Linux >= 2.6.7: /sys/firmware/efi/systab
- */
- if((efi_systab=fopen(filename="/sys/firmware/efi/systab", "r"))==NULL
- && (efi_systab=fopen(filename="/proc/efi/systab", "r"))==NULL) {
- /* No EFI interface, fallback to memory scan */
- return EFI_NOT_FOUND;
- }
- ret=EFI_NO_SMBIOS;
- while((fgets(linebuf, sizeof(linebuf)-1, efi_systab))!=NULL) {
- char *addrp=strchr(linebuf, '=');
- *(addrp++)='\0';
- if(strcmp(linebuf, "SMBIOS")==0) {
- *address=strtoul(addrp, NULL, 0);
- printf("# SMBIOS entry point at 0x%08lx\n", (unsigned long)*address);
- ret=0;
- break;
- }
- }
- if(fclose(efi_systab)!=0)
- perror(filename);
-
- if(ret==EFI_NO_SMBIOS)
- fprintf(stderr, "%s: SMBIOS entry point missing\n", filename);
-
- return ret;
+ return data_n;
}
+
+int legacy_decode(int type, u8 *buf, const char *devmem, xmlNode *xmlnode)
+{
+ int check = _legacy_decode_check(buf);
+
+ if(check == 1)
+ dmi_table(type, DWORD(buf + 0x08), WORD(buf + 0x06), WORD(buf + 0x0C),
+ ((buf[0x0E] & 0xF0) << 4) + (buf[0x0E] & 0x0F), devmem, xmlnode);
+ return check;
+}
+
diff --git a/src/dmidecode.h b/src/dmidecode.h
index 7e99faa..10412c6 100644
--- a/src/dmidecode.h
+++ b/src/dmidecode.h
@@ -1,3 +1,4 @@
+
/*
* This file is part of the dmidecode project.
*
@@ -17,29 +18,27 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <Python.h>
+
+#include <libxml/tree.h>
+#include "dmihelper.h"
struct dmi_header {
- u8 type;
- u8 length;
- u16 handle;
- u8 *data;
+ u8 type;
+ u8 length;
+ u16 handle;
+ u8 *data;
};
-PyObject *dmi_dump(struct dmi_header *h);
-PyObject* dmi_decode(struct dmi_header *h, u16 ver);
-int address_from_efi(size_t *address);
-void to_dmi_header(struct dmi_header *h, u8 *data);
-int smbios_decode_set_version(u8 *buf, const char *devmem, PyObject** pydata);
-int smbios_decode(u8 *buf, const char *devmem, PyObject* pydata);
-int legacy_decode_set_version(u8 *buf, const char *devmem, PyObject** pydata);
-int legacy_decode(u8 *buf, const char *devmem, PyObject* pydata);
+void dmi_dump(xmlNode *node, struct dmi_header * h);
+xmlNode *dmi_decode(xmlNode *parent_n, dmi_codes_major *dmiMajor, struct dmi_header * h, u16 ver);
+void to_dmi_header(struct dmi_header *h, u8 * data);
-const char *dmi_string(const struct dmi_header *dm, u8 s);
-const char *dmi_system_uuid(u8 *p);
-PyObject *dmi_system_uuid_py(const u8 *p, u16 ver);
-const char *dmi_chassis_type(u8 code);
-int dmi_processor_frequency(const u8 *p);
+xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem);
+xmlNode *legacy_decode_get_version(u8 * buf, const char *devmem);
+int smbios_decode(int type, u8 *buf, const char *devmem, xmlNode *xmlnode);
+int legacy_decode(int type, u8 *buf, const char *devmem, xmlNode *xmlnode);
-int dump(const char *dumpfile);
-int dumpling(u8 *buf, const char *devmem, u8 mode);
+const char *dmi_string(const struct dmi_header *dm, u8 s);
+void dmi_system_uuid(xmlNode *node, const u8 * p, u16 ver);
+void dmi_chassis_type(xmlNode *node, u8 code);
+int dmi_processor_frequency(const u8 * p);
diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c
index 345b151..5c74124 100644
--- a/src/dmidecodemodule.c
+++ b/src/dmidecodemodule.c
@@ -1,305 +1,731 @@
+
+/*. ******* coding:utf-8 AUTOHEADER START v1.1 *******
+ *. vim: fileencoding=utf-8 syntax=c sw=8 ts=8 et
+ *.
+ *. © 2007-2009 Nima Talebi <nima@autonomy.net.au>
+ *. © 2009 David Sommerseth <davids@redhat.com>
+ *. © 2002-2008 Jean Delvare <khali@linux-fr.org>
+ *. © 2000-2002 Alan Cox <alan@redhat.com>
+ *.
+ *. This file is part of Python DMI-Decode.
+ *.
+ *. Python DMI-Decode 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, either version 2 of the License, or
+ *. (at your option) any later version.
+ *.
+ *. Python DMI-Decode is distributed in the hope that it will be useful,
+ *. but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *. GNU General Public License for more details.
+ *.
+ *. You should have received a copy of the GNU General Public License
+ *. along with Python DMI-Decode. If not, see <http://www.gnu.org/licenses/>.
+ *.
+ *. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *. WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *. MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ *. EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ *. PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ *. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ *. OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ *. ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *.
+ *. ADAPTED M. STONE & T. PARKER DISCLAIMER: THIS SOFTWARE COULD RESULT IN INJURY
+ *. AND/OR DEATH, AND AS SUCH, IT SHOULD NOT BE BUILT, INSTALLED OR USED BY ANYONE.
+ *.
+ *. $AutoHeaderSerial::20090522 $
+ *. ******* AUTOHEADER END v1.1 ******* */
+
+#include <Python.h>
+
+#include <libxml/tree.h>
+#include "libxml_wrap.h"
+
+#include "xmlpythonizer.h"
#include "dmidecodemodule.h"
+#include "dmixml.h"
+#include "dmierror.h"
+#include "version.h"
+#include "dmidump.h"
#include <mcheck.h>
-options opt;
-static void init(void) {
- /* sanity check */
- if(sizeof(u8)!=1 || sizeof(u16)!=2 || sizeof(u32)!=4 || '\0'!=0)
- fprintf(stderr, "%s: compiler incompatibility\n", "dmidecodemodule");
+static void init(options *opt)
+{
+ /* sanity check */
+ if(sizeof(u8) != 1 || sizeof(u16) != 2 || sizeof(u32) != 4 || '\0' != 0)
+ fprintf(stderr, "%s: compiler incompatibility\n", "dmidecodemodule");
+
+ opt->devmem = DEFAULT_MEM_DEV;
+ opt->dumpfile = NULL;
+ opt->flags = 0;
+ opt->type = -1;
+ opt->dmiversion_n = NULL;
+ opt->mappingxml = NULL;
+ opt->python_xml_map = strdup(PYTHON_XML_MAP);
+}
- opt.devmem = DEFAULT_MEM_DEV;
- opt.dumpfile = NULL;
- opt.flags=0;
- opt.type = NULL;
+int parse_opt_type(const char *arg)
+{
+ while(*arg != '\0') {
+ int val;
+ char *next;
+
+ val = strtoul(arg, &next, 0);
+ if(next == arg) {
+ fprintf(stderr, "Invalid type keyword: %s\n", arg);
+ return -1;
+ }
+ if(val > 0xff) {
+ fprintf(stderr, "Invalid type number: %i\n", val);
+ return -1;
+ }
+
+ if( val >= 0 ) {
+ return val;
+ }
+ arg = next;
+ while(*arg == ',' || *arg == ' ')
+ arg++;
+ }
+ return -1;
}
-u8 *parse_opt_type(u8 *p, const char *arg) {
-
- /* Allocate memory on first call only */
- if(p == NULL) {
- if(!(p = (u8 *)calloc(256, sizeof(u8)))) {
- perror("calloc");
- return NULL;
- }
- }
-
- unsigned int i, j;
- /* First try as a keyword */
- for(i = 0; i < ARRAY_SIZE(opt_type_keyword); i++) {
- if(!strcasecmp(arg, opt_type_keyword[i].keyword)) {
- j = 0;
- while(opt_type_keyword[i].type[j] != 255)
- p[opt_type_keyword[i].type[j++]] = 1;
- return p;
- }
- }
-
- /* Else try as a number */
- while(*arg != '\0') {
- unsigned long val;
- char *next;
-
- val = strtoul(arg, &next, 0);
- if(next == arg) {
- fprintf(stderr, "Invalid type keyword: %s\n", arg);
- free(p);
- return NULL;
- }
- if (val > 0xff) {
- fprintf(stderr, "Invalid type number: %lu\n", val);
- free(p);
- return NULL;
- }
-
- p[val] = 1;
- arg = next;
- while(*arg == ',' || *arg == ' ')
- arg++;
- }
-
- return p;
+xmlNode *dmidecode_get_version(options *opt)
+{
+ int found = 0;
+ size_t fp;
+ int efi;
+ u8 *buf = NULL;
+ xmlNode *ver_n = NULL;
+
+ /* Set default option values */
+ if( opt->devmem == NULL ) {
+ opt->devmem = DEFAULT_MEM_DEV;
+ }
+
+ /* Read from dump if so instructed */
+ if(opt->dumpfile != NULL) {
+ //. printf("Reading SMBIOS/DMI data from file %s.\n", dumpfile);
+ if((buf = mem_chunk(0, 0x20, opt->dumpfile)) != NULL) {
+ if(memcmp(buf, "_SM_", 4) == 0) {
+ ver_n = smbios_decode_get_version(buf, opt->dumpfile);
+ if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) {
+ found++;
+ }
+ } else if(memcmp(buf, "_DMI_", 5) == 0) {
+ ver_n = legacy_decode_get_version(buf, opt->dumpfile);
+ if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) {
+ found++;
+ }
+ }
+ }
+ } else { /* Read from /dev/mem */
+ /* First try EFI (ia64, Intel-based Mac) */
+ efi = address_from_efi(&fp);
+ if(efi == EFI_NOT_FOUND) {
+ /* Fallback to memory scan (x86, x86_64) */
+ if((buf = mem_chunk(0xF0000, 0x10000, opt->devmem)) != NULL) {
+ for(fp = 0; fp <= 0xFFF0; fp += 16) {
+ if(memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0) {
+ ver_n = smbios_decode_get_version(buf + fp, opt->devmem);
+ if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) {
+ found++;
+ }
+ fp += 16;
+ } else if(memcmp(buf + fp, "_DMI_", 5) == 0) {
+ ver_n = legacy_decode_get_version (buf + fp, opt->devmem);
+ if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) {
+ found++;
+ }
+ }
+ }
+ }
+ } else if(efi == EFI_NO_SMBIOS) {
+ ver_n = NULL;
+ } else {
+ // Process as EFI
+ if((buf = mem_chunk(fp, 0x20, opt->devmem)) != NULL) {
+ ver_n = smbios_decode_get_version(buf, opt->devmem);
+ if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) {
+ found++;
+ }
+ //. TODO: dmixml_AddAttribute(dmixml_n, "efi_address", efiAddress);
+ }
+ }
+ }
+ if( buf != NULL ) {
+ free(buf);
+ }
+ if( !found ) {
+ fprintf(stderr, "No SMBIOS nor DMI entry point found, sorry.");
+ }
+ return ver_n;
}
+int dmidecode_get_xml(options *opt, xmlNode* dmixml_n)
+{
+ assert(dmixml_n != NULL);
+ if(dmixml_n == NULL) {
+ return 0;
+ }
+ //mtrace();
+
+ int ret = 0;
+ int found = 0;
+ size_t fp;
+ int efi;
+ u8 *buf = NULL;
+
+ const char *f = opt->dumpfile ? opt->dumpfile : opt->devmem;
+ if(access(f, R_OK) < 0) {
+ fprintf(stderr, "Permission denied to memory file/device (%s)", f);
+ return 0;
+ }
+
+ /* Read from dump if so instructed */
+ if(opt->dumpfile != NULL) {
+ // printf("Reading SMBIOS/DMI data from file %s.\n", dumpfile);
+ if((buf = mem_chunk(0, 0x20, opt->dumpfile)) != NULL) {
+ if(memcmp(buf, "_SM_", 4) == 0) {
+ if(smbios_decode(opt->type, buf, opt->dumpfile, dmixml_n))
+ found++;
+ } else if(memcmp(buf, "_DMI_", 5) == 0) {
+ if(legacy_decode(opt->type, buf, opt->dumpfile, dmixml_n))
+ found++;
+ }
+ } else {
+ ret = 1;
+ }
+ } else { /* Read from /dev/mem */
+ /* First try EFI (ia64, Intel-based Mac) */
+ efi = address_from_efi(&fp);
+ if(efi == EFI_NOT_FOUND) {
+ /* Fallback to memory scan (x86, x86_64) */
+ if((buf = mem_chunk(0xF0000, 0x10000, opt->devmem)) != NULL) {
+ for(fp = 0; fp <= 0xFFF0; fp += 16) {
+ if(memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0) {
+ if(smbios_decode(opt->type, buf + fp, opt->devmem, dmixml_n)) {
+ found++;
+ fp += 16;
+ }
+ } else if(memcmp(buf + fp, "_DMI_", 5) == 0) {
+ if(legacy_decode(opt->type, buf + fp, opt->devmem, dmixml_n))
+ found++;
+ }
+ }
+ } else
+ ret = 1;
+ } else if(efi == EFI_NO_SMBIOS) {
+ ret = 1;
+ } else {
+ if((buf = mem_chunk(fp, 0x20, opt->devmem)) == NULL)
+ ret = 1;
+ else if(smbios_decode(opt->type, buf, opt->devmem, dmixml_n))
+ found++;
+ // TODO: dmixml_AddAttribute(dmixml_n, "efi_address", "0x%08x", efiAddress);
+ }
+ }
+ if(ret == 0) {
+ free(buf);
+ }
+ //muntrace();
+ return ret;
+}
-static int dmidecode_set_version(PyObject** pydata) {
- int ret=0;
- int found=0;
- size_t fp;
- int efi;
- u8 *buf;
-
- /* Set default option values */
- opt.devmem = DEFAULT_MEM_DEV;
-
- /***********************************/
- /* Read from dump if so instructed */
- if(opt.dumpfile != NULL) {
- const char *dumpfile = PyString_AS_STRING(opt.dumpfile);
- //. printf("Reading SMBIOS/DMI data from file %s.\n", dumpfile);
- if((buf = mem_chunk(0, 0x20, dumpfile))!=NULL) {
- if(memcmp(buf, "_SM_", 4)==0) {
- if(smbios_decode_set_version(buf, dumpfile, pydata)) found++;
- } else if (memcmp(buf, "_DMI_", 5)==0) {
- if(legacy_decode_set_version(buf, dumpfile, pydata)) found++;
- }
- } else ret = 1;
- } else { /* Read from /dev/mem */
- /* First try EFI (ia64, Intel-based Mac) */
- efi = address_from_efi(&fp);
- if(efi == EFI_NOT_FOUND) {
- /* Fallback to memory scan (x86, x86_64) */
- if((buf=mem_chunk(0xF0000, 0x10000, opt.devmem))!=NULL) {
- for(fp=0; fp<=0xFFF0; fp+=16) {
- if(memcmp(buf+fp, "_SM_", 4)==0 && fp<=0xFFE0) {
- if(smbios_decode_set_version(buf+fp, opt.devmem, pydata)) found++;
- fp+=16;
- } else if(memcmp(buf+fp, "_DMI_", 5)==0) {
- if(legacy_decode_set_version(buf+fp, opt.devmem, pydata)) found++;
- }
- }
- } else ret = 1;
- } else if(efi == EFI_NO_SMBIOS) {
- ret = 1;
- } else {
- if((buf=mem_chunk(fp, 0x20, opt.devmem))==NULL) ret = 1;
- else if(smbios_decode_set_version(buf, opt.devmem, pydata)) found++;
- //. TODO: dmiSetItem(pydata, "efi_address", efiAddress);
- }
- }
-
- if(ret==0) {
- free(buf);
- if(!found) {
- fprintf(stderr, "No SMBIOS nor DMI entry point found, sorry G.");
- }
- }
- free(opt.type);
- return ret;
+xmlNode* load_mappingxml(options *opt) {
+ if( opt->mappingxml == NULL ) {
+ // Load mapping into memory
+ opt->mappingxml = xmlReadFile(opt->python_xml_map, NULL, 0);
+ if( opt->mappingxml == NULL ) {
+ PyReturnError(PyExc_IOError, "Could not open tje XML mapping file '%s'",
+ opt->python_xml_map);
+ }
+ }
+ return dmiMAP_GetRootElement(opt->mappingxml);
}
+xmlNode *__dmidecode_xml_getsection(options *opt, const char *section) {
+ xmlNode *dmixml_n = NULL;
+ xmlNode *group_n = NULL;
+
+ dmixml_n = xmlNewNode(NULL, (xmlChar *) "dmidecode");
+ assert( dmixml_n != NULL );
+ // Append DMI version info
+ if( opt->dmiversion_n != NULL ) {
+ xmlAddChild(dmixml_n, xmlCopyNode(opt->dmiversion_n, 1));
+ }
+
+ // Fetch the Mapping XML file
+ if( (group_n = load_mappingxml(opt)) == NULL) {
+ // Exception already set by calling function
+ return NULL;
+ }
+
+ // Find the section in the XML containing the group mappings
+ if( (group_n = dmixml_FindNode(group_n, "GroupMapping")) == NULL ) {
+ PyReturnError(PyExc_LookupError,
+ "Could not find the GroupMapping section in the XML mapping");
+ }
+
+ // Find the XML node containing the Mapping section requested to be decoded
+ if( (group_n = dmixml_FindNodeByAttr(group_n, "Mapping", "name", section)) == NULL ) {
+ PyReturnError(PyExc_LookupError,
+ "Could not find the XML->Python Mapping section for '%s'", section);
+ }
+
+ if( group_n->children == NULL ) {
+ PyReturnError(PyExc_RuntimeError,
+ "Mapping is empty for the '%s' section in the XML mapping", section);
+ }
-static PyObject* dmidecode_get(PyObject *self, const char* section) {
- //mtrace();
-
- int ret=0;
- int found=0;
- size_t fp;
- int efi;
- u8 *buf;
-
- /* Set default option values */
- opt.devmem = DEFAULT_MEM_DEV;
- opt.flags = 0;
- opt.type = NULL;
- opt.type = parse_opt_type(opt.type, section);
- if(opt.type==NULL) return NULL;
-
- const char *f = opt.dumpfile ? PyString_AsString(opt.dumpfile) : opt.devmem;
- if(access(f, R_OK) < 0)
- PyErr_SetString(PyExc_IOError, "Permission denied to memory file/device");
-
- PyObject* pydata = PyDict_New();
-
- /***********************************/
- /* Read from dump if so instructed */
- if(opt.dumpfile != NULL) {
- const char *dumpfile = PyString_AS_STRING(opt.dumpfile);
- //. printf("Reading SMBIOS/DMI data from file %s.\n", dumpfile);
- if((buf = mem_chunk(0, 0x20, dumpfile))!=NULL) {
- if(memcmp(buf, "_SM_", 4)==0) {
- if(smbios_decode(buf, dumpfile, pydata)) found++;
- } else if (memcmp(buf, "_DMI_", 5)==0) {
- if(legacy_decode(buf, dumpfile, pydata)) found++;
- }
- } else ret = 1;
- } else { /* Read from /dev/mem */
- /* First try EFI (ia64, Intel-based Mac) */
- efi = address_from_efi(&fp);
- if(efi == EFI_NOT_FOUND) {
- /* Fallback to memory scan (x86, x86_64) */
- if((buf=mem_chunk(0xF0000, 0x10000, opt.devmem))!=NULL) {
- for(fp=0; fp<=0xFFF0; fp+=16) {
- if(memcmp(buf+fp, "_SM_", 4)==0 && fp<=0xFFE0) {
- if(smbios_decode(buf+fp, opt.devmem, pydata)) {
- found++;
- fp+=16;
- }
- } else if(memcmp(buf+fp, "_DMI_", 5)==0) {
- if(legacy_decode(buf+fp, opt.devmem, pydata)) found++;
- }
- }
- } else ret = 1;
- } else if(efi == EFI_NO_SMBIOS) {
- ret = 1;
- } else {
- if((buf=mem_chunk(fp, 0x20, opt.devmem))==NULL) ret = 1;
- else if(smbios_decode(buf, opt.devmem, pydata)) found++;
- //. TODO: dmiSetItem(pydata, "efi_address", efiAddress);
- }
- }
-
- free(opt.type);
- if(ret==0) {
- free(buf);
- } else {
- Py_DECREF(pydata);
- pydata = NULL;
- }
-
- //muntrace();
- return pydata;
+ // Go through all TypeMap's belonging to this Mapping section
+ foreach_xmlnode(dmixml_FindNode(group_n, "TypeMap"), group_n) {
+ char *typeid = dmixml_GetAttrValue(group_n, "id");
+
+ if( group_n->type != XML_ELEMENT_NODE ) {
+ continue;
+ }
+
+ // The children of <Mapping> tags must only be <TypeMap> and
+ // they must have an 'id' attribute
+ if( (typeid == NULL) || (xmlStrcmp(group_n->name, (xmlChar *) "TypeMap") != 0) ) {
+ PyReturnError(PyExc_RuntimeError, "Invalid TypeMap node in mapping XML");
+ }
+
+ // Parse the typeid string to a an integer
+ opt->type = parse_opt_type(typeid);
+ if(opt->type == -1) {
+ PyReturnError(PyExc_RuntimeError, "Invalid type id '%s'", typeid);
+ }
+
+ // Parse the DMI data and put the result into dmixml_n node chain.
+ if( dmidecode_get_xml(opt, dmixml_n) != 0 ) {
+ PyReturnError(PyExc_RuntimeError, "Error decoding DMI data");
+ }
+ }
+#if 0 // DEBUG - will dump generated XML to stdout
+ xmlDoc *doc = xmlNewDoc((xmlChar *) "1.0");
+ xmlDocSetRootElement(doc, xmlCopyNode(dmixml_n, 1));
+ xmlSaveFormatFileEnc("-", doc, "UTF-8", 1);
+ xmlFreeDoc(doc);
+#endif
+ return dmixml_n;
}
-static PyObject* dmidecode_get_bios(PyObject *self, PyObject *args) { return dmidecode_get(self, "bios"); }
-static PyObject* dmidecode_get_system(PyObject *self, PyObject *args) { return dmidecode_get(self, "system"); }
-static PyObject* dmidecode_get_baseboard(PyObject *self, PyObject *args) { return dmidecode_get(self, "baseboard"); }
-static PyObject* dmidecode_get_chassis(PyObject *self, PyObject *args) { return dmidecode_get(self, "chassis"); }
-static PyObject* dmidecode_get_processor(PyObject *self, PyObject *args) { return dmidecode_get(self, "processor"); }
-static PyObject* dmidecode_get_memory(PyObject *self, PyObject *args) { return dmidecode_get(self, "memory"); }
-static PyObject* dmidecode_get_cache(PyObject *self, PyObject *args) { return dmidecode_get(self, "cache"); }
-static PyObject* dmidecode_get_connector(PyObject *self, PyObject *args) { return dmidecode_get(self, "connector"); }
-static PyObject* dmidecode_get_slot(PyObject *self, PyObject *args) { return dmidecode_get(self, "slot"); }
-static PyObject* dmidecode_get_type(PyObject *self, PyObject *args) {
- long unsigned int lu;
- if(PyArg_ParseTuple(args, (char *)"i", &lu)) {
- if(lu < 256) {
- char s[8];
- sprintf(s, "%lu", lu);
- return dmidecode_get(self, s);
- }
- return Py_False;
- }
- return Py_None;
+static PyObject *dmidecode_get_group(options *opt, const char *section)
+{
+ PyObject *pydata = NULL;
+ xmlNode *dmixml_n = NULL;
+ ptzMAP *mapping = NULL;
+
+ /* Set default option values */
+ if( opt->devmem == NULL ) {
+ opt->devmem = DEFAULT_MEM_DEV;
+ }
+ opt->flags = 0;
+
+ // Decode the dmidata into an XML node
+ dmixml_n = __dmidecode_xml_getsection(opt, section);
+ if( dmixml_n == NULL ) {
+ // Exception already set
+ return NULL;
+ }
+
+ // Convert the retrieved XML nodes to a Python dictionary
+ mapping = dmiMAP_ParseMappingXML_GroupName(opt->mappingxml, section);
+ if( mapping == NULL ) {
+ // Exception already set
+ xmlFreeNode(dmixml_n);
+ return NULL;
+ }
+
+ // Generate Python dict out of XML node
+ pydata = pythonizeXMLnode(mapping, dmixml_n);
+
+ // Clean up and return the resulting Python dictionary
+ ptzmap_Free(mapping);
+ xmlFreeNode(dmixml_n);
+
+ return pydata;
}
-static PyObject* dmidecode_dump(PyObject *self, PyObject *null) {
- const char *f;
- f = opt.dumpfile ? PyString_AsString(opt.dumpfile) : opt.devmem;
- struct stat _buf;
- stat(f, &_buf);
- if((access(f, F_OK) != 0) || ((access(f, W_OK) == 0) && S_ISREG(_buf.st_mode)))
- if(dump(PyString_AS_STRING(opt.dumpfile)))
- Py_RETURN_TRUE;
- Py_RETURN_FALSE;
+xmlNode *__dmidecode_xml_gettypeid(options *opt, int typeid)
+{
+ xmlNode *dmixml_n = NULL;
+
+ /* Set default option values */
+ if( opt->devmem == NULL ) {
+ opt->devmem = DEFAULT_MEM_DEV;
+ }
+ opt->flags = 0;
+
+ dmixml_n = xmlNewNode(NULL, (xmlChar *) "dmidecode");
+ assert( dmixml_n != NULL );
+ // Append DMI version info
+ if( opt->dmiversion_n != NULL ) {
+ xmlAddChild(dmixml_n, xmlCopyNode(opt->dmiversion_n, 1));
+ }
+
+ // Fetch the Mapping XML file
+ if( load_mappingxml(opt) == NULL) {
+ return NULL;
+ }
+
+ // Parse the DMI data and put the result into dmixml_n node chain.
+ opt->type = typeid;
+ if( dmidecode_get_xml(opt, dmixml_n) != 0 ) {
+ PyReturnError(PyExc_RuntimeError, "Error decoding DMI data");
+ }
+
+ return dmixml_n;
}
-static PyObject* dmidecode_get_dev(PyObject *self, PyObject *null) {
- PyObject *dev;
- if(opt.dumpfile != NULL) dev = opt.dumpfile;
- else dev = PyString_FromString(opt.devmem);
- Py_INCREF(dev);
- return dev;
+
+static PyObject *dmidecode_get_typeid(options *opt, int typeid)
+{
+ PyObject *pydata = NULL;
+ xmlNode *dmixml_n = NULL;
+ ptzMAP *mapping = NULL;
+
+ dmixml_n = __dmidecode_xml_gettypeid(opt, typeid);
+ if( dmixml_n == NULL ) {
+ // Exception already set
+ return NULL;
+ }
+
+ // Convert the retrieved XML nodes to a Python dictionary
+ mapping = dmiMAP_ParseMappingXML_TypeID(opt->mappingxml, opt->type);
+ if( mapping == NULL ) {
+ // FIXME: Should we raise an exception here?
+ // Now it passes the unit-test
+ return PyDict_New();
+ }
+
+ // Generate Python dict out of XML node
+ pydata = pythonizeXMLnode(mapping, dmixml_n);
+
+ // Clean up and return the resulting Python dictionary
+ ptzmap_Free(mapping);
+ xmlFreeNode(dmixml_n);
+
+ return pydata;
}
-static PyObject* dmidecode_set_dev(PyObject *self, PyObject *arg) {
- if(PyString_Check(arg)) {
- if(opt.dumpfile == arg) Py_RETURN_TRUE;
- struct stat buf;
- char *f = PyString_AsString(arg);
- stat(f, &buf);
- if(opt.dumpfile) { Py_DECREF(opt.dumpfile); }
+// This global variable should only be available for the "first-entry" functions
+// which is defined in PyMethodDef DMIDataMethods[].
+options *global_options = NULL;
- if(S_ISCHR(buf.st_mode)) {
- if(memcmp(PyString_AsString(arg), "/dev/mem", 8)==0) {
- opt.dumpfile = NULL;
- Py_RETURN_TRUE;
- } else {
+static PyObject *dmidecode_get_bios(PyObject * self, PyObject * args)
+{
+ return dmidecode_get_group(global_options, "bios");
+}
+static PyObject *dmidecode_get_system(PyObject * self, PyObject * args)
+{
+ return dmidecode_get_group(global_options, "system");
+}
+static PyObject *dmidecode_get_baseboard(PyObject * self, PyObject * args)
+{
+ return dmidecode_get_group(global_options, "baseboard");
+}
+static PyObject *dmidecode_get_chassis(PyObject * self, PyObject * args)
+{
+ return dmidecode_get_group(global_options, "chassis");
+}
+static PyObject *dmidecode_get_processor(PyObject * self, PyObject * args)
+{
+ return dmidecode_get_group(global_options, "processor");
+}
+static PyObject *dmidecode_get_memory(PyObject * self, PyObject * args)
+{
+ return dmidecode_get_group(global_options, "memory");
+}
+static PyObject *dmidecode_get_cache(PyObject * self, PyObject * args)
+{
+ return dmidecode_get_group(global_options, "cache");
+}
+static PyObject *dmidecode_get_connector(PyObject * self, PyObject * args)
+{
+ return dmidecode_get_group(global_options, "connector");
+}
+static PyObject *dmidecode_get_slot(PyObject * self, PyObject * args)
+{
+ return dmidecode_get_group(global_options, "slot");
+}
+
+static PyObject *dmidecode_get_section(PyObject *self, PyObject *args)
+{
+ char *section = PyString_AsString(args);
+
+ if( section != NULL ) {
+ return dmidecode_get_group(global_options, section);
+ }
+ PyReturnError(PyExc_RuntimeError, "No section name was given");
+}
+
+static PyObject *dmidecode_get_type(PyObject * self, PyObject * args)
+{
+ int typeid;
+ PyObject *pydata = NULL;
+
+ if( PyArg_ParseTuple(args, (char *)"i", &typeid) ) {
+ if( (typeid < 0) || (typeid > 255) ) {
+ Py_RETURN_FALSE;
+ // FIXME: Should send exception instead
+ // PyReturnError(PyExc_RuntimeError, "Types are bound between 0 and 255 (inclusive)."
+ // "Type value used was '%i'", typeid);
+ }
+ } else {
+ PyReturnError(PyExc_RuntimeError, "Type '%i' is not a valid type identifier%c", typeid);
+ }
+
+ pydata = dmidecode_get_typeid(global_options, typeid);
+ return pydata;
+}
+
+static PyObject *dmidecode_xmlapi(PyObject *self, PyObject *args, PyObject *keywds)
+{
+ static char *keywordlist[] = {"query_type", "result_type", "section", "typeid", NULL};
+ PyObject *pydata = NULL;
+ xmlDoc *dmixml_doc = NULL;
+ xmlNode *dmixml_n = NULL;
+ char *sect_query = NULL, *qtype = NULL, *rtype = NULL;
+ int type_query = -1;
+
+ // Parse the keywords - we only support keywords, as this is an internal API
+ if( !PyArg_ParseTupleAndKeywords(args, keywds, "ss|si", keywordlist,
+ &qtype, &rtype, &sect_query, &type_query) ) {
+ return NULL;
+ }
+
+ // Check for sensible arguments and retrieve the xmlNode with DMI data
+ switch( *qtype ) {
+ case 's': // Section / GroupName
+ if( sect_query == NULL ) {
+ PyReturnError(PyExc_TypeError, "section keyword cannot be NULL")
+ }
+ dmixml_n = __dmidecode_xml_getsection(global_options, sect_query);
+ break;
+
+ case 't': // TypeID / direct TypeMap
+ if( type_query < 0 ) {
+ PyReturnError(PyExc_TypeError,
+ "typeid keyword must be set and must be a positive integer");
+ } else if( type_query > 255 ) {
+ PyReturnError(PyExc_ValueError,
+ "typeid keyword must be an integer between 0 and 255");
+ }
+ dmixml_n = __dmidecode_xml_gettypeid(global_options, type_query);
+ break;
+
+ default:
+ PyReturnError(PyExc_TypeError, "Internal error - invalid query type '%c'", *qtype);
+ }
+
+ // Check if we got any data
+ if( dmixml_n == NULL ) {
+ // Exception already set
+ return NULL;
+ }
+
+ // Check for sensible return type and wrap the correct type into a Python Object
+ switch( *rtype ) {
+ case 'n':
+ pydata = libxml_xmlNodePtrWrap((xmlNode *) dmixml_n);
+ break;
+
+ case 'd':
+ dmixml_doc = xmlNewDoc((xmlChar *) "1.0");
+ if( dmixml_doc == NULL ) {
+ PyReturnError(PyExc_MemoryError, "Could not create new XML document");
+ }
+ xmlDocSetRootElement(dmixml_doc, dmixml_n);
+ pydata = libxml_xmlDocPtrWrap((xmlDoc *) dmixml_doc);
+ break;
+
+ default:
+ PyReturnError(PyExc_TypeError, "Internal error - invalid result type '%c'", *rtype);
+ }
+
+ // Return XML data
+ Py_INCREF(pydata);
+ return pydata;
+}
+
+
+
+static PyObject *dmidecode_dump(PyObject * self, PyObject * null)
+{
+ const char *f;
+ struct stat _buf;
+
+ f = (global_options->dumpfile ? global_options->dumpfile : global_options->devmem);
+ stat(f, &_buf);
+
+ if( (access(f, F_OK) != 0) || ((access(f, W_OK) == 0) && S_ISREG(_buf.st_mode)) ) {
+ if( dump(DEFAULT_MEM_DEV, f) ) {
+ Py_RETURN_TRUE;
+ }
+ }
Py_RETURN_FALSE;
- }
- } else if(!S_ISDIR(buf.st_mode)) {
- opt.dumpfile = arg;
- Py_INCREF(opt.dumpfile);
- Py_RETURN_TRUE;
- }
- }
- Py_RETURN_FALSE;
- //PyErr_Occurred();
}
-/*
-typedef struct {
- PyObject_HEAD char *version;
-} ivars;
+static PyObject *dmidecode_get_dev(PyObject * self, PyObject * null)
+{
+ PyObject *dev = NULL;
+ dev = PyString_FromString((global_options->dumpfile != NULL
+ ? global_options->dumpfile : global_options->devmem));
+ Py_INCREF(dev);
+ return dev;
+}
+
+static PyObject *dmidecode_set_dev(PyObject * self, PyObject * arg)
+{
+ if(PyString_Check(arg)) {
+ struct stat buf;
+ char *f = PyString_AsString(arg);
+
+ if( (f != NULL) && (global_options->dumpfile != NULL )
+ && (strcmp(global_options->dumpfile, f) == 0) ) {
+ Py_RETURN_TRUE;
+ }
+
+ stat(f, &buf);
+ if(S_ISCHR(buf.st_mode)) {
+ if(memcmp(PyString_AsString(arg), "/dev/mem", 8) == 0) {
+ if( global_options->dumpfile != NULL ) {
+ free(global_options->dumpfile);
+ global_options->dumpfile = NULL;
+ }
+ Py_RETURN_TRUE;
+ } else {
+ Py_RETURN_FALSE;
+ }
+ } else if(!S_ISDIR(buf.st_mode)) {
+ global_options->dumpfile = strdup(f);
+ Py_RETURN_TRUE;
+ }
+ }
+ Py_RETURN_FALSE;
+}
+
+static PyObject *dmidecode_set_pythonxmlmap(PyObject * self, PyObject * arg)
+{
+ if(PyString_Check(arg)) {
+ struct stat fileinfo;
+ char *fname = PyString_AsString(arg);
+
+ memset(&fileinfo, 0, sizeof(struct stat));
+
+ if( stat(fname, &fileinfo) != 0 ) {
+ PyReturnError(PyExc_IOError, "Could not access the file '%s'", fname);
+ }
+
+ free(global_options->python_xml_map);
+ global_options->python_xml_map = strdup(fname);
+ Py_RETURN_TRUE;
+ } else {
+ Py_RETURN_FALSE;
+ }
+}
-static PyMemberDef DMIDataMembers[] = {
- { (char *)"fred", T_STRING, offsetof(ivars, version), 0, "2.10" },
- { NULL }
-};
-*/
static PyMethodDef DMIDataMethods[] = {
- { (char *)"dump", dmidecode_dump, METH_NOARGS, (char *)"Dump dmidata to set file" },
- { (char *)"get_dev", dmidecode_get_dev, METH_NOARGS, (char *)"Get an alternative memory device file" },
- { (char *)"set_dev", dmidecode_set_dev, METH_O, (char *)"Set an alternative memory device file" },
-
- { (char *)"bios", dmidecode_get_bios, METH_VARARGS, (char *)"BIOS Data" },
- { (char *)"system", dmidecode_get_system, METH_VARARGS, (char *)"System Data" },
- { (char *)"baseboard", dmidecode_get_baseboard, METH_VARARGS, (char *)"Baseboard Data" },
- { (char *)"chassis", dmidecode_get_chassis, METH_VARARGS, (char *)"Chassis Data" },
- { (char *)"processor", dmidecode_get_processor, METH_VARARGS, (char *)"Processor Data" },
- { (char *)"memory", dmidecode_get_memory, METH_VARARGS, (char *)"Memory Data" },
- { (char *)"cache", dmidecode_get_cache, METH_VARARGS, (char *)"Cache Data" },
- { (char *)"connector", dmidecode_get_connector, METH_VARARGS, (char *)"Connector Data" },
- { (char *)"slot", dmidecode_get_slot, METH_VARARGS, (char *)"Slot Data" },
-
- { (char *)"type", dmidecode_get_type, METH_VARARGS, (char *)"By Type" },
-
- { NULL, NULL, 0, NULL }
+ {(char *)"dump", dmidecode_dump, METH_NOARGS, (char *)"Dump dmidata to set file"},
+ {(char *)"get_dev", dmidecode_get_dev, METH_NOARGS,
+ (char *)"Get an alternative memory device file"},
+ {(char *)"set_dev", dmidecode_set_dev, METH_O,
+ (char *)"Set an alternative memory device file"},
+
+ {(char *)"bios", dmidecode_get_bios, METH_VARARGS, (char *)"BIOS Data"},
+ {(char *)"system", dmidecode_get_system, METH_VARARGS, (char *)"System Data"},
+ {(char *)"baseboard", dmidecode_get_baseboard, METH_VARARGS, (char *)"Baseboard Data"},
+ {(char *)"chassis", dmidecode_get_chassis, METH_VARARGS, (char *)"Chassis Data"},
+ {(char *)"processor", dmidecode_get_processor, METH_VARARGS, (char *)"Processor Data"},
+ {(char *)"memory", dmidecode_get_memory, METH_VARARGS, (char *)"Memory Data"},
+ {(char *)"cache", dmidecode_get_cache, METH_VARARGS, (char *)"Cache Data"},
+ {(char *)"connector", dmidecode_get_connector, METH_VARARGS, (char *)"Connector Data"},
+ {(char *)"slot", dmidecode_get_slot, METH_VARARGS, (char *)"Slot Data"},
+
+ {(char *)"QuerySection", dmidecode_get_section, METH_O,
+ (char *) "Queries the DMI data structure for a given section name. A section"
+ "can often contain several DMI type elements"
+ },
+
+ {(char *)"type", dmidecode_get_type, METH_VARARGS, (char *)"By Type"},
+
+ {(char *)"QueryTypeId", dmidecode_get_type, METH_VARARGS,
+ (char *) "Queries the DMI data structure for a specific DMI type."
+ },
+
+ {(char *)"pythonmap", dmidecode_set_pythonxmlmap, METH_O,
+ (char *) "Use another python dict map definition. The default file is " PYTHON_XML_MAP},
+
+ {(char *)"xmlapi", dmidecode_xmlapi, METH_KEYWORDS,
+ (char *) "Internal API for retrieving data as raw XML data"},
+
+ {NULL, NULL, 0, NULL}
};
-PyMODINIT_FUNC initdmidecode(void) {
- init();
+void destruct_options(void *ptr)
+{
+ options *opt = (options *) ptr;
+
+ if( opt->mappingxml != NULL ) {
+ xmlFreeDoc(opt->mappingxml);
+ opt->mappingxml = NULL;
+ }
+
+ if( opt->python_xml_map != NULL ) {
+ free(opt->python_xml_map);
+ opt->python_xml_map = NULL;
+ }
+
+ if( opt->dmiversion_n != NULL ) {
+ xmlFreeNode(opt->dmiversion_n);
+ opt->dmiversion_n = NULL;
+ }
+
+ if( opt->dumpfile != NULL ) {
+ free(opt->dumpfile);
+ opt->dumpfile = NULL;
+ }
+
+ free(ptr);
+}
+
+
+PyMODINIT_FUNC initdmidecodemod(void)
+{
+ char *dmiver = NULL;
+ PyObject *module = NULL;
+ PyObject *version = NULL;
+ options *opt;
+
+ xmlInitParser();
+ xmlXPathInit();
+
+ opt = (options *) malloc(sizeof(options)+2);
+ memset(opt, 0, sizeof(options)+2);
+ init(opt);
+ module = Py_InitModule3((char *)"dmidecodemod", DMIDataMethods,
+ "Python extension module for dmidecode");
- PyObject *module = Py_InitModule3((char *)"dmidecode", DMIDataMethods, "Python extension module for dmidecode");
+ version = PyString_FromString(VERSION);
+ Py_INCREF(version);
+ PyModule_AddObject(module, "version", version);
- PyObject *version = PyString_FromString("2.10");
- Py_INCREF(version);
- PyModule_AddObject(module, "version", version);
+ opt->dmiversion_n = dmidecode_get_version(opt);
+ dmiver = dmixml_GetContent(opt->dmiversion_n);
+ PyModule_AddObject(module, "dmi", dmiver ? PyString_FromString(dmiver) : Py_None);
- PyObject *dmi_version = NULL;
- dmidecode_set_version(&dmi_version);
- PyModule_AddObject(module, "dmi", dmi_version?dmi_version:Py_None);
+ // Assign this options struct to the module as well with a destructor, that way it will
+ // clean up the memory for us.
+ PyModule_AddObject(module, "options", PyCObject_FromVoidPtr(opt, destruct_options));
+ global_options = opt;
}
diff --git a/src/dmidecodemodule.h b/src/dmidecodemodule.h
index 2b2bde7..c0be3a1 100644
--- a/src/dmidecodemodule.h
+++ b/src/dmidecodemodule.h
@@ -1,3 +1,44 @@
+/*. ******* coding:utf-8 AUTOHEADER START v1.1 *******
+ *. vim: fileencoding=utf-8 syntax=c sw=8 ts=8 et
+ *.
+ *. © 2007-2009 Nima Talebi <nima@autonomy.net.au>
+ *. © 2009 David Sommerseth <davids@redhat.com>
+ *. © 2002-2008 Jean Delvare <khali@linux-fr.org>
+ *. © 2000-2002 Alan Cox <alan@redhat.com>
+ *.
+ *. This file is part of Python DMI-Decode.
+ *.
+ *. Python DMI-Decode 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, either version 2 of the License, or
+ *. (at your option) any later version.
+ *.
+ *. Python DMI-Decode is distributed in the hope that it will be useful,
+ *. but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *. GNU General Public License for more details.
+ *.
+ *. You should have received a copy of the GNU General Public License
+ *. along with Python DMI-Decode. If not, see <http://www.gnu.org/licenses/>.
+ *.
+ *. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *. WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *. MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ *. EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ *. PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ *. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ *. OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ *. ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *.
+ *. ADAPTED M. STONE & T. PARKER DISCLAIMER: THIS SOFTWARE COULD RESULT IN INJURY
+ *. AND/OR DEATH, AND AS SUCH, IT SHOULD NOT BE BUILT, INSTALLED OR USED BY ANYONE.
+ *.
+ *. $AutoHeaderSerial::20090522 $
+ *. ******* AUTOHEADER END v1.1 ******* */
+
+
#include <Python.h>
#include <structmember.h>
@@ -22,43 +63,15 @@
#include "dmihelper.h"
-//extern void dmi_decode(struct dmi_header *h, u16 ver, PyObject* pydata);
-extern PyObject *dmi_dump(struct dmi_header *h);
-extern PyObject* dmi_decode(struct dmi_header *h, u16 ver);
-extern int address_from_efi(size_t *address);
-extern void to_dmi_header(struct dmi_header *h, u8 *data);
-extern void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem);
-extern int smbios_decode(u8 *buf, const char *devmem, PyObject* pydata);
-extern int legacy_decode(u8 *buf, const char *devmem, PyObject* pydata);
-extern int smbios_decode_set_version(u8 *buf, const char *devmem, PyObject** pydata);
-extern int legacy_decode_set_version(u8 *buf, const char *devmem, PyObject** pydata);
-extern void *mem_chunk(size_t base, size_t len, const char *devmem);
+xmlNode *dmidecode_get_version(options *);
-extern u8 *parse_opt_type(u8 *p, const char *arg);
-static const u8 opt_type_bios[] = { 0, 13, 255 };
-static const u8 opt_type_system[] = { 1, 12, 15, 23, 32, 255 };
-static const u8 opt_type_baseboard[] = { 2, 10, 255 };
-static const u8 opt_type_chassis[] = { 3, 255 };
-static const u8 opt_type_processor[] = { 4, 255 };
-static const u8 opt_type_memory[] = { 5, 6, 16, 17, 255 };
-static const u8 opt_type_cache[] = { 7, 255 };
-static const u8 opt_type_connector[] = { 8, 255 };
-static const u8 opt_type_slot[] = { 9, 255 };
-struct type_keyword {
- const char *keyword;
- const u8 *type;
-};
-
-static const struct type_keyword opt_type_keyword[] = {
- { "bios", opt_type_bios },
- { "system", opt_type_system },
- { "baseboard", opt_type_baseboard },
- { "chassis", opt_type_chassis },
- { "processor", opt_type_processor },
- { "memory", opt_type_memory },
- { "cache", opt_type_cache },
- { "connector", opt_type_connector },
- { "slot", opt_type_slot },
-};
+extern void dmi_dump(xmlNode *node, struct dmi_header *h);
+extern int address_from_efi(size_t * address);
+extern void to_dmi_header(struct dmi_header *h, u8 * data);
+extern int smbios_decode(int type, u8 *buf, const char *devmem, xmlNode *node);
+extern int legacy_decode(int type, u8 *buf, const char *devmem, xmlNode *node);
+extern xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem);
+extern xmlNode *legacy_decode_get_version(u8 * buf, const char *devmem);
+extern void *mem_chunk(size_t base, size_t len, const char *devmem);
PyMODINIT_FUNC initdmidecode(void);
diff --git a/src/dmidump.c b/src/dmidump.c
new file mode 100644
index 0000000..a07c975
--- /dev/null
+++ b/src/dmidump.c
@@ -0,0 +1,168 @@
+/* Simple program for dumping DMI/SMBIOS data
+ * Based on code from python-dmidecode/dmidecode.c
+ *
+ * Copyright 2009 David Sommerseth <davids@redhat.com>
+ * Copyright 2002-2008 Jean Delvare <khali@linux-fr.org>
+ * Copyright 2000-2002 Alan Cox <alan@redhat.com>
+ *
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For the avoidance of doubt the "preferred form" of this code is one which
+ * is in an open unpatent encumbered format. Where cryptographic key signing
+ * forms part of the process of creating an executable the information
+ * including keys needed to generate an equivalently functional executable
+ * are deemed to be part of the source code.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "types.h"
+#include "util.h"
+
+#include "dmidump.h"
+#include "efi.h"
+
+/*
+ * Build a crafted entry point with table address hard-coded to 32,
+ * as this is where we will put it in the output file. We adjust the
+ * DMI checksum appropriately. The SMBIOS checksum needs no adjustment.
+ */
+static void overwrite_dmi_address(u8 * buf)
+{
+ buf[0x05] += buf[0x08] + buf[0x09] + buf[0x0A] + buf[0x0B] - 32;
+ buf[0x08] = 32;
+ buf[0x09] = 0;
+ buf[0x0A] = 0;
+ buf[0x0B] = 0;
+}
+
+int dumpling(u8 * buf, const char *dumpfile, u8 mode)
+{
+ u32 base;
+ u16 len;
+
+ if(mode == NON_LEGACY) {
+ if(!checksum(buf, buf[0x05]) || !memcmp(buf + 0x10, "_DMI_", 5) == 0 ||
+ !checksum(buf + 0x10, 0x0F))
+ return 0;
+ base = DWORD(buf + 0x18);
+ len = WORD(buf + 0x16);
+ } else {
+ if(!checksum(buf, 0x0F))
+ return 0;
+ base = DWORD(buf + 0x08);
+ len = WORD(buf + 0x06);
+ }
+
+ u8 *buff;
+
+ if((buff = mem_chunk(base, len, DEFAULT_MEM_DEV)) != NULL) {
+ //. Part 1.
+#ifdef NDEBUG
+ printf("# Writing %d bytes to %s.\n", len, dumpfile);
+#endif
+ write_dump(32, len, buff, dumpfile, 0);
+ free(buff);
+
+ //. Part 2.
+ if(mode != LEGACY) {
+ u8 crafted[32];
+
+ memcpy(crafted, buf, 32);
+ overwrite_dmi_address(crafted + 0x10);
+#ifdef NDEBUG
+ printf("# Writing %d bytes to %s.\n", crafted[0x05], dumpfile);
+#endif
+ write_dump(0, crafted[0x05], crafted, dumpfile, 1);
+ } else {
+ u8 crafted[16];
+
+ memcpy(crafted, buf, 16);
+ overwrite_dmi_address(crafted);
+#ifdef NDEBUG
+ printf("# Writing %d bytes to %s.\n", 0x0F, dumpfile);
+#endif
+ write_dump(0, 0x0F, crafted, dumpfile, 1);
+ }
+ } else {
+ fprintf(stderr, "Failed to read table, sorry.\n");
+ }
+
+ //. TODO: Cleanup
+ return 1;
+}
+
+
+int dump(const char *memdev, const char *dumpfile)
+{
+ /* On success, return found, otherwise return -1 */
+ int ret = 0;
+ int found = 0;
+ size_t fp;
+ int efi;
+ u8 *buf;
+
+ /* First try EFI (ia64, Intel-based Mac) */
+ efi = address_from_efi(&fp);
+ if(efi == EFI_NOT_FOUND) {
+ /* Fallback to memory scan (x86, x86_64) */
+ if((buf = mem_chunk(0xF0000, 0x10000, memdev)) != NULL) {
+ for(fp = 0; fp <= 0xFFF0; fp += 16) {
+ if(memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0) {
+ if(dumpling(buf + fp, dumpfile, NON_LEGACY))
+ found++;
+ fp += 16;
+ } else if(memcmp(buf + fp, "_DMI_", 5) == 0) {
+ if(dumpling(buf + fp, dumpfile, LEGACY))
+ found++;
+ }
+ }
+ } else
+ ret = -1;
+ } else if(efi == EFI_NO_SMBIOS) {
+ ret = -1;
+ } else {
+ if((buf = mem_chunk(fp, 0x20, memdev)) == NULL)
+ ret = -1;
+ else if(dumpling(buf, dumpfile, NON_LEGACY))
+ found++;
+ }
+
+ if(ret == 0) {
+ free(buf);
+ if(!found) {
+ ret = -1;
+ }
+ }
+
+ return ret == 0 ? found : ret;
+}
+
+
+#ifdef _DMIDUMP_MAIN_
+int main(int argc, char **argv)
+{
+ if( argc != 3 ) {
+ fprintf(stderr, "Usage: %s </dev/mem device> <destfile>\n", argv[0]);
+ return 1;
+ }
+ dump(argv[1], argv[2]);
+
+ return 0;
+}
+#endif
diff --git a/src/dmidump.h b/src/dmidump.h
new file mode 100644
index 0000000..3c12248
--- /dev/null
+++ b/src/dmidump.h
@@ -0,0 +1,37 @@
+/* Simple program for dumping DMI/SMBIOS data
+ * Based on code from python-dmidecode/dmidecode.c
+ *
+ * Copyright 2009 David Sommerseth <davids@redhat.com>
+ * Copyright 2002-2008 Jean Delvare <khali@linux-fr.org>
+ * Copyright 2000-2002 Alan Cox <alan@redhat.com>
+ *
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For the avoidance of doubt the "preferred form" of this code is one which
+ * is in an open unpatent encumbered format. Where cryptographic key signing
+ * forms part of the process of creating an executable the information
+ * including keys needed to generate an equivalently functional executable
+ * are deemed to be part of the source code.
+ */
+
+#ifndef _DMIDUMP_H
+
+#define NON_LEGACY 0
+#define LEGACY 1
+
+int dump(const char *memdev, const char *dumpfile);
+
+#endif
diff --git a/src/dmierror.c b/src/dmierror.c
new file mode 100644
index 0000000..d64b4b9
--- /dev/null
+++ b/src/dmierror.c
@@ -0,0 +1,79 @@
+/* Simpilfied and improved Python Error/Exception functions
+ *
+ * 2009 (C) David Sommerseth <davids@redhat.com>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For the avoidance of doubt the "preferred form" of this code is one which
+ * is in an open unpatent encumbered format. Where cryptographic key signing
+ * forms part of the process of creating an executable the information
+ * including keys needed to generate an equivalently functional executable
+ * are deemed to be part of the source code.
+ */
+
+/**
+ * @file dmierror.h
+ * @brief Simpilfied and improved Python Error/Exception functions
+ * @author David Sommerseth <davids@redhat.com>
+ */
+
+#include <Python.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+// #define PRINT_ERRORS // Enable for copy of error messages to stderr
+
+/**
+ * A more flexible function for setting error messages. This function
+ * is called via PyReturnError(...) macro which also returns NULL.
+ * @author David Sommerseth <davids@redhat.com>
+ * @param PyObject* A Python Exception object
+ * @param const char* Error message to follow the exception, may be string formated
+ *
+ */
+void _pyReturnError(void *exception, const char *fname, int line, const char *fmt, ...)
+{
+ va_list ap;
+ char *buf = NULL;
+
+ va_start(ap, fmt);
+ buf = (char *) malloc(4098);
+ memset(buf, 0, 4098);
+
+ if( buf == NULL ) {
+ // Backup routine if we can't get the needed memory
+ fprintf(stderr, "\n\n** ERROR ALLOCATING ERROR MESSAGE BUFFER\n\n");
+ fprintf(stderr, "** ERROR: [%s:%i] ", fname, line);
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+ va_end(ap);
+ return;
+ }
+
+ // Set the error state and message
+ snprintf(buf, 4096, "[%s:%i] %s", fname, line, fmt);
+ PyErr_Format(exception, buf, ap);
+
+#ifdef PRINT_ERRORS
+ fprintf(stderr, "\n**\n** ERROR: ");
+ vfprintf(stderr, buf, ap);
+ fprintf(stderr, "\n**\n\n");
+#endif
+ va_end(ap);
+ free(buf); buf = NULL;
+}
+
diff --git a/src/dmierror.h b/src/dmierror.h
new file mode 100644
index 0000000..0fa0858
--- /dev/null
+++ b/src/dmierror.h
@@ -0,0 +1,54 @@
+/* Simpilfied and improved Python Error/Exception functions
+ *
+ * 2009 (C) David Sommerseth <davids@redhat.com>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For the avoidance of doubt the "preferred form" of this code is one which
+ * is in an open unpatent encumbered format. Where cryptographic key signing
+ * forms part of the process of creating an executable the information
+ * including keys needed to generate an equivalently functional executable
+ * are deemed to be part of the source code.
+ */
+
+/**
+ * @file dmierror.h
+ * @brief Simpilfied and improved Python Error/Exception functions
+ * @author David Sommerseth <davids@redhat.com>
+ */
+
+
+#ifndef DMIERROR_H
+#define DMIERROR_H
+
+#include <stdarg.h>
+
+void _pyReturnError(PyObject *exception, const char *fname, int line, const char *msgfmt, ...);
+
+/**
+ * A more flexible function for setting error messages.
+ * This macro is the one which is supposed to be used in programs, as it will
+ * also exit the calling function with NULL.
+ * @author David Sommerseth <davids@redhat.com>
+ * @param PyObject* A Python Exception object
+ * @param const char* Error message to follow the exception, may be string formated
+ */
+#define PyReturnError(Exception, msg...) { \
+ _pyReturnError(Exception, __FILE__, __LINE__,## msg); \
+ return NULL; \
+ }
+
+
+#endif
diff --git a/src/dmihelper.c b/src/dmihelper.c
deleted file mode 100644
index 6d52e04..0000000
--- a/src/dmihelper.c
+++ /dev/null
@@ -1,115 +0,0 @@
-#include <stdio.h>
-#include <strings.h>
-
-#include "dmihelper.h"
-
-/*
-dmi_minor* dmiAppendObject(long code, char const *key, const char *format, ...) {
- static dmi_minor* last = NULL;
-
- //. int minor = code&0x00FF;
- //. int major = code>>8;
-
- va_list arg;
- va_start(arg, format);
-
- dmi_minor *o = (dmi_minor *)malloc(sizeof(dmi_minor));
- o->next = last;
- o->id = code;
- o->major = (dmi_codes_major *)&dmiCodesMajor[map_maj[code>>8]];
- o->key = (char *)key;
-
- if((format != NULL)&&(vsnprintf(o->value, MAXVAL-1, format, arg) > MAXVAL)) {
- free(o);
- o = NULL;
- //. TODO: Make this a python exception.
- printf("dmidecode: Internal (python module) error; Value too long.\n");
- }
-
- last = o;
- va_end(arg); // cleanup
-
- return o;
-}
-*/
-
-int dmiSetItem(PyObject* dict, const char *key, const char *format, ...) {
- va_list arg;
- va_start(arg, format);
- char buffer[2048];
- vsprintf(buffer, format, arg);
- va_end(arg);
- //printf("DEBUG: Setting k:%s, f:%s s:%s...", key, format, buffer);
- PyDict_SetItem(dict, PyString_FromString(key), PyString_FromString(buffer));
- //printf("Done.\n");
- return 0;
-}
-
-
-/* NOTE: Decomissioned helper function...
-void dmiAppendData(PyObject *pydata, const int count) {
- dmi_minor* last = dmiAppendObject(count, "JUNK", "NODATA");
-
- const char *id = last->major->id;
- PyObject *_key, *_val;
-
- PyObject *pymajor = PyDict_New();
-
- _key = PyString_FromString("code");
- _val = PyInt_FromLong((long)last->major->code);
- PyDict_SetItem(pymajor, _key, _val);
- Py_DECREF(_key);
- Py_DECREF(_val);
-
- _key = PyString_FromString("id");
- _val = PyString_FromString(last->major->id);
- PyDict_SetItem(pymajor, _key, _val);
- Py_DECREF(_key);
- Py_DECREF(_val);
-
- _key = PyString_FromString("name");
- _val = PyString_FromString(last->major->desc);
- PyDict_SetItem(pymajor, _key, _val);
- Py_DECREF(_key);
- Py_DECREF(_val);
-
- PyObject *pyminor = PyDict_New();
- while((last = last->next)) {
- //printf("%d:<%s, %s> | %ld:[%s => %s]\n", last->major->code, last->major->id, last->major->desc, last->id, last->key, last->value);
- _key = PyString_FromString(last->key);
- _val = PyString_FromString(last->value);
- PyDict_SetItem(pyminor, _key, _val);
- Py_DECREF(_key);
- Py_DECREF(_val);
- }
- _key = PyString_FromString("data");
- PyDict_SetItem(pymajor, _key, pyminor);
- Py_DECREF(_key);
- Py_DECREF(pyminor);
-
- _key = PyString_FromString(id);
- PyDict_SetItem(pydata, _key, pymajor);
- Py_DECREF(_key);
- Py_DECREF(pymajor);
-}
-*/
-
-/* NOTE: Decomissioned helper function...
-int catsprintf(char *buf, const char *format, ...) {
- if(format == NULL) {
- bzero(buf, strlen(buf));
- return 0;
- }
-
- va_list arg; // will point to each unnamed argument in turn
- va_start(arg, format); // point to first element after fmt
-
- char b[8192];
- int c = vsprintf (b, format, arg);
-
- strcat(buf, b);
- va_end(arg); // cleanp
-
- return c;
-}
-*/
diff --git a/src/dmihelper.h b/src/dmihelper.h
index a056eb2..d89c024 100644
--- a/src/dmihelper.h
+++ b/src/dmihelper.h
@@ -1,3 +1,44 @@
+/*. ******* coding:utf-8 AUTOHEADER START v1.1 *******
+ *. vim: fileencoding=utf-8 syntax=c sw=8 ts=8 et
+ *.
+ *. © 2007-2009 Nima Talebi <nima@autonomy.net.au>
+ *. © 2009 David Sommerseth <davids@redhat.com>
+ *. © 2002-2008 Jean Delvare <khali@linux-fr.org>
+ *. © 2000-2002 Alan Cox <alan@redhat.com>
+ *.
+ *. This file is part of Python DMI-Decode.
+ *.
+ *. Python DMI-Decode 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, either version 2 of the License, or
+ *. (at your option) any later version.
+ *.
+ *. Python DMI-Decode is distributed in the hope that it will be useful,
+ *. but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *. GNU General Public License for more details.
+ *.
+ *. You should have received a copy of the GNU General Public License
+ *. along with Python DMI-Decode. If not, see <http://www.gnu.org/licenses/>.
+ *.
+ *. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *. WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *. MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ *. EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ *. PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ *. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ *. OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ *. ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *.
+ *. ADAPTED M. STONE & T. PARKER DISCLAIMER: THIS SOFTWARE COULD RESULT IN INJURY
+ *. AND/OR DEATH, AND AS SUCH, IT SHOULD NOT BE BUILT, INSTALLED OR USED BY ANYONE.
+ *.
+ *. $AutoHeaderSerial::20090522 $
+ *. ******* AUTOHEADER END v1.1 ******* */
+
+
#ifndef HELPER
#define HELPER 1
@@ -9,106 +50,84 @@
#include <stdlib.h>
#include <assert.h>
+#include <libxml/tree.h>
+
#include "types.h"
#define MAXVAL 1024
-static const int map_maj[] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
- 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
- 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
- 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
- 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
- 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
- 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
- 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
- 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
- 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
- 120, 121, 122, 123, 124, 125, 126, 127,
-};
-
typedef struct _dmi_codes_major {
- const unsigned short code;
- const char *id;
- const char *desc;
+ const unsigned short code;
+ const char *id;
+ const char *desc;
+ const char *tagname;
} dmi_codes_major;
static const dmi_codes_major dmiCodesMajor[] = {
- { 0, "3.3.1", "BIOS Information" },
- { 1, "3.3.2", "System Information" },
- { 2, "3.3.3", "Base Board Information" },
- { 3, "3.3.4", "Chassis Information" },
- { 4, "3.3.5", "Processor Information" },
- { 5, "3.3.6", "Memory Controller Information" },
- { 6, "3.3.7", "Memory Module Information" },
- { 7, "3.3.8", "Cache Information" },
- { 8, "3.3.9", "Port Connector Information" },
- { 9, "3.3.10", "System Slots" },
- { 10, "3.3.11", "On Board Devices Information" },
- { 11, "3.3.12", "OEM Strings" },
- { 12, "3.3.13", "System Configuration Options" },
- { 13, "3.3.14", "BIOS Language Information" },
- { 14, "3.3.15", "Group Associations" },
- { 15, "3.3.16", "System Event Log" },
- { 16, "3.3.17", "Physical Memory Array" },
- { 17, "3.3.18", "Memory Device" },
- { 18, "3.3.19", "32-bit Memory Error Information" },
- { 19, "3.3.20", "Memory Array Mapped Address" },
- { 20, "3.3.21", "Memory Device Mapped Address" },
- { 21, "3.3.22", "Built-in Pointing Device" },
- { 22, "3.3.23", "Portable Battery" },
- { 23, "3.3.24", "System Reset" },
- { 24, "3.3.25", "Hardware Security" },
- { 25, "3.3.26", "System Power Controls" },
- { 26, "3.3.27", "Voltage Probe" },
- { 27, "3.3.28", "Cooling Device" },
- { 28, "3.3.29", "Temperature Probe" },
- { 29, "3.3.30", "Electrical Current Probe" },
- { 30, "3.3.31", "Out-of-band Remote Access" },
- { 31, "3.3.32", "Boot Integrity Services Entry Point" },
- { 32, "3.3.33", "System Boot Information" },
- { 33, "3.3.34", "64-bit Memory Error Information" },
- { 34, "3.3.35", "Management Device" },
- { 35, "3.3.36", "Management Device Component" },
- { 36, "3.3.37", "Management Device Threshold Data" },
- { 37, "3.3.38", "Memory Channel" },
- { 38, "3.3.39", "IPMI Device Information" },
- { 39, "3.3.40", "System Power Supply" },
- { 40, "3.3.41", "-------------------" },
- { 41, "3.3.42", "-------------------" },
- { 126, "3.3.41", "Inactive" },
- { 127, "3.3.42", "End Of Table" },
+ {0, "3.3.1", "BIOS Information", "BIOSinfo"},
+ {1, "3.3.2", "System Information", "SystemInfo"},
+ {2, "3.3.3", "Base Board Information", "BaseBoardInfo"},
+ {3, "3.3.4", "Chassis Information", "ChassisInfo"},
+ {4, "3.3.5", "Processor Information", "ProcessorInfo"},
+ {5, "3.3.6", "Memory Controller Information", "MemoryCtrlInfo"},
+ {6, "3.3.7", "Memory Module Information", "MemoryModuleInfo"},
+ {7, "3.3.8", "Cache Information", "CacheInfo"},
+ {8, "3.3.9", "Port Connector Information", "PortConnectorInfo"},
+ {9, "3.3.10", "System Slots", "SystemSlots"},
+ {10, "3.3.11", "On Board Devices Information", "OnBoardDevicesInfo"},
+ {11, "3.3.12", "OEM Strings", "OEMstrings"},
+ {12, "3.3.13", "System Configuration Options", "SysConfigOptions"},
+ {13, "3.3.14", "BIOS Language Information", "BIOSlanguage"},
+ {14, "3.3.15", "Group Associations", "GroupAssoc"},
+ {15, "3.3.16", "System Event Log", "SysEventLog"},
+ {16, "3.3.17", "Physical Memory Array", "PhysicalMemoryArray"},
+ {17, "3.3.18", "Memory Device", "MemoryDevice"},
+ {18, "3.3.19", "32-bit Memory Error Information", "MemoryErrorInfo"},
+ {19, "3.3.20", "Memory Array Mapped Address", "MemoryArrayMappedAddress"},
+ {20, "3.3.21", "Memory Device Mapped Address", "MemoryDeviceMappedAddress"},
+ {21, "3.3.22", "Built-in Pointing Device", "BuiltIntPointingDevice"},
+ {22, "3.3.23", "Portable Battery", "PortableBattery"},
+ {23, "3.3.24", "System Reset", "SystemReset"},
+ {24, "3.3.25", "Hardware Security", "HardwareSecurity"},
+ {25, "3.3.26", "System Power Controls", "SystemPowerCtrls"},
+ {26, "3.3.27", "Voltage Probe", "Probe"},
+ {27, "3.3.28", "Cooling Device", "CoolingDevice"},
+ {28, "3.3.29", "Temperature Probe", "Probe"},
+ {29, "3.3.30", "Electrical Current Probe", "Probe"},
+ {30, "3.3.31", "Out-of-band Remote Access", "RemoteAccess"},
+ {31, "3.3.32", "Boot Integrity Services Entry Point", "BootIntegrity"},
+ {32, "3.3.33", "System Boot Information", "SystemBootInfo"},
+ {33, "3.3.34", "64-bit Memory Error Information", "MemoryErrorInfo"},
+ {34, "3.3.35", "Management Device", "ManagementDevice"},
+ {35, "3.3.36", "Management Device Component", "ManagementDevice"},
+ {36, "3.3.37", "Management Device Threshold Data", "ManagementDevice"},
+ {37, "3.3.38", "Memory Channel", "MemoryChannel"},
+ {38, "3.3.39", "IPMI Device Information", "IPMIdeviceInfo"},
+ {39, "3.3.40", "System Power Supply", "SystemPowerSupply"},
+ {40, "3.3.41", "-------------------", "Unknown"},
+ {41, "3.3.42", "-------------------", "Unknown"},
+ {126, "3.3.41", "Inactive", "Inactive"},
+ {127, "3.3.42", "End Of Table", "EndOfTable"},
+ {-1, NULL, NULL, NULL}
};
typedef struct _dmi_minor {
- long id;
- dmi_codes_major* major;
- char *key;
- char value[MAXVAL];
- struct _dmi_minor* next;
+ long id;
+ dmi_codes_major *major;
+ char *key;
+ char value[MAXVAL];
+ struct _dmi_minor *next;
} dmi_minor;
-void dmiAppendData(PyObject *pydata, const int count);
-int dmiSetItem(PyObject* dict, const char *key, const char *format, ...);
-//dmi_minor* dmiAppendObject(long code, char const *key, const char *format, ...);
-
-/*** dmiopt.h ***/
-struct string_keyword {
- const char *keyword;
- u8 type;
- u8 offset;
-};
-
/*** dmiopt.h ***/
typedef struct _options {
- const char *devmem;
- unsigned int flags;
- u8 *type;
- const struct string_keyword *string;
- PyObject *dumpfile;
+ const char *devmem;
+ unsigned int flags;
+ int type;
+ xmlDoc *mappingxml;
+ char *python_xml_map;
+ xmlNode *dmiversion_n;
+ char *dumpfile;
} options;
-extern options opt;
#endif
diff --git a/src/dmioem.c b/src/dmioem.c
index a2fd2a2..361810a 100644
--- a/src/dmioem.c
+++ b/src/dmioem.c
@@ -1,3 +1,4 @@
+
/*
* Decoding of OEM-specific entries
* This file is part of the dmidecode project.
@@ -32,7 +33,7 @@
enum DMI_VENDORS { VENDOR_UNKNOWN, VENDOR_HP };
-static enum DMI_VENDORS dmi_vendor=VENDOR_UNKNOWN;
+static enum DMI_VENDORS dmi_vendor = VENDOR_UNKNOWN;
/*
* Remember the system vendor for later use. We only actually store the
@@ -41,8 +42,8 @@ static enum DMI_VENDORS dmi_vendor=VENDOR_UNKNOWN;
*/
void dmi_set_vendor(const char *s)
{
- if(strcmp(s, "HP")==0)
- dmi_vendor=VENDOR_HP;
+ if(strcmp(s, "HP") == 0)
+ dmi_vendor = VENDOR_HP;
}
/*
@@ -53,63 +54,60 @@ void dmi_set_vendor(const char *s)
static int dmi_decode_hp(struct dmi_header *h)
{
- u8 *data=h->data;
- int nic, ptr;
+ u8 *data = h->data;
+ int nic, ptr;
- switch(h->type)
- {
- case 204:
- /*
- * Vendor Specific: HP ProLiant System/Rack Locator
- */
- printf("HP ProLiant System/Rack Locator\n");
- if(h->length<0x0B) break;
- printf("\tRack Name: %s\n", dmi_string(h, data[0x04]));
- printf("\tEnclosure Name: %s\n", dmi_string(h, data[0x05]));
- printf("\tEnclosure Model: %s\n", dmi_string(h, data[0x06]));
- printf("\tEnclosure Serial: %s\n", dmi_string(h, data[0x0A]));
- printf("\tEnclosure Bays: %d\n", data[0x08]);
- printf("\tServer Bay: %s\n", dmi_string(h, data[0x07]));
- printf("\tBays Filled: %d\n", data[0x09]);
- break;
+ switch (h->type) {
+ case 204:
+ /*
+ * Vendor Specific: HP ProLiant System/Rack Locator
+ */
+ printf("HP ProLiant System/Rack Locator\n");
+ if(h->length < 0x0B)
+ break;
+ printf("\tRack Name: %s\n", dmi_string(h, data[0x04]));
+ printf("\tEnclosure Name: %s\n", dmi_string(h, data[0x05]));
+ printf("\tEnclosure Model: %s\n", dmi_string(h, data[0x06]));
+ printf("\tEnclosure Serial: %s\n", dmi_string(h, data[0x0A]));
+ printf("\tEnclosure Bays: %d\n", data[0x08]);
+ printf("\tServer Bay: %s\n", dmi_string(h, data[0x07]));
+ printf("\tBays Filled: %d\n", data[0x09]);
+ break;
- case 209:
- case 221:
- /*
- * Vendor Specific: HP ProLiant NIC MAC Information
- *
- * This prints the BIOS NIC number,
- * PCI bus/device/function, and MAC address
- */
- printf(h->type==221?
- "HP BIOS iSCSI NIC PCI and MAC Information\n":
- "HP BIOS NIC PCI and MAC Information\n");
- nic=1;
- ptr=4;
- while(h->length>=ptr+8)
- {
- if(data[ptr]==0x00 && data[ptr+1]==0x00)
- printf("\tNIC %d: Disabled\n", nic);
- else if(data[ptr]==0xFF && data[ptr+1]==0xFF)
- printf("\tNIC %d: Not Installed\n", nic);
- else
- {
- printf("\tNIC %d: PCI device %02x:%02x.%x, "
- "MAC address %02X:%02X:%02X:%02X:%02X:%02X\n",
- nic, data[ptr+1], data[ptr]>>3, data[ptr]&7,
- data[ptr+2], data[ptr+3],
- data[ptr+4], data[ptr+5],
- data[ptr+6], data[ptr+7]);
- }
- nic++;
- ptr+=8;
- }
- break;
+ case 209:
+ case 221:
+ /*
+ * Vendor Specific: HP ProLiant NIC MAC Information
+ *
+ * This prints the BIOS NIC number,
+ * PCI bus/device/function, and MAC address
+ */
+ printf(h->type == 221 ?
+ "HP BIOS iSCSI NIC PCI and MAC Information\n" :
+ "HP BIOS NIC PCI and MAC Information\n");
+ nic = 1;
+ ptr = 4;
+ while(h->length >= ptr + 8) {
+ if(data[ptr] == 0x00 && data[ptr + 1] == 0x00)
+ printf("\tNIC %d: Disabled\n", nic);
+ else if(data[ptr] == 0xFF && data[ptr + 1] == 0xFF)
+ printf("\tNIC %d: Not Installed\n", nic);
+ else {
+ printf("\tNIC %d: PCI device %02x:%02x.%x, "
+ "MAC address %02X:%02X:%02X:%02X:%02X:%02X\n",
+ nic, data[ptr + 1], data[ptr] >> 3, data[ptr] & 7,
+ data[ptr + 2], data[ptr + 3],
+ data[ptr + 4], data[ptr + 5], data[ptr + 6], data[ptr + 7]);
+ }
+ nic++;
+ ptr += 8;
+ }
+ break;
- default:
- return 0;
- }
- return 1;
+ default:
+ return 0;
+ }
+ return 1;
}
/*
@@ -118,11 +116,10 @@ static int dmi_decode_hp(struct dmi_header *h)
*/
int dmi_decode_oem(struct dmi_header *h)
{
- switch(dmi_vendor)
- {
- case VENDOR_HP:
- return dmi_decode_hp(h);
- default:
- return 0;
- }
+ switch (dmi_vendor) {
+ case VENDOR_HP:
+ return dmi_decode_hp(h);
+ default:
+ return 0;
+ }
}
diff --git a/src/dmioem.h b/src/dmioem.h
index 00483f2..b1b4af8 100644
--- a/src/dmioem.h
+++ b/src/dmioem.h
@@ -1,3 +1,4 @@
+
/*
* Decoding of OEM-specific entries
* This file is part of the dmidecode project.
diff --git a/src/dmixml.c b/src/dmixml.c
new file mode 100644
index 0000000..5d9f1a1
--- /dev/null
+++ b/src/dmixml.c
@@ -0,0 +1,360 @@
+/* Simplified XML API for dmidecode
+ *
+ * Copyright 2009 David Sommerseth <davids@redhat.com>
+ * Copyright 2009 Nima Talebi <nima@autonomy.net.au>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For the avoidance of doubt the "preferred form" of this code is one which
+ * is in an open unpatent encumbered format. Where cryptographic key signing
+ * forms part of the process of creating an executable the information
+ * including keys needed to generate an equivalently functional executable
+ * are deemed to be part of the source code.
+ */
+
+/**
+ * @file dmixml.c
+ * @brief Helper functions for XML nodes and documents.
+ * @author David Sommerseth <davids@redhat.com>
+ * @author Nima Talebi <nima@autonomy.net.au>
+ */
+
+
+
+#include <string.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#include <libxml/tree.h>
+#include <libxml/xpath.h>
+#include <libxml/xmlstring.h>
+
+#include "dmixml.h"
+
+/**
+ * Internal function for dmixml_* functions. The function will allocate a buffer and populate it
+ * according to the format string
+ * @author David Sommerseth <davids@redhat.com>
+ * @param size_t The requested size for the new buffer
+ * @param const char* The format of the string being built (uses vsnprintf())
+ * @param ... The needed variables to build up the string
+ * @return xmlChar* Pointer to the buffer of the string
+ */
+xmlChar *dmixml_buildstr(size_t len, const char *fmt, va_list ap) {
+ xmlChar *ret = NULL, *xmlfmt = NULL;
+ xmlChar *ptr = NULL;
+
+ ret = (xmlChar *) malloc(len+2);
+ assert( ret != NULL );
+ memset(ret, 0, len+2);
+
+ xmlfmt = xmlCharStrdup(fmt);
+ assert( xmlfmt != NULL );
+
+ xmlStrVPrintf(ret, len, xmlfmt, ap);
+ free(xmlfmt);
+
+ // Right trim the string
+ ptr = ret + xmlStrlen(ret)-1;
+ while( (ptr >= ret) && (*ptr == ' ') ) {
+ *ptr = 0;
+ ptr--;
+ }
+ return ret;
+}
+
+
+/**
+ * Add an XML property/attribute to the given XML node
+ * @author David Sommerseth <davids@redhat.com>
+ * @param xmlNode* A pointer to the xmlNode being updated
+ * @param const char* The name of the attribute
+ * @param const char* Value of the string (can make use of string formating options)
+ * @return xmlAttr* Pointer to the new attribute node. On errors an assert is
+ * triggered and return value should be NULL.
+ */
+xmlAttr *dmixml_AddAttribute(xmlNode *node, const char *atrname, const char *fmt, ...)
+{
+ xmlChar *val_s = NULL, *atrname_s = NULL;
+ xmlAttr *res = NULL;
+ va_list ap;
+
+ if( (node == NULL) || (atrname == NULL) || (fmt == NULL) ) {
+ return NULL;
+ }
+
+ atrname_s = xmlCharStrdup(atrname);
+ assert( atrname_s != NULL );
+
+ va_start(ap, fmt);
+ val_s = dmixml_buildstr(2048, fmt, ap);
+ va_end(ap);
+
+ res = xmlNewProp(node, atrname_s,
+ (xmlStrcmp(val_s, (xmlChar *) "(null)") == 0 ? NULL : val_s));
+
+ free(atrname_s);
+ free(val_s);
+
+ assert( res != NULL );
+ return res;
+}
+
+
+/**
+ * Adds a new XML tag to the given node with the given tag name and value.
+ * @author David Sommerseth <davids@redhat.com>
+ * @param xmlNode* Pointer to the parent node for this new node
+ * @param const char* Name of the new tag
+ * @param const char* Contents of the new tag (can make use of string formating options)
+ * @return xmlNode* Pointer to the new tag. On errors an assert is triggered and return
+ * value should be NULL.
+ */
+xmlNode *dmixml_AddTextChild(xmlNode *node, const char *tagname, const char *fmt, ...)
+{
+ xmlChar *val_s = NULL, *tagname_s = NULL;
+ xmlNode *res = NULL;
+ va_list ap;
+
+ if( (node == NULL) || (tagname == NULL) || (fmt == NULL) ) {
+ return NULL;
+ }
+
+ tagname_s = xmlCharStrdup(tagname);
+ assert( tagname_s != NULL );
+
+ va_start(ap, fmt);
+ val_s = dmixml_buildstr(2048, fmt, ap);
+ va_end(ap);
+
+ // Do not add any contents if the string contents is "(null)"
+ res = xmlNewTextChild(node, NULL, tagname_s,
+ (xmlStrcmp(val_s, (xmlChar *) "(null)") == 0 ? NULL : val_s));
+
+ free(tagname_s);
+ free(val_s);
+
+ assert( res != NULL );
+ return res;
+}
+
+/**
+ * Adds a text node child to the given XML node. If input is NULL, the tag contents will be empty.
+ * @author David Sommerseth <davids@redhat.com>
+ * @param xmlNode* Pointer to the current node which will get the text child
+ * @param const char* Contents of the tag (can make use of string formating options)
+ * @return xmlNode* Pointer to the tags content node
+ */
+xmlNode *dmixml_AddTextContent(xmlNode *node, const char *fmt, ...)
+{
+ xmlChar *val_s = NULL;
+ xmlNode *res = NULL;
+ va_list ap;
+
+ if( (node == NULL) || (fmt == NULL) ) {
+ return NULL;
+ }
+
+ va_start(ap, fmt);
+ val_s = dmixml_buildstr(2048, fmt, ap);
+ va_end(ap);
+
+ if( xmlStrcmp(val_s, (xmlChar *) "(null)") != 0 ) {
+ res = xmlAddChild(node, xmlNewText(val_s));
+ } else {
+ res = node;
+ }
+ free(val_s);
+
+ assert( res != NULL );
+ return res;
+}
+
+/**
+ * Retrieve the contents of a named attribute in a given XML node
+ * @author David Sommerseth <davids@redhat.com>
+ * @param xmlNode* Pointer to the XML node of which we want to extract the attribute value
+ * @param const char* The name of the attribute to be extracted
+ * @return char* Pointer to the attribute contents if found, otherwise NULL. This value
+ * must NOT be freed, as it points directly into the value in the XML document.
+ */
+char *dmixml_GetAttrValue(xmlNode *node, const char *key) {
+ xmlAttr *aptr = NULL;
+ xmlChar *key_s = NULL;
+
+ if( node == NULL ) {
+ return NULL;
+ }
+
+ key_s = xmlCharStrdup(key);
+ assert( key_s != NULL );
+
+ for( aptr = node->properties; aptr != NULL; aptr = aptr->next ) {
+ if( xmlStrcmp(aptr->name, key_s) == 0 ) {
+ free(key_s); key_s = NULL;
+ // FIXME: Should find better way how to return UTF-8 data
+ return (char *)(aptr->children != NULL ? aptr->children->content : NULL);
+ }
+ }
+ free(key_s); key_s = NULL;
+ return NULL;
+}
+
+/**
+ * Internal function - Retrieve a pointer to an XML node based on tag name and a specified attribute
+ * value. To get a hit, tag name and the attribute must be found and the value of the attribute must
+ * match as well. The function will traverse all children nodes of the given input node, but it will
+ * not go deeper.
+ * @author David Sommerseth <davids@redhat.com>
+ * @author Nima Talebi <nima@autonomy.net.au>
+ * @param xmlNode* Pointer to the XML node of where to start searching
+ * @param const char* Tag name the function will search for
+ * @param const char* Attribute to check for in the tag
+ * @param const char* Value of the attribute which must match to have a hit
+ * @param int Be case sensitive or not. 1 == case sensitive, 0 == case insensitive
+ * @return xmlNode* Pointer to the found XML node, NULL if no tag was found.
+ */
+xmlNode *__dmixml_FindNodeByAttr(xmlNode *node, const char *tagkey, const char *attrkey,
+ const char *val, int casesens) {
+ xmlNode *ptr_n = NULL;
+ xmlChar *tag_s = NULL;
+ int (*compare_func) (const char *, const char *);
+
+ assert( node != NULL );
+ if( node->children == NULL ) {
+ return NULL;
+ }
+
+ tag_s = xmlCharStrdup(tagkey);
+ assert( tag_s != NULL );
+
+ compare_func = (casesens == 1 ? strcmp : strcasecmp);
+
+ foreach_xmlnode(node->children, ptr_n) {
+ // To return the correct node, we need to check node type,
+ // tag name and the attribute value of the given attribute.
+ if( (ptr_n->type == XML_ELEMENT_NODE)
+ && (xmlStrcmp(ptr_n->name, tag_s) == 0)
+ && (compare_func(dmixml_GetAttrValue(ptr_n, attrkey), val) == 0 ) ) {
+ goto exit;
+ }
+ }
+ exit:
+ free(tag_s); tag_s = NULL;
+ return ptr_n;
+}
+
+/**
+ * Retrieve a poitner to an XML node with the given name. The function will traverse
+ * all children nodes of the given input node, but it will not go deeper. The function
+ * will only return the first hit.
+ * @author David Sommerseth <davids@redhat.com>
+ * @param xmlNode* Pointer to the XML node of where to start searching
+ * @param const char* Name of the tag name the function will look for.
+ * @return xmlNode* Pointer to the found XML node, NULL if no tag was found.
+ */
+xmlNode *dmixml_FindNode(xmlNode *node, const char *key) {
+ xmlNode *ptr_n = NULL;
+ xmlChar *key_s = NULL;
+
+ if( node->children == NULL ) {
+ return NULL;
+ }
+
+ key_s = xmlCharStrdup(key);
+ assert( key_s != NULL );
+
+ for( ptr_n = node->children; ptr_n != NULL; ptr_n = ptr_n->next ) {
+ if( (ptr_n->type == XML_ELEMENT_NODE)
+ && (xmlStrcmp(ptr_n->name, key_s) == 0) ) {
+ free(key_s); key_s = NULL;
+ return ptr_n;
+ }
+ }
+ free(key_s); key_s = NULL;
+ return NULL;
+}
+
+/**
+ * Retrieve the text contents of the given XML node
+ * @author David Sommerseth <davids@redhat.com>
+ * @param xmlNode* Pointer to the XML node of which we want to extract the contents
+ * @return char* Pointer to the tag contents if found, otherwise NULL. This value
+ * must NOT be freed, as it points directly into the value in the XML document.
+ */
+inline char *dmixml_GetContent(xmlNode *node) {
+ // FIXME: Should find better way how to return UTF-8 data
+ return (((node != NULL) && (node->children != NULL)) ? (char *) node->children->content : NULL);
+}
+
+/**
+ * Retrieve the text content of a given tag. The function will traverse
+ * all children nodes of the given input node, but it will not go deeper.
+ * The function will only return the first hit.
+ * @author David Sommerseth <davids@redhat.com>
+ * @param xmlNode* Pointer to the XML node of where to start searching
+ * @param const char* Name of the tag the function will look for
+ * @return char* Pointer to the tag contents if found, otherwise NULL. This value
+ * must NOT be freed, as it points directly into the value in the XML document.
+ */
+inline char *dmixml_GetNodeContent(xmlNode *node, const char *key) {
+ return dmixml_GetContent(dmixml_FindNode(node, key));
+}
+
+/**
+ * Retrieve the contents from an XPath object.
+ * @author David Sommerseth <davids@redhat.com>
+ * @param char* Pointer to a buffer where to return the value
+ * @param size_t Size of the return buffer
+ * @param xmlXPathObject* Pointer to the XPath object containing the data
+ * @param int If the XPath object contains a node set, this defines
+ * which of the elements to be extracted.
+ * @return char* Points at the return buffer if a value is found, otherwise NULL is returned.
+ */
+char *dmixml_GetXPathContent(char *buf, size_t buflen, xmlXPathObject *xpo, int idx) {
+ memset(buf, 0, buflen);
+
+ if( xpo == NULL ) {
+ return NULL;
+ }
+
+ switch( xpo->type ) {
+ case XPATH_STRING:
+ strncpy(buf, (char *)xpo->stringval, buflen-1);
+ break;
+
+ case XPATH_NUMBER:
+ snprintf(buf, buflen-1, "%f", xpo->floatval);
+ break;
+
+ case XPATH_NODESET:
+ if( (xpo->nodesetval != NULL) && (xpo->nodesetval->nodeNr >= (idx+1)) ) {
+ char *str = dmixml_GetContent(xpo->nodesetval->nodeTab[idx]);
+ if( str != NULL ) {
+ strncpy(buf, str, buflen-1);
+ } else {
+ memset(buf, 0, buflen);
+ }
+ }
+ break;
+
+ default:
+ fprintf(stderr, "dmixml_GetXPathContent(...):: "
+ "Do not know how to handle XPath type %i\n",
+ xpo->type);
+ return NULL;
+ }
+ return buf;
+}
diff --git a/src/dmixml.h b/src/dmixml.h
new file mode 100644
index 0000000..3dc32e5
--- /dev/null
+++ b/src/dmixml.h
@@ -0,0 +1,79 @@
+/* Simplified XML API for dmidecode
+ *
+ * Copyright 2009 David Sommerseth <davids@redhat.com>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For the avoidance of doubt the "preferred form" of this code is one which
+ * is in an open unpatent encumbered format. Where cryptographic key signing
+ * forms part of the process of creating an executable the information
+ * including keys needed to generate an equivalently functional executable
+ * are deemed to be part of the source code.
+ */
+
+#ifndef _XMLHELPER_H
+#define _XMLHELPER_H
+
+#include <stdarg.h>
+#include <libxml/tree.h>
+#include <libxml/xpath.h>
+
+#define foreach_xmlnode(n, itn) for( itn = n; itn != NULL; itn = itn->next )
+
+xmlAttr *dmixml_AddAttribute(xmlNode *node, const char *atrname, const char *fmt, ...);
+xmlNode *dmixml_AddTextChild(xmlNode *node, const char *tagname, const char *fmt, ...);
+xmlNode *dmixml_AddTextContent(xmlNode *node, const char *fmt, ...);
+
+char *dmixml_GetAttrValue(xmlNode *node, const char *key);
+
+xmlNode *__dmixml_FindNodeByAttr(xmlNode *, const char *, const char *, const char *, int);
+
+/**
+ * Retrieve a pointer to an XML node based on tag name and a specified attribute value. To get
+ * a hit, tag name and the attribute must be found and the value of the attribute must match as well.
+ * The function will traverse all children nodes of the given input node, but it will not go deeper.
+ * Matching is case sensitive.
+ * @author David Sommerseth <davids@redhat.com>
+ * @author Nima Talebi <nima@autonomy.net.au>
+ * @param xmlNode* Pointer to the XML node of where to start searching
+ * @param const char* Tag name the function will search for
+ * @param const char* Attribute to check for in the tag
+ * @param const char* Value of the attribute which must match to have a hit
+ * @return xmlNode* Pointer to the found XML node, NULL if no tag was found.
+ */
+#define dmixml_FindNodeByAttr(n, t, a, v) __dmixml_FindNodeByAttr(n, t, a, v, 1)
+
+/**
+ * Retrieve a pointer to an XML node based on tag name and a specified attribute value. To get
+ * a hit, tag name and the attribute must be found and the value of the attribute must match as well.
+ * The function will traverse all children nodes of the given input node, but it will not go deeper.
+ * Matching is case INsensitive.
+ * @author David Sommerseth <davids@redhat.com>
+ * @author Nima Talebi <nima@autonomy.net.au>
+ * @param xmlNode* Pointer to the XML node of where to start searching
+ * @param const char* Tag name the function will search for
+ * @param const char* Attribute to check for in the tag
+ * @param const char* Value of the attribute which must match to have a hit
+ * @return xmlNode* Pointer to the found XML node, NULL if no tag was found.
+ */
+#define dmixml_FindNodeByAttr_NoCase(n, t, a, v) __dmixml_FindNodeByAttr(n, t, a, v, 0)
+
+
+xmlNode *dmixml_FindNode(xmlNode *, const char *key);
+inline char *dmixml_GetContent(xmlNode *node);
+inline char *dmixml_GetNodeContent(xmlNode *node, const char *key);
+char *dmixml_GetXPathContent(char *buf, size_t buflen, xmlXPathObject *xpo, int idx);
+
+#endif
diff --git a/src/efi.c b/src/efi.c
new file mode 100644
index 0000000..9802171
--- /dev/null
+++ b/src/efi.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2009 David Sommerseth <davids@redhat.com>
+ * Copyright 2002-2008 Jean Delvare <khali@linux-fr.org>
+ * Copyright 2000-2002 Alan Cox <alan@redhat.com>
+ *
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For the avoidance of doubt the "preferred form" of this code is one which
+ * is in an open unpatent encumbered format. Where cryptographic key signing
+ * forms part of the process of creating an executable the information
+ * including keys needed to generate an equivalently functional executable
+ * are deemed to be part of the source code.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "efi.h"
+
+/**
+ * @file xmlpythonizer.c
+ * @brief Helper function for EFI support
+ * @author Jean Delvare <khali@linux-fr.org>
+ * @author Alan Cox <alan@redhat.com>
+ */
+
+/**
+ * Probe for EFI interface
+ * @param size_t*
+ * @return returns EFI_NOT_FOUND or EFI_NO_SMBIOS
+ */
+int address_from_efi(size_t * address)
+{
+ FILE *efi_systab;
+ const char *filename;
+ char linebuf[64];
+ int ret;
+
+ *address = 0; /* Prevent compiler warning */
+
+ /*
+ ** Linux <= 2.6.6: /proc/efi/systab
+ ** Linux >= 2.6.7: /sys/firmware/efi/systab
+ */
+ if((efi_systab = fopen(filename = "/sys/firmware/efi/systab", "r")) == NULL
+ && (efi_systab = fopen(filename = "/proc/efi/systab", "r")) == NULL) {
+ /* No EFI interface, fallback to memory scan */
+ return EFI_NOT_FOUND;
+ }
+ ret = EFI_NO_SMBIOS;
+ while((fgets(linebuf, sizeof(linebuf) - 1, efi_systab)) != NULL) {
+ char *addrp = strchr(linebuf, '=');
+
+ *(addrp++) = '\0';
+ if(strcmp(linebuf, "SMBIOS") == 0) {
+ *address = strtoul(addrp, NULL, 0);
+ printf("# SMBIOS entry point at 0x%08lx\n", (unsigned long)*address);
+ ret = 0;
+ break;
+ }
+ }
+ if(fclose(efi_systab) != 0)
+ perror(filename);
+
+ if(ret == EFI_NO_SMBIOS)
+ fprintf(stderr, "%s: SMBIOS entry point missing\n", filename);
+
+ return ret;
+}
+
diff --git a/src/efi.h b/src/efi.h
new file mode 100644
index 0000000..240fb01
--- /dev/null
+++ b/src/efi.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2009 David Sommerseth <davids@redhat.com>
+ * Copyright 2002-2008 Jean Delvare <khali@linux-fr.org>
+ * Copyright 2000-2002 Alan Cox <alan@redhat.com>
+ *
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For the avoidance of doubt the "preferred form" of this code is one which
+ * is in an open unpatent encumbered format. Where cryptographic key signing
+ * forms part of the process of creating an executable the information
+ * including keys needed to generate an equivalently functional executable
+ * are deemed to be part of the source code.
+ */
+
+#ifndef _EFI_H
+#define _EFI_H
+#define EFI_NOT_FOUND (-1)
+#define EFI_NO_SMBIOS (-2)
+
+int address_from_efi(size_t * address);
+
+#endif
diff --git a/src/libxml_wrap.h b/src/libxml_wrap.h
new file mode 100644
index 0000000..e4f56dd
--- /dev/null
+++ b/src/libxml_wrap.h
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 1998-2003 Daniel Veillard. 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 fur-
+ * nished 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, FIT-
+ * NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * DANIEL VEILLARD BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
+ * NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Daniel Veillard shall not
+ * be used in advertising or otherwise to promote the sale, use or other deal-
+ * ings in this Software without prior written authorization from him.
+ *
+ *
+ * This include file is taken from the libxml2 source tree, to provide the needed
+ * declarations to implement usage of libxml2xml.so
+ * (David Sommerseth <davids@redhat.com>, 2009)
+ *
+ */
+
+#include <Python.h>
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/catalog.h>
+#include <libxml/threads.h>
+#include <libxml/nanoftp.h>
+#include <libxml/nanohttp.h>
+#include <libxml/uri.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/debugXML.h>
+#include <libxml/HTMLparser.h>
+#include <libxml/HTMLtree.h>
+#include <libxml/xinclude.h>
+#include <libxml/xpointer.h>
+#include <libxml/xmlunicode.h>
+#include <libxml/xmlregexp.h>
+#include <libxml/xmlautomata.h>
+#include <libxml/xmlreader.h>
+#ifdef LIBXML_SCHEMAS_ENABLED
+#include <libxml/relaxng.h>
+#include <libxml/xmlschemas.h>
+#endif
+
+/**
+ * ATTRIBUTE_UNUSED:
+ *
+ * Macro used to signal to GCC unused function parameters
+ * Repeated here since the definition is not available when
+ * compiled outside the libxml2 build tree.
+ */
+#ifdef __GNUC__
+#ifdef ATTRIBUTE_UNUSED
+#undef ATTRIBUTE_UNUSED
+#endif
+#ifndef ATTRIBUTE_UNUSED
+#define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
+#endif /* ATTRIBUTE_UNUSED */
+#else
+#define ATTRIBUTE_UNUSED
+#endif
+
+#define PyxmlNode_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyxmlNode_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlNodePtr obj;
+} PyxmlNode_Object;
+
+#define PyxmlXPathContext_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyxmlXPathContext_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlXPathContextPtr obj;
+} PyxmlXPathContext_Object;
+
+#define PyxmlXPathParserContext_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyxmlXPathParserContext_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlXPathParserContextPtr obj;
+} PyxmlXPathParserContext_Object;
+
+#define PyparserCtxt_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyparserCtxt_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlParserCtxtPtr obj;
+} PyparserCtxt_Object;
+
+#define PyValidCtxt_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyValidCtxt_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlValidCtxtPtr obj;
+} PyValidCtxt_Object;
+
+#define Pycatalog_Get(v) (((v) == Py_None) ? NULL : \
+ (((Pycatalog_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlCatalogPtr obj;
+} Pycatalog_Object;
+
+#ifdef LIBXML_REGEXP_ENABLED
+#define PyxmlReg_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyxmlReg_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlRegexpPtr obj;
+} PyxmlReg_Object;
+#endif /* LIBXML_REGEXP_ENABLED */
+
+#ifdef LIBXML_READER_ENABLED
+#define PyxmlTextReader_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyxmlTextReader_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlTextReaderPtr obj;
+} PyxmlTextReader_Object;
+
+#define PyxmlTextReaderLocator_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyxmlTextReaderLocator_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlTextReaderLocatorPtr obj;
+} PyxmlTextReaderLocator_Object;
+#endif
+
+#define PyURI_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyURI_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlErrorPtr obj;
+} PyError_Object;
+
+#define PyError_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyError_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlOutputBufferPtr obj;
+} PyoutputBuffer_Object;
+
+#define PyoutputBuffer_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyoutputBuffer_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlParserInputBufferPtr obj;
+} PyinputBuffer_Object;
+
+#define PyinputBuffer_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyinputBuffer_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlURIPtr obj;
+} PyURI_Object;
+
+/* FILE * have their own internal representation */
+#define PyFile_Get(v) (((v) == Py_None) ? NULL : \
+ (PyFile_Check(v) ? (PyFile_AsFile(v)) : stdout))
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+typedef struct {
+ PyObject_HEAD
+ xmlRelaxNGPtr obj;
+} PyrelaxNgSchema_Object;
+
+#define PyrelaxNgSchema_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyrelaxNgSchema_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlRelaxNGParserCtxtPtr obj;
+} PyrelaxNgParserCtxt_Object;
+
+#define PyrelaxNgParserCtxt_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyrelaxNgParserCtxt_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlRelaxNGValidCtxtPtr obj;
+} PyrelaxNgValidCtxt_Object;
+
+#define PyrelaxNgValidCtxt_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyrelaxNgValidCtxt_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlSchemaPtr obj;
+} PySchema_Object;
+
+#define PySchema_Get(v) (((v) == Py_None) ? NULL : \
+ (((PySchema_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlSchemaParserCtxtPtr obj;
+} PySchemaParserCtxt_Object;
+
+#define PySchemaParserCtxt_Get(v) (((v) == Py_None) ? NULL : \
+ (((PySchemaParserCtxt_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlSchemaValidCtxtPtr obj;
+} PySchemaValidCtxt_Object;
+
+#define PySchemaValidCtxt_Get(v) (((v) == Py_None) ? NULL : \
+ (((PySchemaValidCtxt_Object *)(v))->obj))
+
+#endif /* LIBXML_SCHEMAS_ENABLED */
+
+PyObject * libxml_intWrap(int val);
+PyObject * libxml_longWrap(long val);
+PyObject * libxml_xmlCharPtrWrap(xmlChar *str);
+PyObject * libxml_constxmlCharPtrWrap(const xmlChar *str);
+PyObject * libxml_charPtrWrap(char *str);
+PyObject * libxml_constcharPtrWrap(const char *str);
+PyObject * libxml_charPtrConstWrap(const char *str);
+PyObject * libxml_xmlCharPtrConstWrap(const xmlChar *str);
+PyObject * libxml_xmlDocPtrWrap(xmlDocPtr doc);
+PyObject * libxml_xmlNodePtrWrap(xmlNodePtr node);
+PyObject * libxml_xmlAttrPtrWrap(xmlAttrPtr attr);
+PyObject * libxml_xmlNsPtrWrap(xmlNsPtr ns);
+PyObject * libxml_xmlAttributePtrWrap(xmlAttributePtr ns);
+PyObject * libxml_xmlElementPtrWrap(xmlElementPtr ns);
+PyObject * libxml_doubleWrap(double val);
+PyObject * libxml_xmlXPathContextPtrWrap(xmlXPathContextPtr ctxt);
+PyObject * libxml_xmlParserCtxtPtrWrap(xmlParserCtxtPtr ctxt);
+PyObject * libxml_xmlXPathParserContextPtrWrap(xmlXPathParserContextPtr ctxt);
+PyObject * libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj);
+PyObject * libxml_xmlValidCtxtPtrWrap(xmlValidCtxtPtr valid);
+PyObject * libxml_xmlCatalogPtrWrap(xmlCatalogPtr obj);
+PyObject * libxml_xmlURIPtrWrap(xmlURIPtr uri);
+PyObject * libxml_xmlOutputBufferPtrWrap(xmlOutputBufferPtr buffer);
+PyObject * libxml_xmlParserInputBufferPtrWrap(xmlParserInputBufferPtr buffer);
+#ifdef LIBXML_REGEXP_ENABLED
+PyObject * libxml_xmlRegexpPtrWrap(xmlRegexpPtr regexp);
+#endif /* LIBXML_REGEXP_ENABLED */
+#ifdef LIBXML_READER_ENABLED
+PyObject * libxml_xmlTextReaderPtrWrap(xmlTextReaderPtr reader);
+PyObject * libxml_xmlTextReaderLocatorPtrWrap(xmlTextReaderLocatorPtr locator);
+#endif
+
+xmlXPathObjectPtr libxml_xmlXPathObjectPtrConvert(PyObject * obj);
+#ifdef LIBXML_SCHEMAS_ENABLED
+PyObject * libxml_xmlRelaxNGPtrWrap(xmlRelaxNGPtr ctxt);
+PyObject * libxml_xmlRelaxNGParserCtxtPtrWrap(xmlRelaxNGParserCtxtPtr ctxt);
+PyObject * libxml_xmlRelaxNGValidCtxtPtrWrap(xmlRelaxNGValidCtxtPtr valid);
+PyObject * libxml_xmlSchemaPtrWrap(xmlSchemaPtr ctxt);
+PyObject * libxml_xmlSchemaParserCtxtPtrWrap(xmlSchemaParserCtxtPtr ctxt);
+PyObject * libxml_xmlSchemaValidCtxtPtrWrap(xmlSchemaValidCtxtPtr valid);
+#endif /* LIBXML_SCHEMAS_ENABLED */
+PyObject * libxml_xmlErrorPtrWrap(xmlErrorPtr error);
+PyObject * libxml_xmlSchemaSetValidErrors(PyObject * self, PyObject * args);
diff --git a/src/pymap.xml b/src/pymap.xml
new file mode 100644
index 0000000..a07512c
--- /dev/null
+++ b/src/pymap.xml
@@ -0,0 +1,864 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ # 2007-2009 (C) Nima Talebi <nima@autonomy.net.au>
+ # 2009 (C) David Sommerseth <davids@redhat.com>
+ #
+ # This file is part of Python DMI-Decode.
+ #
+ # Python DMI-Decode 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, either version 2 of the License, or
+ # (at your option) any later version.
+ #
+ # Python DMI-Decode is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ # GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+ # along with Python DMI-Decode. If not, see <http://www.gnu.org/licenses/>.
+ #
+ # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ # EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ #
+ # ADAPTED M. STONE & T. PARKER DISCLAIMER: THIS SOFTWARE COULD RESULT IN INJURY
+ # AND/OR DEATH, AND AS SUCH, IT SHOULD NOT BE BUILT, INSTALLED OR USED BY ANYONE.
+ #
+-->
+
+<dmidecode_mapping version="1">
+
+<!--
+ TODO: To discuss the following with dazo...
+ TODO: Naming convention - sit on this or can we do better? For example some
+ TODO: root-paths have an appended `Info', and some don't (going from doc/README.types).
+-->
+
+ <TypeMapping>
+ <!-- Type 00 : BIOS -->
+ <TypeMap id="0x00">
+ <Map rootpath="/dmidecode/BIOSinfo" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="Vendor" valuetype="string" value="Vendor"/>
+ <Map keytype="constant" key="Characteristics" valuetype="dict">
+ <Map keytype="string" key="Characteristics/flags/flag[../../@level = '0']"
+ valuetype="boolean" value="Characteristics/flags/flag/@enabled"/>
+ </Map>
+ <Map keytype="constant" key="Characteristic x1" valuetype="dict">
+ <Map keytype="string" key="Characteristics/characteristic[../@level = 'x1']"
+ valuetype="boolean" value="Characteristics/characteristic/@enabled"/>
+ </Map>
+ <Map keytype="constant" key="Characteristic x2" valuetype="dict">
+ <Map keytype="string" key="Characteristics/characteristic[../@level = 'x2']"
+ valuetype="boolean" value="Characteristics/characteristic/@enabled"/>
+ </Map>
+ <Map keytype="constant" key="Runtime Size" valuetype="string"
+ value="concat(RuntimeSize,' ',RuntimeSize/@unit)"/>
+ <Map keytype="constant" key="BIOS Revision"
+ valuetype="string" value="BIOSrevision"/>
+ <Map keytype="constant" key="Version" valuetype="string" value="Version"/>
+ <Map keytype="constant" key="ROM Size" valuetype="string"
+ value="concat(ROMsize,' ',ROMsize/@unit)"/>
+ <Map keytype="constant" key="Address" valuetype="string" value="Address"/>
+ <Map keytype="constant" key="Relase Date" valuetype="string" value="ReleaseDate"/>
+ </Map>
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ </Map>
+ </TypeMap>
+
+ <!-- Type 01 : System -->
+ <TypeMap id="0x01">
+ <Map rootpath="/dmidecode/SystemInfo" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="SKU Number" valuetype="string" value="SKUnumber"/>
+ <Map keytype="constant" key="UUID" valuetype="string" value="SystemUUID"/>
+ <Map keytype="constant" key="Family" valuetype="string" value="Family"/>
+ <Map keytype="constant" key="Serial Number" valuetype="string" value="SerialNumber"/>
+ <Map keytype="constant" key="Version" valuetype="string" value="Version"/>
+ <Map keytype="constant" key="Product Name" valuetype="string" value="ProductName"/>
+ <Map keytype="constant" key="Wake-Up Type" valuetype="string" value="SystemWakeUpType"/>
+ <Map keytype="constant" key="Manufacturer" valuetype="string" value="Manufacturer"/>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- Type 02 : Base Board -->
+ <TypeMap id="0x02">
+ <Map rootpath="/dmidecode/BaseBoardInfo" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="Serial Number" valuetype="string" value="SerialNumber"/>
+ <Map keytype="constant" key="Version" valuetype="string" value="Version"/>
+ <Map keytype="constant" key="Product Name" valuetype="string" value="ProductName"/>
+ <Map keytype="constant" key="Manufacturer" valuetype="string" value="Manufacturer"/>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- Type 03 : Chassis -->
+ <TypeMap id="0x03">
+ <Map rootpath="/dmidecode/ChassisInfo" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="Boot-Up State" valuetype="string" value="ChassisStates/BootUp"/>
+ <Map keytype="constant" key="Power Supply State" valuetype="string" value="ChassisStates/PowerSupply"/>
+ <Map keytype="constant" key="Thermal State" valuetype="string" value="ChassisStates/Thermal"/>
+ <Map keytype="constant" key="Lock" valuetype="string" value="ChassisLock"/>
+ <Map keytype="constant" key="Serial Number" valuetype="string" value="SerialNumber"/>
+ <Map keytype="constant" key="Version" valuetype="string" value="Version"/>
+ <Map keytype="constant" key="Asset Tag" valuetype="string" value="AssetTag"/>
+ <Map keytype="constant" key="Security Status" valuetype="string" value="SecurityStatus"/>
+ <Map keytype="constant" key="Type" valuetype="string" value="ChassisType"/>
+ <Map keytype="constant" key="Manufacturer" valuetype="string" value="Manufacturer"/>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- Type 04 : Processor -->
+ <TypeMap id="0x04">
+ <Map rootpath="/dmidecode/ProcessorInfo" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="Status" valuetype="string" value="concat('Populated:', Populated)"/>
+ <Map keytype="constant" key="Part Number" valuetype="string" value="PartNumber"/>
+ <Map keytype="constant" key="Upgrade" valuetype="string" value="Upgrade"/>
+ <Map keytype="constant" key="Socket Designation" valuetype="string" value="SocketDesignation"/>
+ <Map keytype="constant" key="Family" valuetype="string" value="Family"/>
+ <Map keytype="constant" key="Characteristics" valuetype="list:string" value="Cores/Characteristics/Flag"/>
+ <Map keytype="constant" key="Current Speed" valuetype="integer" value="Frequencies/CurrentSpeed"/>
+ <Map keytype="constant" key="Thread Count" valuetype="integer" value="Cores/ThreadCount"/>
+ <Map keytype="constant" key="External Clock" valuetype="integer" value="Frequencies/ExternalClock"/>
+ <Map keytype="constant" key="Serial Number" valuetype="string" value="SerialNumber"/>
+ <Map keytype="constant" key="Version" valuetype="string" value="Manufacturer/Version"/>
+ <Map keytype="constant" key="Voltage" valuetype="string" value="concat(Voltages/Voltage, ' ', Voltages/Voltage/@unit)"/>
+ <Map keytype="constant" key="Max Speed" valuetype="integer" value="Frequencies/MaxSpeed"/>
+ <Map keytype="constant" key="Asset Tag" valuetype="string" value="AssetTag"/>
+ <Map keytype="constant" key="Core Enabled" valuetype="integer" value="Cores/CoresEnabled"/>
+ <Map keytype="constant" key="Type" valuetype="string" value="Type"/>
+ <Map keytype="constant" key="Core Count" valuetype="integer" value="Cores/CoreCount"/>
+ <Map keytype="constant" key="Manufacturer" valuetype="dict">
+ <Map keytype="constant" key="Vendor" valuetype="string" value="Manufacturer/Vendor"/>
+ <Map keytype="constant" key="Flags" valuetype="dict">
+ <Map keytype="string" key="CPUCore/cpu_flags/flag"
+ valuetype="boolean" value="CPUCore/cpu_flags/flag/@available"/>
+ </Map>
+ <Map keytype="constant" key="ID" valuetype="string" value="CPUCore/ID"/>
+ <Map keytype="constant" key="Signature" valuetype="string" value="CPUCore/Signature"/>
+ </Map>
+ <Map keytype="constant" key="L1 Cache Handle"
+ valuetype="string" value="Cache/Level[@level = '1']/@handle"/>
+ <Map keytype="constant" key="L2 Cache Handle"
+ valuetype="string" value="Cache/Level[@level = '2']/@handle"/>
+ <Map keytype="constant" key="L3 Cache Handle"
+ valuetype="string" value="Cache/Level[@level = '3']/@handle"/>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- Type 05 : Memory Controller -->
+ <TypeMap id="0x05">
+ <Map rootpath="/dmidecode/MemoryCtrlInfo" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="Associated Memory Slots"
+ valuetype="list:string" value="AssociatedMemorySlots/Slot"/>
+ <Map keytype="constant" key="Current Interleave" valuetype="string" value="CurrentInterleave"/>
+ <Map keytype="constant" key="Enabled Error Correcting Capabilities"
+ valuetype="list:string" value="EnabledErrorCorrection/Capability"
+ fixedsize="6" index_attr="index"/>
+ <Map keytype="constant" key="Error Correcting Capabilities"
+ valuetype="list:string" value="ErrorCorrection/Capabilities/Capability"
+ fixedsize="6" index_attr="index"/>
+ <Map keytype="constant" key="Error Detecting Method"
+ valuetype="string" value="ErrorCorrection/CorrectionMethod"/>
+ <Map keytype="constant" key="Maximum Memory Module Size"
+ valuetype="string" value="concat(MaxMemoryModuleSize,' ',MaxMemoryModuleSize/@unit)"/>
+ <Map keytype="constant" key="Maximum Total Memory Size"
+ valuetype="string" value="concat(MaxTotalMemorySize,' ',MaxTotalMemorySize/@unit)"/>
+ <Map rootpath="Voltages" keytype="constant" key="Memory Module Voltage" valuetype="dict">
+ <Map keytype="string" key="Voltage/@key_compound" valuetype="boolean" value="Voltage/@available"/>
+ </Map>
+ <Map keytype="constant" key="Supported Interleave" valuetype="string" value="SupportedInterleave"/>
+ <Map keytype="constant" key="Supported Memory Types"
+ valuetype="list:string" value="SupportedTypes/ModuleType" fixedsize="11" index_attr="index"/>
+ <Map keytype="constant" key="Supported Speeds"
+ valuetype="list:string" value="SupportedSpeeds/Speed" emptyIsNone="1"/>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- Type 06 : Memory Module -->
+ <TypeMap id="0x06">
+ <Map rootpath="/dmidecode/MemoryModuleInfo" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="Bank Connections"
+ valuetype="list:integer" value="BankConnections/Connection"/>
+ <Map keytype="constant" key="Current Speed"
+ valuetype="string" value="concat(ModuleSpeed,' ',ModuleSpeed/@unit)" emptyValue="Unknown"/>
+ <Map keytype="constant" key="Enabled Size" valuetype="dict">
+ <Map keytype="constant" key="Connection" valuetype="string" value="EnabledSize/@Connection"/>
+ <Map keytype="constant" key="Size"
+ valuetype="string" value="concat(EnabledSize,' ',EnabledSize/@unit)"/>
+ </Map>
+ <Map keytype="constant" key="Error Status" valuetype="boolean" value="ModuleErrorStatus/@Error"/>
+ <Map keytype="constant" key="Installed Size" valuetype="dict">
+ <Map keytype="constant" key="Connection" valuetype="string" value="InstalledSize/@Connection"/>
+ <Map keytype="constant" key="Size"
+ valuetype="string" value="concat(InstalledSize,' ',InstalledSize/@unit)"/>
+ </Map>
+ <Map keytype="constant" key="Socket Designation" valuetype="string" value="SocketDesignation"/>
+ <Map keytype="constant" key="Type"
+ valuetype="list:string" value="Type/ModuleType" fixedsize="11" index_attr="index"/>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- Type 07 : Cache -->
+ <TypeMap id="0x07">
+ <Map rootpath="/dmidecode/CacheInfo" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="System Type" valuetype="string" value="SystemType"/>
+ <Map keytype="constant" key="Socket Designation" valuetype="string" value="SocketDesignation"/>
+ <Map keytype="constant" key="Installed SRAM Type"
+ valuetype="list:string" value="InstalledSRAMtypes/CacheType" fixedsize="7" index_attr="index"/>
+ <Map keytype="constant" key="Supported SRAM Type"
+ valuetype="list:string" value="SupportedSRAMtypes/CacheType" fixedsize="7" index_attr="index"/>
+ <Map keytype="constant" key="Associativity" valuetype="string" value="Associativity"/>
+ <Map keytype="constant" key="Maximum Size" valuetype="string"
+ value="concat(MaximumSize,' ',MaximumSize/@unit)"/>
+ <Map keytype="constant" key="Installed Size" valuetype="string"
+ value="concat(InstalledSize,' ',InstalledSize/@unit)"/>
+ <Map keytype="constant" key="Location" valuetype="string" value="CacheLocation"/>
+ <Map keytype="constant" key="Error Correction Type" valuetype="string" value="ErrorCorrectionType"/>
+ <Map keytype="constant" key="Speed" valuetype="string" value="Speed" emptyValue="Unknown"/>
+ <Map keytype="constant" key="Operational Mode" valuetype="string" value="OperationalMode"/>
+ <Map keytype="constant" key="Configuration" valuetype="dict">
+ <Map keytype="constant" key="Socketed" valuetype="boolean" value="@Socketed"/>
+ <Map keytype="constant" key="Enabled" valuetype="boolean" value="@Enabled"/>
+ <Map keytype="constant" key="Level" valuetype="integer" value="@Level"/>
+ </Map>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- Type 08 : Port Connector -->
+ <TypeMap id="0x08">
+ <Map rootpath="/dmidecode/PortConnectorInfo" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="External Reference Designator"
+ valuetype="string" value="DesignatorRef[@type='external']"/>
+ <Map keytype="constant" key="Port Type" valuetype="string" value="PortType"/>
+ <Map keytype="constant" key="External Connector Type"
+ valuetype="string" value="Connector[@type='external']"/>
+ <Map keytype="constant" key="Internal Reference Designator"
+ valuetype="string" value="DesignatorRef[@type='internal']"/>
+ <Map keytype="constant" key="Internal Connector Type"
+ valuetype="string" value="Connector[@type='internal']"/>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- Type 09 : System Slots -->
+ <TypeMap id="0x09">
+ <Map rootpath="/dmidecode/SystemSlots" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="Designation" valuetype="string" value="Designation"/>
+ <Map keytype="constant" key="Current Usage" valuetype="string" value="CurrentUsage"/>
+ <Map keytype="constant" key="Characteristics"
+ valuetype="list:string" value="SlotCharacteristics/Characteristic"
+ fixedsize="10" index_attr="index"/>
+ <Map keytype="constant" key="SlotLength" valuetype="string" value="SlotLength"/>
+ <Map keytype="constant" key="SlotId" valuetype="string" value="SlotID/@id"/>
+ <Map keytype="constant" key="Type:SlotBusWidth" valuetype="string" value="SlotWidth"/>
+ <Map keytype="constant" key="Type:SlotType" valuetype="string" value="SlotType"/>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- Type 10 : On-Board Devices -->
+ <TypeMap id="0x0A">
+ <Map rootpath="/dmidecode/OnBoardDevicesInfo" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="dmi_on_board_devices" valuetype="list:dict" value="dmi_on_board_devices">
+ <Map keytype="constant" key="Enabled" valuetype="boolean" value="Device/@Enabled"/>
+ <Map keytype="constant" key="Type" valuetype="string" value="Device/Type"/>
+ <Map keytype="constant" key="Description" valuetype="string" value="Device/Description"/>
+ </Map>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- Type 11 : OEM Strings -->
+ <TypeMap id="0x0B">
+ <Map rootpath="/dmidecode/OEMstrings" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="Strings" valuetype="dict">
+ <Map keytype="integer" key="Record/@index" valuetype="string" value="Record"/>
+ </Map>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- Type 12 : System Configuration Options -->
+ <TypeMap id="0x0C">
+ <Map rootpath="/dmidecode/SysConfigOptions" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map rootpath="Options" keytype="constant" key="Options" valuetype="dict">
+ <Map keytype="integer" key="Option/@index" valuetype="string" value="Option"/>
+ </Map>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- Type 13 : BIOS Language -->
+ <TypeMap id="0x0D">
+ <Map rootpath="/dmidecode/BIOSlanguage" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="Currently Installed Language"
+ valuetype="list:string" value="Installed/Language"/>
+ <Map keytype="constant" key="Installed Languages"
+ valuetype="integer" value="@installable_languages"/>
+ </Map>
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ </Map>
+ </TypeMap>
+
+ <!-- FIXME : Type 14 : Group Associations -->
+ <TypeMap id="0x0E">
+ </TypeMap>
+
+ <!-- Type 15 : System Event Log -->
+ <TypeMap id="0x0F">
+ <Map rootpath="/dmidecode/SysEventLog" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="Status"
+ valuetype="string" value="concat(Status/@Valid, ', ', Status/@Full)"/>
+ <Map keytype="constant" key="Access Method" valuetype="string" value="Access/AccessMethod"/>
+ <Map keytype="constant" key="Header Format" valuetype="string" value="Access/Header/Format"/>
+ <Map keytype="constant" key="Supported Log Type Descriptors" valuetype="string" value="LogTypes/@count"/>
+ <Map keytype="constant" key="Header Start Offset" valuetype="string" value="Access/Header/OffsetStart"/>
+ <Map keytype="constant" key="Change Token" valuetype="string" value="Access/Header/ChangeToken"/>
+ <Map keytype="constant" key="Header Length" valuetype="string" value="Access/Header/Length"/>
+ <Map keytype="constant" key="Access Address" valuetype="string" value="Access/Address/@Data"/>
+ <Map keytype="constant" key="Area Length" valuetype="string" value="Access/@AreaLength"/>
+ <Map keytype="constant" key="Data Start Offset" valuetype="string" value="Access/Header/DataOffset"/>
+ <Map keytype="constant" key="DMI Event Log Descriptors" valuetype="list:dict" value="LogTypes/LogType">
+ <Map keytype="constant" key="Descriptor" valuetype="string" value="Descriptor"/>
+ <Map keytype="constant" key="Data Format" valuetype="string" value="Format"/>
+ </Map>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- Type 16 : Physical Memory Array -->
+ <TypeMap id="0x10">
+ <Map rootpath="/dmidecode/PhysicalMemoryArray" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="Maximum Capacity"
+ valuetype="string" value="concat(MaxCapacity, ' ', MaxCapacity/@unit)"/>
+ <Map keytype="constant" key="Number Of Devices" valuetype="integer" value="@NumDevices"/>
+ <Map keytype="constant" key="Use" valuetype="string" value="Use"/>
+ <Map keytype="constant" key="Error Information Handle"
+ valuetype="string" value="ErrorInfoHandle" emptyValue="Not Provided"/>
+ <Map keytype="constant" key="Error Correction Type" valuetype="string" value="ErrorCorrectionType"/>
+ <Map keytype="constant" key="Location" valuetype="string" value="Location"/>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- Type 17 : Memory Device -->
+ <TypeMap id="0x11">
+ <Map rootpath="/dmidecode/MemoryDevice" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="Manufacturer" valuetype="string" value="Manufacturer"/>
+ <Map keytype="constant" key="Set" valuetype="integer" value="Set" emptyIsNone="1"/>
+ <Map keytype="constant" key="Data Width"
+ valuetype="string" value="concat(DataWidth, ' ', DataWidth/@unit)"/>
+ <Map keytype="constant" key="Part Number" valuetype="string" value="PartNumber"/>
+ <Map keytype="constant" key="Type" valuetype="string" value="Type"/>
+ <Map keytype="constant" key="Bank Locator" valuetype="string" value="BankLocator"/>
+ <Map keytype="constant" key="Speed"
+ valuetype="string" value="concat(Speed, ' ', Speed/@unit, ' (',Speed/@speed_ns,'ns)')"/>
+ <Map keytype="constant" key="Error Information Handle"
+ valuetype="string" value="ErrorInfoHandle" emptyValue="No Error"/>
+ <Map keytype="constant" key="Locator" valuetype="string" value="Locator"/>
+ <Map keytype="constant" key="Serial Number" valuetype="string" value="SerialNumber"/>
+ <Map keytype="constant" key="Total Width"
+ valuetype="string" value="concat(TotalWidth, ' ', TotalWidth/@unit)"/>
+ <Map keytype="constant" key="AssetTag" valuetype="string" value="AssetTag"/>
+ <Map keytype="constant" key="Type Detail" valuetype="list:string" value="TypeDetails/flag"
+ fixedsize="12" index_attr="index"/>
+ <Map keytype="constant" key="Array Handle" valuetype="string" value="@ArrayHandle"/>
+ <Map keytype="constant" key="Form Factor" valuetype="string" value="FormFactor"/>
+ <Map keytype="constant" key="Size"
+ valuetype="string" value="concat(Size, ' ', Size/@unit)" emptyIsNone="1"/>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- Type 18 : 32-bit Memory Error -->
+ <TypeMap id="0x12">
+ <Map rootpath="/dmidecode/MemoryErrorInfo[@bits='32']" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="Device Address"
+ valuetype="string" value="DeviceAddr" emptyValue="Unknown"/>
+ <Map keytype="constant" key="Granularity" valuetype="string" value="Granularity"/>
+ <Map keytype="constant" key="Memory Array Address"
+ valuetype="string" value="MemArrayAddr" emptyValue="Unknown"/>
+ <Map keytype="constant" key="Operation" valuetype="string" value="Operation"/>
+ <Map keytype="constant" key="Resolution" valuetype="string" value="Resolution" emptyValue="Unknown"/>
+ <Map keytype="constant" key="Type" valuetype="string" value="Type"/>
+ <Map keytype="constant" key="Vendor Syndrome"
+ valuetype="string" value="VendorSyndrome" emptyValue="Unknown"/>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- Type 19 : Memory Array Mapped Address -->
+ <TypeMap id="0x13">
+ <Map rootpath="/dmidecode/MemoryArrayMappedAddress" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="Ending Address" valuetype="string" value="EndAddress"/>
+ <Map keytype="constant" key="Partition Width" valuetype="string" value="PartitionWidth"/>
+ <Map keytype="constant" key="Physical Array Handle" valuetype="string" value="PhysicalArrayHandle"/>
+ <Map keytype="constant" key="Range Size"
+ valuetype="string" value="concat(RangeSize, ' ', RangeSize/@unit)"/>
+ <Map keytype="constant" key="Starting Address" valuetype="string" value="StartAddress"/>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- Type 20 : Memory Device Mapped Address -->
+ <TypeMap id="0x14">
+ <Map rootpath="/dmidecode/MemoryDeviceMappedAddress" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="Interleave Data Depth"
+ valuetype="integer" value="InterleaveDataDepth"/>
+ <Map keytype="constant" key="Ending Address" valuetype="string" value="EndAddress"/>
+ <Map keytype="constant" key="Memory Array Mapped Address Handle"
+ valuetype="string" value="MemArrayMappedAddrHandle"/>
+ <Map keytype="constant" key="Partition Row Position" valuetype="integer" value="PartitionRowPosition"/>
+ <Map keytype="constant" key="Physical Device Handle" valuetype="string" value="PhysicalDeviceHandle"/>
+ <Map keytype="constant" key="Range Size"
+ valuetype="string" value="concat(RangeSize,' ',RangeSize/@unit)"/>
+ <Map keytype="constant" key="Starting Address" valuetype="string" value="StartAddress"/>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- Type 21 : Built-in Pointing Device -->
+ <TypeMap id="0x15">
+ <Map rootpath="/dmidecode/BuiltIntPointingDevice" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="Buttons" valuetype="string" value="Buttons"/>
+ <Map keytype="constant" key="Interface" valuetype="string" value="DeviceInterface"/>
+ <Map keytype="constant" key="Type" valuetype="string" value="DeviceType"/>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- Type 22 : Portable Battery -->
+ <TypeMap id="0x16">
+ <Map rootpath="/dmidecode/PortableBattery" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="Design Capacity"
+ valuetype="string" value="concat(DesignCapacity,' ',DesignCapacity/@unit)"/>
+ <Map keytype="constant" key="Design Voltage"
+ valuetype="string" value="concat(DesignVoltage,' ',DesignVoltage/@unit)"/>
+ <Map keytype="constant" key="Location" valuetype="string" value="Location"/>
+ <Map keytype="constant" key="Manufacturer" valuetype="string" value="Manufacturer"/>
+ <Map keytype="constant" key="Maximum Error"
+ valuetype="string" value="MaximumError" emptyValue="Unknown"/>
+ <Map keytype="constant" key="Name" valuetype="string" value="Name"/>
+ <Map keytype="constant" key="OEM-specific Information" valuetype="string" value="OEMinformation"/>
+ <Map keytype="constant" key="SBDS Chemistry" valuetype="string" value="SBDSchemistry"/>
+ <Map keytype="constant" key="SBDS Manufacture Date" valuetype="string" value="SBDSmanufactureDate"/>
+ <Map keytype="constant" key="SBDS Serial Number" valuetype="string" value="SBDSserialNumber"/>
+ <Map keytype="constant" key="SBDS Version" valuetype="string" value="SBDSversion"/>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- Type 23 : System Reset -->
+ <TypeMap id="0x17">
+ <Map rootpath="/dmidecode/SystemReset" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="Boot Option" valuetype="string" value="BootOption"/>
+ <Map keytype="constant" key="Boot Option On Limit" valuetype="string" value="BootOptionOnLimit"/>
+ <Map keytype="constant" key="Reset Count" valuetype="string" value="ResetCount" emptyValue="Unknown"/>
+ <Map keytype="constant" key="Reset Limit" valuetype="string" value="ResetLimit" emptyValue="Unknown"/>
+ <Map keytype="constant" key="Status" valuetype="string" value="Status"/>
+ <Map keytype="constant" key="Timeout" valuetype="string" value="Timeout" emptyValue="Unknown"/>
+ <Map keytype="constant" key="Timer Interval"
+ valuetype="string" value="TimerInterval" emptyValue="Unknown"/>
+ <Map keytype="constant" key="Watchdog Timer" valuetype="string" value="WatchdogTimer"/>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- Type 24 : Hardware Security -->
+ <TypeMap id="0x18">
+ <Map rootpath="/dmidecode/HardwareSecurity" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="Administrator Password Status"
+ valuetype="string" value="AdministratorPassword"/>
+ <Map keytype="constant" key="Front Panel Reset Status"
+ valuetype="string" value="FronPanelReset"/>
+ <Map keytype="constant" key="Keyboard Password Status"
+ valuetype="string" value="KeyboardPassword"/>
+ <Map keytype="constant" key="Power-On Password Status"
+ valuetype="string" value="PowerOnPassword"/>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- Type 25 : System Power Controls -->
+ <TypeMap id="0x19">
+ <Map rootpath="/dmidecode/SystemPowerCtrls" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="Next Scheduled Power-on" valuetype="string" value="NextSchedPowerOn"/>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- Type 26 : Voltage Probe -->
+ <TypeMap id="0x1A">
+ <Map rootpath="/dmidecode/Probe[@probetype='Voltage']" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="Accuracy"
+ valuetype="string" value="concat(Accuracy,' ',Accuracy/@unit)"/>
+ <Map keytype="constant" key="Description"
+ valuetype="string" value="Description"/>
+ <Map keytype="constant" key="Location"
+ valuetype="string" value="Location"/>
+ <Map keytype="constant" key="Maximum Value"
+ valuetype="string" value="concat(MaxValue,' ',MaxValue/@unit)"/>
+ <Map keytype="constant" key="Minimum Value"
+ valuetype="string" value="concat(MinValue,' ',MinValue/@unit)"/>
+ <Map keytype="constant" key="OEM-specific Information"
+ valuetype="string" value="OEMinformation"/>
+ <Map keytype="constant" key="Resolution"
+ valuetype="string" value="concat(Resolution,' ',Resolution/@unit)"/>
+ <Map keytype="constant" key="Status" valuetype="string" value="Status"/>
+ <Map keytype="constant" key="Tolerance" valuetype="string" value="Tolerance" emptyValue="Unknown"/>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- Type 27 : Cooling Device -->
+ <TypeMap id="0x1B">
+ <Map rootpath="/dmidecode/CoolingDevice" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="OEM-specific Information" valuetype="string" value="OEMinformation"/>
+ <Map keytype="constant" key="Status" valuetype="string" value="Status"/>
+ <Map keytype="constant" key="Type" valuetype="string" value="Type"/>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- Type 28 : Temperature Probe -->
+ <TypeMap id="0x1C">
+ <Map rootpath="/dmidecode/Probe[@probetype='Temperature']" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="Accuracy"
+ valuetype="string" value="concat(Accuracy,' ',Accuracy/@unit)" emptyValue="Unknown"/>
+ <Map keytype="constant" key="Description"
+ valuetype="string" value="Description"/>
+ <Map keytype="constant" key="Location"
+ valuetype="string" value="Location"/>
+ <Map keytype="constant" key="Maximum Value"
+ valuetype="string" value="concat(MaxValue,' deg ',MaxValue/@unit)"/>
+ <Map keytype="constant" key="Minimum Value"
+ valuetype="string" value="concat(MinValue,' deg ',MinValue/@unit)"/>
+ <Map keytype="constant" key="OEM-specific Information"
+ valuetype="string" value="OEMinformation"/>
+ <Map keytype="constant" key="Resolution"
+ valuetype="string" value="concat(Resolution,' deg ',Resolution/@unit)"/>
+ <Map keytype="constant" key="Status" valuetype="string" value="Status"/>
+ <Map keytype="constant" key="Tolerance" valuetype="string" value="Tolerance" emptyValue="Unknown"/>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- FIXME : Type 29 : Electrical Current Probe -->
+ <TypeMap id="0x1D">
+ </TypeMap>
+
+ <!-- Type 30 : Out-of-band Remote Access -->
+ <TypeMap id="0x1E">
+ <Map rootpath="/dmidecode/RemoteAccess" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="Inbound Connection Enabled"
+ valuetype="boolean" value="@InboundConnectionEnabled"/>
+ <Map keytype="constant" key="Manufacturer Name" valuetype="string" value="ManufacturerName"/>
+ <Map keytype="constant" key="Outbound Connection Enabled"
+ valuetype="boolean" value="@OutboundConnectionEnabled"/>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- FIXME : Type 31 : Boot Integrity Services -->
+ <TypeMap id="0x1F">
+ </TypeMap>
+
+ <!-- Type 32 : System Boot -->
+ <TypeMap id="0x20">
+ <Map rootpath="/dmidecode/SystemBootInfo" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="Status" valuetype="string" value="Status"/>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- Type 33 : 64-bit Memory Error -->
+ <TypeMap id="0x21">
+ <Map rootpath="/dmidecode/MemoryErrorInfo[@bits='64']" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="Device Address" valuetype="string" value="DeviceAddr"/>
+ <Map keytype="constant" key="Granularity" valuetype="string" value="Granularity"/>
+ <Map keytype="constant" key="Memory Array Address" valuetype="string" value="MemArrayAddr"/>
+ <Map keytype="constant" key="Operation" valuetype="string" value="Operation"/>
+ <Map keytype="constant" key="Resolution"
+ valuetype="string" value="Resolution" emptyValue="Unknown"/>
+ <Map keytype="constant" key="Type" valuetype="string" value="Type"/>
+ <Map keytype="constant" key="Vendor Syndrome"
+ valuetype="string" value="VendorSyndrome" emptyValue="Unknown"/>
+ </Map>
+ </Map>
+ </TypeMap>
+
+ <!-- FIXME : Type 34 : Management Device -->
+ <TypeMap id="0x22">
+ </TypeMap>
+
+ <!-- FIXME : Type 35 : Management Device Component -->
+ <TypeMap id="0x23">
+ </TypeMap>
+
+ <!-- FIXME : Type 36 : Management Device Threshold Data -->
+ <TypeMap id="0x24">
+ </TypeMap>
+
+ <!-- FIXME : Type 37 : Memory Channel -->
+ <TypeMap id="0x25">
+ </TypeMap>
+
+ <!-- Type 38 : IPMI Device -->
+ <TypeMap id="0x26">
+ <Map rootpath="/dmidecode/IPMIdeviceInfo" keytype="string" key="@handle" valuetype="dict">
+ <Map keytype="constant" key="dmi_type" valuetype="integer" value="@type"/>
+ <Map keytype="constant" key="dmi_handle" valuetype="string" value="@handle"/>
+ <Map keytype="constant" key="dmi_size" valuetype="integer" value="@size"/>
+ <Map keytype="constant" key="data" valuetype="dict">
+ <Map keytype="constant" key="Base Address"
+ valuetype="string" value="concat(BaseAddress, ' (',BaseAddress/@interface,')')"/>
+ <Map keytype="constant" key="I2C Slave Address" valuetype="string" value="@I2CslaveAddr"/>
+ <Map keytype="constant" key="Interface Type" valuetype="string" value="InterfaceType"/>
+ <Map keytype="constant" key="NV Storage Device: Not Present"
+ valuetype="string" value="NVstorageDevice[@NotPresent='1']" emptyIsNone="1"/>
+ <Map keytype="constant" key="Register Spacing" valuetype="string" value="RegisterSpacing"/>
+ <Map keytype="constant" key="Specification Version" valuetype="string" value="@spec_version"/>
+ </Map>
+ </Map>
+
+ </TypeMap>
+
+ <!-- FIXME : Type 39 : Power Supply -->
+ <TypeMap id="0x27">
+ </TypeMap>
+ </TypeMapping>
+
+ <GroupMapping>
+ <!-- Mapping setup for BIOS DMI data -->
+ <Mapping name="bios">
+ <TypeMap id="0x00" />
+ <TypeMap id="0x0D" />
+ </Mapping>
+
+ <!-- Mapping setup for processor info -->
+ <Mapping name="processor">
+ <TypeMap id="0x04" />
+ </Mapping>
+
+ <!-- Mapping setup for chassis info -->
+ <Mapping name="chassis">
+ <TypeMap id="0x03" />
+ </Mapping>
+
+ <!-- Mapping setup for memory info -->
+ <Mapping name="memory">
+ <TypeMap id="0x10" />
+ <TypeMap id="0x11" />
+ </Mapping>
+
+ <!-- Mapping setup for cache info -->
+ <Mapping name="cache">
+ <TypeMap id="0x07" />
+ </Mapping>
+
+ <!-- Mapping setup for system info -->
+ <Mapping name="system">
+ <TypeMap id="0x01" />
+ <TypeMap id="0x0C" />
+ <TypeMap id="0x20" />
+ </Mapping>
+
+ <!-- Mapping setup for baseboard info -->
+ <Mapping name="baseboard">
+ <TypeMap id="0x02" />
+ <TypeMap id="0x0A" />
+ </Mapping>
+
+ <!-- Mapping setup for slot info -->
+ <Mapping name="slot">
+ <TypeMap id="0x09" />
+ </Mapping>
+
+ <!-- Mapping setup for connector info -->
+ <Mapping name="connector">
+ <TypeMap id="0x08" />
+ </Mapping>
+
+ <!-- Mapping setup for retrieving all info at once -->
+ <Mapping name="all">
+ <TypeMap id="0x00"/>
+ <TypeMap id="0x01"/>
+ <TypeMap id="0x02"/>
+ <TypeMap id="0x03"/>
+ <TypeMap id="0x04"/>
+ <TypeMap id="0x05"/>
+ <TypeMap id="0x06"/>
+ <TypeMap id="0x07"/>
+ <TypeMap id="0x08"/>
+ <TypeMap id="0x09"/>
+ <TypeMap id="0x0A"/>
+ <TypeMap id="0x0B"/>
+ <TypeMap id="0x0C"/>
+ <TypeMap id="0x0D"/>
+ <TypeMap id="0x0E"/>
+ <TypeMap id="0x0F"/>
+ <TypeMap id="0x10"/>
+ <TypeMap id="0x11"/>
+ <TypeMap id="0x12"/>
+ <TypeMap id="0x13"/>
+ <TypeMap id="0x14"/>
+ <TypeMap id="0x15"/>
+ <TypeMap id="0x16"/>
+ <TypeMap id="0x17"/>
+ <TypeMap id="0x18"/>
+ <TypeMap id="0x19"/>
+ <TypeMap id="0x1A"/>
+ <TypeMap id="0x1B"/>
+ <TypeMap id="0x1C"/>
+ <TypeMap id="0x1D"/>
+ <TypeMap id="0x1E"/>
+ <TypeMap id="0x1F"/>
+ <TypeMap id="0x20"/>
+ <TypeMap id="0x21"/>
+ <TypeMap id="0x22"/>
+ <TypeMap id="0x23"/>
+ <TypeMap id="0x24"/>
+ <TypeMap id="0x25"/>
+ <TypeMap id="0x26"/>
+ <TypeMap id="0x27"/>
+ <TypeMap id="0x28"/>
+ <TypeMap id="0x29"/>
+ </Mapping>
+ </GroupMapping>
+
+</dmidecode_mapping>
diff --git a/src/setup-dbg.py b/src/setup-dbg.py
index e4b3b37..9602abc 100644
--- a/src/setup-dbg.py
+++ b/src/setup-dbg.py
@@ -1,25 +1,80 @@
+#
+# setup-dbg.py
+# Python distutil package setup, with debug features enabled
+#
+# Copyright 2009 David Sommerseth <davids@redhat.com>
+# Copyright 2007-2009 Nima Talebi <nima@autonomy.net.au>
+#
+# 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; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# For the avoidance of doubt the "preferred form" of this code is one which
+# is in an open unpatent encumbered format. Where cryptographic key signing
+# forms part of the process of creating an executable the information
+# including keys needed to generate an equivalently functional executable
+# are deemed to be part of the source code.
+#
+
from distutils.core import setup, Extension
+from setup_common import *
+
+#
+# Some default values
+#
+incdir = []
+libdir = []
+libs = []
+
+# Get libxml2 info
+libxml2_include(incdir)
+libxml2_lib(libdir, libs)
+
+# misc info
+dmidec_version = get_version()
+
+#
+# Python setup
+#
setup(
name = "python-dmidecode-dbg",
- version = "2.10.6",
+ version = dmidec_version,
+ license='GPL-2',
description = "Python extension module for dmidecode",
- author = "Nima Talebi",
- author_email = "nima@autonomy.net.au",
- url = "http://projects.autonomy.net.au/dmidecode/",
+ author = "Nima Talebi & David Sommerseth",
+ author_email = "nima@it.net.au, davids@redhat.com",
+ url = "http://projects.autonomy.net.au/python-dmidecode/",
+ data_files = [ ('share/python-dmidecode-dbg', ['src/pymap.xml']) ],
ext_modules = [
Extension(
- "dmidecode",
+ "dmidecodemod",
sources = [
"src/dmidecodemodule.c",
- "src/dmihelper.c",
"src/util.c",
"src/dmioem.c",
- "src/dmidecode.c"
+ "src/dmidecode.c",
+ "src/dmixml.c",
+ "src/dmierror.c",
+ "src/xmlpythonizer.c",
+ "src/efi.c",
+ "src/dmidump.c"
],
- library_dirs = [ "/home/nima/dev-room/projects/dmidecode" ],
- libraries = [ "util" ],
- #libraries = [ "util", "efence" ],
+ include_dirs = incdir,
+ library_dirs = libdir,
+ libraries = libs,
+ undef_macros = [ "NDEBUG" ]
)
- ]
+ ],
+ py_modules = [ "dmidecode" ]
)
diff --git a/src/setup.py b/src/setup.py
index 69b1d80..d33db64 100644
--- a/src/setup.py
+++ b/src/setup.py
@@ -1,25 +1,80 @@
+#
+# setup.py
+# Python distutil package setup
+#
+# Copyright 2009 David Sommerseth <davids@redhat.com>
+# Copyright 2007-2009 Nima Talebi <nima@autonomy.net.au>
+#
+# 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; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# For the avoidance of doubt the "preferred form" of this code is one which
+# is in an open unpatent encumbered format. Where cryptographic key signing
+# forms part of the process of creating an executable the information
+# including keys needed to generate an equivalently functional executable
+# are deemed to be part of the source code.
+#
+
from distutils.core import setup, Extension
+from setup_common import *
+
+#
+# Some default values
+#
+incdir = []
+libdir = []
+libs = []
+
+# Get libxml2 info
+libxml2_include(incdir)
+libxml2_lib(libdir, libs)
+
+# misc info
+dmidec_version = get_version()
+
+#
+# Python setup
+#
setup(
name = "python-dmidecode",
- version = "2.10.6",
+ version = dmidec_version,
+ license='GPL-2',
description = "Python extension module for dmidecode",
- author = "Nima Talebi",
- author_email = "nima@autonomy.net.au",
- url = "http://projects.autonomy.net.au/dmidecode/",
+ author = "Nima Talebi & David Sommerseth",
+ author_email = "nima@it.net.au, davids@redhat.com",
+ url = "http://projects.autonomy.net.au/python-dmidecode/",
+ data_files = [ ('share/python-dmidecode', ['src/pymap.xml']) ],
ext_modules = [
Extension(
- "dmidecode",
+ "dmidecodemod",
sources = [
"src/dmidecodemodule.c",
- "src/dmihelper.c",
"src/util.c",
"src/dmioem.c",
- "src/dmidecode.c"
+ "src/dmidecode.c",
+ "src/dmixml.c",
+ "src/dmierror.c",
+ "src/xmlpythonizer.c",
+ "src/efi.c",
+ "src/dmidump.c"
],
- library_dirs = [ "/home/nima/dev-room/projects/dmidecode" ],
- libraries = [ "util" ],
- #libraries = [ "util", "efence" ],
+ include_dirs = incdir,
+ library_dirs = libdir,
+ libraries = libs,
+ undef_macros = [ "NDEBUG" ]
)
- ]
+ ],
+ py_modules = [ "dmidecode" ]
)
diff --git a/src/setup_common.py b/src/setup_common.py
new file mode 100644
index 0000000..fdf5c8c
--- /dev/null
+++ b/src/setup_common.py
@@ -0,0 +1,93 @@
+#
+# setup-common.py
+# Helper functions for retrieving libxml2 arguments needed for compilation
+# and other functions which is used in both setup.py and setup-dbg.py
+#
+# Copyright 2009 David Sommerseth <davids@redhat.com>
+#
+# 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; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# For the avoidance of doubt the "preferred form" of this code is one which
+# is in an open unpatent encumbered format. Where cryptographic key signing
+# forms part of the process of creating an executable the information
+# including keys needed to generate an equivalently functional executable
+# are deemed to be part of the source code.
+#
+
+import commands, sys
+from os import path as os_path
+from distutils.sysconfig import get_python_lib
+
+# libxml2 - C flags
+def libxml2_include(incdir):
+ (res, libxml2_cflags) = commands.getstatusoutput("xml2-config --cflags")
+ if res != 0:
+ print "Could not build python-dmidecode."
+ print "Could not run xml2-config, is libxml2 installed?"
+ print "Also the development libraries?"
+ sys.exit(1)
+
+ # Parse the xml2-config --cflags response
+ for l in libxml2_cflags.split(" "):
+ if l.find('-I') == 0:
+ incdir.append(l.replace("-I", "", 1))
+
+
+
+# libxml2 - library flags
+def libxml2_lib(libdir, libs):
+ libdir.append(get_python_lib(1))
+ if os_path.exists("/etc/debian_version"): #. XXX: Debian Workaround...
+ libdir.append("/usr/lib/pymodules/python%d.%d"%sys.version_info[0:2])
+
+ (res, libxml2_libs) = commands.getstatusoutput("xml2-config --libs")
+ if res != 0:
+ print "Could not build python-dmidecode."
+ print "Could not run xml2-config, is libxml2 installed?"
+ print "Also the development libraries?"
+ sys.exit(1)
+
+ # Parse the xml2-config --libs response
+ for l in libxml2_libs.split(" "):
+ if l.find('-L') == 0:
+ libdir.append(l.replace("-L", "", 1))
+ elif l.find('-l') == 0:
+ libs.append(l.replace("-l", "", 1))
+
+ # this library is not reported and we need it anyway
+ libs.append('xml2mod')
+
+
+
+# Get version from src/version.h
+def get_version():
+ version = "0.0.0"
+ try:
+ f = open("src/version.h")
+ except:
+ f = open("version.h")
+
+ try:
+ for line in f:
+ part = line.split(" ")
+ if part[0] == "#define":
+ if part[1] == "VERSION":
+ version = part[2].strip().strip('"')
+ break
+ finally:
+ f.close()
+
+ return version
+
diff --git a/src/types.h b/src/types.h
index b124ecf..5f3dcd4 100644
--- a/src/types.h
+++ b/src/types.h
@@ -1,3 +1,29 @@
+/*
+ * This file is part of the dmidecode project.
+ *
+ * Copyright (C) 2002-2008 Jean Delvare <khali@linux-fr>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For the avoidance of doubt the "preferred form" of this code is one which
+ * is in an open unpatent encumbered format. Where cryptographic key signing
+ * forms part of the process of creating an executable the information
+ * including keys needed to generate an equivalently functional executable
+ * are deemed to be part of the source code.
+ */
+
#ifndef TYPES_H
#define TYPES_H
@@ -21,25 +47,25 @@ typedef unsigned int u32;
#ifdef BIGENDIAN
typedef struct {
- u32 h;
- u32 l;
+ u32 h;
+ u32 l;
} u64;
#else
typedef struct {
- u32 l;
- u32 h;
+ u32 l;
+ u32 h;
} u64;
#endif
#ifdef ALIGNMENT_WORKAROUND
static inline u64 U64(u32 low, u32 high)
{
- u64 self;
-
- self.l=low;
- self.h=high;
-
- return self;
+ u64 self;
+
+ self.l = low;
+ self.h = high;
+
+ return self;
}
#endif
diff --git a/src/util.c b/src/util.c
index 15d24a7..014b75d 100644
--- a/src/util.c
+++ b/src/util.c
@@ -1,3 +1,4 @@
+
/*
* Common "util" functions
* This file is part of the dmidecode project.
@@ -48,46 +49,41 @@
#include "util.h"
#ifndef USE_MMAP
-static int myread(int fd, u8 *buf, size_t count, const char *prefix)
+static int myread(int fd, u8 * buf, size_t count, const char *prefix)
{
- ssize_t r = 1;
- size_t r2 = 0;
-
- while (r2 != count && r != 0)
- {
- r = read(fd, buf + r2, count - r2);
- if (r == -1)
- {
- if (errno != EINTR)
- {
- close(fd);
- perror(prefix);
- return -1;
- }
- }
- else
- r2 += r;
- }
-
- if (r2 != count)
- {
- close(fd);
- fprintf(stderr, "%s: Unexpected end of file\n", prefix);
- return -1;
- }
-
- return 0;
+ ssize_t r = 1;
+ size_t r2 = 0;
+
+ while(r2 != count && r != 0) {
+ r = read(fd, buf + r2, count - r2);
+ if(r == -1) {
+ if(errno != EINTR) {
+ close(fd);
+ perror(prefix);
+ return -1;
+ }
+ } else
+ r2 += r;
+ }
+
+ if(r2 != count) {
+ close(fd);
+ fprintf(stderr, "%s: Unexpected end of file\n", prefix);
+ return -1;
+ }
+
+ return 0;
}
#endif
-int checksum(const u8 *buf, size_t len)
+int checksum(const u8 * buf, size_t len)
{
- u8 sum = 0;
- size_t a;
+ u8 sum = 0;
+ size_t a;
- for (a = 0; a < len; a++)
- sum += buf[a];
- return (sum == 0);
+ for(a = 0; a < len; a++)
+ sum += buf[a];
+ return (sum == 0);
}
/*
@@ -96,110 +92,101 @@ int checksum(const u8 *buf, size_t len)
*/
void *mem_chunk(size_t base, size_t len, const char *devmem)
{
- void *p;
- int fd;
+ void *p;
+ int fd;
+
#ifdef USE_MMAP
- size_t mmoffset;
- void *mmp;
+ size_t mmoffset;
+ void *mmp;
#endif
- if ((fd = open(devmem, O_RDONLY)) == -1)
- {
- perror(devmem);
- return NULL;
- }
-
- if ((p = malloc(len)) == NULL)
- {
- perror("malloc");
- return NULL;
- }
+ if((fd = open(devmem, O_RDONLY)) == -1) {
+ perror(devmem);
+ return NULL;
+ }
+ if((p = malloc(len)) == NULL) {
+ perror("malloc");
+ return NULL;
+ }
#ifdef USE_MMAP
#ifdef _SC_PAGESIZE
- mmoffset = base % sysconf(_SC_PAGESIZE);
+ mmoffset = base % sysconf(_SC_PAGESIZE);
#else
- mmoffset = base % getpagesize();
+ mmoffset = base % getpagesize();
#endif /* _SC_PAGESIZE */
- /*
- * Please note that we don't use mmap() for performance reasons here,
- * but to workaround problems many people encountered when trying
- * to read from /dev/mem using regular read() calls.
- */
- mmp = mmap(0, mmoffset + len, PROT_READ, MAP_SHARED, fd, base - mmoffset);
- if (mmp == MAP_FAILED)
- {
- fprintf(stderr, "%s: ", devmem);
- perror("mmap");
- free(p);
- return NULL;
- }
-
- memcpy(p, (u8 *)mmp + mmoffset, len);
-
- if (munmap(mmp, mmoffset + len) == -1)
- {
- fprintf(stderr, "%s: ", devmem);
- perror("munmap");
- }
+ /*
+ * Please note that we don't use mmap() for performance reasons here,
+ * but to workaround problems many people encountered when trying
+ * to read from /dev/mem using regular read() calls.
+ */
+ mmp = mmap(0, mmoffset + len, PROT_READ, MAP_SHARED, fd, base - mmoffset);
+ if(mmp == MAP_FAILED) {
+ fprintf(stderr, "%s: ", devmem);
+ perror("mmap");
+ free(p);
+ return NULL;
+ }
+
+ memcpy(p, (u8 *) mmp + mmoffset, len);
+
+ if(munmap(mmp, mmoffset + len) == -1) {
+ fprintf(stderr, "%s: ", devmem);
+ perror("munmap");
+ }
#else /* USE_MMAP */
- if (lseek(fd, base, SEEK_SET) == -1)
- {
- fprintf(stderr, "%s: ", devmem);
- perror("lseek");
- free(p);
- return NULL;
- }
-
- if (myread(fd, p, len, devmem) == -1)
- {
- free(p);
- return NULL;
- }
+ if(lseek(fd, base, SEEK_SET) == -1) {
+ fprintf(stderr, "%s: ", devmem);
+ perror("lseek");
+ free(p);
+ return NULL;
+ }
+
+ if(myread(fd, p, len, devmem) == -1) {
+ free(p);
+ return NULL;
+ }
#endif /* USE_MMAP */
- if (close(fd) == -1)
- perror(devmem);
+ if(close(fd) == -1)
+ perror(devmem);
- return p;
+ return p;
}
int write_dump(size_t base, size_t len, const void *data, const char *dumpfile, int add)
{
- FILE *f;
-
- f = fopen(dumpfile, add ? "r+b" : "wb");
- if (!f)
- {
- fprintf(stderr, "%s: ", dumpfile);
- perror("fopen");
- return -1;
- }
-
- if (fseek(f, base, SEEK_SET) != 0)
- {
- fprintf(stderr, "%s: ", dumpfile);
- perror("fseek");
- goto err_close;
- }
-
- if (fwrite(data, len, 1, f) != 1)
- {
- fprintf(stderr, "%s: ", dumpfile);
- perror("fwrite");
- goto err_close;
- }
-
- if (fclose(f))
- {
- fprintf(stderr, "%s: ", dumpfile);
- perror("fclose");
- return -1;
- }
-
- return 0;
-
-err_close:
- fclose(f);
- return -1;
+ FILE *f;
+
+ f = fopen(dumpfile, add ? "r+b" : "wb");
+ if(!f) {
+ fprintf(stderr, "%s: ", dumpfile);
+ perror("fopen");
+ return -1;
+ }
+
+ if(fseek(f, base, SEEK_SET) != 0) {
+ fprintf(stderr, "%s: ", dumpfile);
+ perror("fseek");
+ goto err_close;
+ }
+
+ if(fwrite(data, len, 1, f) != 1) {
+ fprintf(stderr, "%s: ", dumpfile);
+ perror("fwrite");
+ goto err_close;
+ }
+
+ if(fclose(f)) {
+ fprintf(stderr, "%s: ", dumpfile);
+ perror("fclose");
+ return -1;
+ }
+
+ return 0;
+
+ err_close:
+ fclose(f);
+ return -1;
}
+
diff --git a/src/util.h b/src/util.h
index 894bd2f..3effd0c 100644
--- a/src/util.h
+++ b/src/util.h
@@ -1,3 +1,4 @@
+
/*
* This file is part of the dmidecode project.
*
@@ -24,6 +25,6 @@
#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
-int checksum(const u8 *buf, size_t len);
+int checksum(const u8 * buf, size_t len);
void *mem_chunk(size_t base, size_t len, const char *devmem);
int write_dump(size_t base, size_t len, const void *data, const char *dumpfile, int add);
diff --git a/src/version.h b/src/version.h
index 050cf7a..70ea80d 100644
--- a/src/version.h
+++ b/src/version.h
@@ -1 +1 @@
-#define VERSION "2.9"
+#define VERSION "3.10.6"
diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c
new file mode 100644
index 0000000..ba018eb
--- /dev/null
+++ b/src/xmlpythonizer.c
@@ -0,0 +1,1183 @@
+/*. ******* coding:utf-8 AUTOHEADER START v1.1 *******
+ *. vim: fileencoding=utf-8 syntax=c sw=8 ts=8 et
+ *.
+ *. © 2009 David Sommerseth <davids@redhat.com>
+ *. © 2007-2009 Nima Talebi <nima@autonomy.net.au>
+ *.
+ *. This file is part of Python DMI-Decode.
+ *.
+ *. Python DMI-Decode 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, either version 2 of the License, or
+ *. (at your option) any later version.
+ *.
+ *. Python DMI-Decode is distributed in the hope that it will be useful,
+ *. but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *. GNU General Public License for more details.
+ *.
+ *. You should have received a copy of the GNU General Public License
+ *. along with Python DMI-Decode. If not, see <http://www.gnu.org/licenses/>.
+ *.
+ *. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *. WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *. MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ *. EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ *. PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ *. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ *. OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ *. ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *.
+ *. ADAPTED M. STONE & T. PARKER DISCLAIMER: THIS SOFTWARE COULD RESULT IN INJURY
+ *. AND/OR DEATH, AND AS SUCH, IT SHOULD NOT BE BUILT, INSTALLED OR USED BY ANYONE.
+ *.
+ *. $AutoHeaderSerial::20090522 $
+ *. ******* AUTOHEADER END v1.1 ******* */
+
+/* Converts XML docs and nodes to Python dicts and lists by
+ * using an XML file which describes the Python dict layout
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For the avoidance of doubt the "preferred form" of this code is one which
+ * is in an open unpatent encumbered format. Where cryptographic key signing
+ * forms part of the process of creating an executable the information
+ * including keys needed to generate an equivalently functional executable
+ * are deemed to be part of the source code.
+ */
+
+/**
+ * @file xmlpythonizer.c
+ * @brief Generic parser for converting XML documents or XML nodes
+ * into Python Dictionaries
+ * @author David Sommerseth <davids@redhat.com>
+ * @author Nima Talebi <nima@autonomy.net.au>
+ */
+
+
+#include <Python.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include <libxml/tree.h>
+#include <libxml/xpath.h>
+
+#include "util.h"
+#include "dmixml.h"
+#include "dmierror.h"
+#include "xmlpythonizer.h"
+#include "version.h"
+
+
+/**
+ * This functions appends a new ptzMAP structure to an already existing chain
+ * @author David Sommerseth <davids@redhat.com>
+ * @param ptzMAP* Pointer to the chain the new ptzMAP is to be appended
+ * @param ptzMAP* Pointer to the new ptzMAP to be appended to the already existing ptzMAP
+ * @return ptzMAP* Pointer to the ptzMAP which includes the newly added ptzMAP
+ */
+ptzMAP *ptzmap_AppendMap(const ptzMAP *chain, ptzMAP *newmap)
+{
+ if( chain != NULL ) {
+ newmap->next = (ptzMAP *) chain;
+ }
+ return newmap;
+}
+
+
+/**
+ * This function creates a new ptzMAP mapping record. This defines the key/value relationship in
+ * the resulting Python Dictionaries.
+ * @author David Sommerseth <davids@redhat.com>
+ * @param ptzMAP* Pointer to the chain the new mapping will be appended
+ * @param char* XPath root of the given key and value XPath expressions.
+ * If NULL, the key and value XPath expressions must be absolute.
+ * @param ptzTYPES Type of the 'key' value
+ * @param const char* XPath expression or constant string for the 'key' value
+ * @param ptzTYPES Type of the 'value' value
+ * @param const char* XPath expression or constant string for the 'value' value
+ * @param ptzMAP* Used if the value type is of one of the ptzDICT types, contains a new
+ * mapping level for the children
+ * @return ptzMAP* Pointer to the ptzMAP which includes the newly added ptzMAP
+ */
+ptzMAP *ptzmap_Add(const ptzMAP *chain, char *rootp,
+ ptzTYPES ktyp, const char *key,
+ ptzTYPES vtyp, const char *value,
+ ptzMAP *child)
+{
+ ptzMAP *ret = NULL;
+
+ assert( (ktyp == ptzCONST) || (ktyp == ptzSTR) || (ktyp == ptzINT) || (ktyp == ptzFLOAT) );
+ assert( key != NULL );
+
+ ret = (ptzMAP *) malloc(sizeof(ptzMAP)+2);
+ assert( ret != NULL );
+ memset(ret, 0, sizeof(ptzMAP)+2);
+
+ if( rootp != NULL ) {
+ ret->rootpath = strdup(rootp);
+ }
+
+ ret->type_key = ktyp;
+ ret->key = strdup(key);
+
+ ret->type_value = vtyp;
+ if( value != NULL ) {
+ ret->value = strdup(value);
+ }
+
+ if( child != NULL ) {
+ ret->child = child;
+ }
+
+ return ptzmap_AppendMap(chain, ret);
+};
+
+
+/**
+ * This functions sets an ptzLIST typed map entry as a fixed list
+ * @author David Sommerseth <davids@redhat.com>
+ * @param ptzMAP* Pointer to the ptzMAP elemnt to be updated
+ * @param const char* Attribute name of the XML node of the 'key' to use as the list index
+ * @param int Defines the size of the list
+ */
+void ptzmap_SetFixedList(ptzMAP *map_p, const char *index, int size)
+{
+ assert( map_p != NULL );
+
+ switch( map_p->type_value ) {
+ case ptzLIST_STR:
+ case ptzLIST_INT:
+ case ptzLIST_FLOAT:
+ case ptzLIST_BOOL:
+ map_p->list_index = strdup(index);
+ map_p->fixed_list_size = size;
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+/**
+ * This functions frees up a complete pointer chain. This is normally called via #define ptzmap_Free()
+ * @author David Sommerseth <davids@redhat.com>
+ * @param ptzMAP* Pointer to the ptzMAP to free
+ */
+void ptzmap_Free_func(ptzMAP *ptr)
+{
+ if( ptr == NULL ) {
+ return;
+ }
+
+ if( ptr->rootpath != NULL ) {
+ free(ptr->rootpath);
+ ptr->rootpath = NULL;
+ }
+
+ if( ptr->list_index != NULL ) {
+ free(ptr->list_index);
+ ptr->list_index = NULL;
+ }
+
+ if( ptr->emptyValue != NULL ) {
+ free(ptr->emptyValue);
+ ptr->emptyValue = NULL;
+ }
+
+ free(ptr->key);
+ ptr->key = NULL;
+
+ if( ptr->value != NULL ) {
+ free(ptr->value);
+ ptr->value = NULL;
+ }
+
+ if( ptr->child != NULL ) {
+ ptzmap_Free(ptr->child);
+ }
+ if( ptr->next != NULL ) {
+ ptzmap_Free(ptr->next);
+ }
+ free(ptr);
+}
+
+
+#if 0
+// DEBUG FUNCTIONS
+static const char *ptzTYPESstr[] = { "ptzCONST", "ptzSTR", "ptzINT", "ptzFLOAT", "ptzBOOL",
+ "ptzLIST_STR", "ptzLIST_INT", "ptzLIST_FLOAT", "ptzLIST_BOOL",
+ "ptzDICT", "ptzLIST_DICT", NULL };
+
+void indent(int lvl)
+{
+ int i = 0;
+ if( lvl == 0 ) {
+ return;
+ }
+
+ for( i = 0; i < (lvl * 3); i++ ) {
+ printf(" ");
+ }
+}
+
+
+#define ptzmap_Dump(ptr) { ptzmap_Dump_func(ptr, 0); }
+void ptzmap_Dump_func(const ptzMAP *ptr, int level)
+{
+ if( ptr == NULL ) {
+ return;
+ }
+
+ if( ptr->rootpath != NULL ) {
+ indent(level); printf("root path: %s\n", ptr->rootpath);
+ }
+ indent(level); printf("key type: (%i) %-13.13s - key: %s\n",
+ ptr->type_key, ptzTYPESstr[ptr->type_key], ptr->key);
+ indent(level); printf("value type: (%i) %-13.13s - value: %s %s\n",
+ ptr->type_value, ptzTYPESstr[ptr->type_value], ptr->value,
+ (ptr->emptyIsNone ? "(EmptyIsNone)": ""));
+ if( ptr->list_index != NULL ) {
+ indent(level);
+ printf("List index: %s - Fixed size: %i\n",
+ ptr->list_index, ptr->fixed_list_size);
+ }
+ if( ptr->child != NULL ) {
+ indent(level); printf(" ** CHILD\n");
+ ptzmap_Dump_func(ptr->child, level + 1);
+ indent(level); printf(" ** ---------\n");
+ }
+ if( ptr->next != NULL ) {
+ printf("\n");
+ ptzmap_Dump_func(ptr->next, level);
+ }
+}
+#endif // END OF DEBUG FUNCTIONS
+
+
+/**
+ * This functions converts a string to valid ptzTYPES values. This is used when parsing the XML mapping nodes
+ * @author David Sommerseth <davids@redhat.com>
+ * @param const char* String value containing the key/value type
+ * @return ptzTYPES The type value
+ */
+inline ptzTYPES _convert_maptype(const char *str) {
+ if( strcmp(str, "string") == 0 ) {
+ return ptzSTR;
+ } else if( strcmp(str, "constant") == 0 ) {
+ return ptzCONST;
+ } else if( strcmp(str, "integer") == 0 ) {
+ return ptzINT;
+ } else if( strcmp(str, "float") == 0 ) {
+ return ptzFLOAT;
+ } else if( strcmp(str, "boolean") == 0 ) {
+ return ptzBOOL;
+ } else if( strcmp(str, "list:string") == 0 ) {
+ return ptzLIST_STR;
+ } else if( strcmp(str, "list:integer") == 0 ) {
+ return ptzLIST_INT;
+ } else if( strcmp(str, "list:float") == 0 ) {
+ return ptzLIST_FLOAT;
+ } else if( strcmp(str, "list:boolean") == 0 ) {
+ return ptzLIST_BOOL;
+ } else if( strcmp(str, "dict") == 0 ) {
+ return ptzDICT;
+ } else if( strcmp(str, "list:dict") == 0 ) {
+ return ptzLIST_DICT;
+ } else {
+ fprintf(stderr, "Unknown field type: %s - defaulting to 'constant'\n", str);
+ return ptzCONST;
+ }
+}
+
+
+/**
+ * This functions is the internal parser - SubMapper (Individual Types of a Group)
+ * @author David Sommerseth <davids@redhat.com>
+ * @param xmlNode* Node of the starting point for the parsing
+ * @return ptzMAP* The ptzMAP version of the XML definition
+ */
+ptzMAP *_do_dmimap_parsing_typeid(xmlNode *node) {
+ ptzMAP *retmap = NULL;
+ xmlNode *ptr_n = NULL, *map_n = NULL;;
+
+ // Go to the next XML_ELEMENT_NODE
+ foreach_xmlnode(node, map_n) {
+ if( map_n->type == XML_ELEMENT_NODE ) {
+ break;
+ }
+ }
+ if( map_n == NULL ) {
+ PyReturnError(PyExc_NameError, "No mapping nodes were found");
+ }
+
+ // Go to the first <Map> node
+ if( xmlStrcmp(node->name, (xmlChar *) "Map") != 0 ) {
+ map_n = dmixml_FindNode(node, "Map");
+ if( map_n == NULL ) {
+ // If we don't find a <Map> node, we just exit now.
+ // Other checks will raise an exception if needed.
+ return NULL;
+ }
+ }
+
+ // Loop through it's children
+ foreach_xmlnode(map_n, ptr_n) {
+ ptzTYPES type_key, type_value;
+ char *key = NULL, *value = NULL;
+ char *rootpath = NULL;
+ char *listidx = NULL;
+ int fixedsize = 0;
+ if( ptr_n->type != XML_ELEMENT_NODE ) {
+ continue;
+ }
+
+ // Get the attributes defining key, keytype, value and valuetype
+ key = dmixml_GetAttrValue(ptr_n, "key");
+ type_key = _convert_maptype(dmixml_GetAttrValue(ptr_n, "keytype"));
+
+ value = dmixml_GetAttrValue(ptr_n, "value");
+ type_value = _convert_maptype(dmixml_GetAttrValue(ptr_n, "valuetype"));
+
+ rootpath = dmixml_GetAttrValue(ptr_n, "rootpath");
+
+ listidx = dmixml_GetAttrValue(ptr_n, "index_attr");
+ if( listidx != NULL ) {
+ char *fsz = dmixml_GetAttrValue(ptr_n, "fixedsize");
+ fixedsize = (fsz != NULL ? atoi(fsz) : 0);
+ }
+
+ if( (type_value == ptzDICT) || (type_value == ptzLIST_DICT) ) {
+ // When value type is ptzDICT, traverse the children nodes
+ // - should contain another Map set instead of a value attribute
+ if( ptr_n->children == NULL ) {
+ continue;
+ }
+ // Recursion
+ retmap = ptzmap_Add(retmap, rootpath, type_key, key, type_value,
+ (type_value == ptzLIST_DICT ? value : NULL),
+ _do_dmimap_parsing_typeid(ptr_n->children->next));
+ } else {
+ char *tmpstr = NULL;
+
+ // Append the value as a normal value when the
+ // value type is not a Python Dict
+ retmap = ptzmap_Add(retmap, rootpath, type_key, key, type_value, value, NULL);
+
+ // Set emptyIsNone flag
+ if( (tmpstr = dmixml_GetAttrValue(ptr_n, "emptyIsNone")) != NULL ) {
+ switch( retmap->type_value ) {
+ case ptzSTR:
+ case ptzINT:
+ case ptzFLOAT:
+ case ptzBOOL:
+ case ptzLIST_STR:
+ case ptzLIST_INT:
+ case ptzLIST_FLOAT:
+ case ptzLIST_BOOL:
+ retmap->emptyIsNone = (tmpstr[0] == '1' ? 1 : 0);
+ break;
+ default:
+ break;
+ }
+ }
+ if( (tmpstr = dmixml_GetAttrValue(ptr_n, "emptyValue")) != NULL ) {
+ retmap->emptyValue = strdup(tmpstr);
+ }
+ }
+
+ if( (retmap != NULL) && (listidx != NULL) && (fixedsize > 0) ) {
+ ptzmap_SetFixedList(retmap, listidx, fixedsize);
+ }
+
+ value = NULL;
+ key = NULL;
+ }
+
+ return retmap;
+}
+
+/**
+ * This functions validates and retrieves the root node of the dmidecode_mapping XML node from an XML document
+ * @author David Sommerseth <davids@redhat.com>
+ * @param xmlDoc* XML mapping document pointer
+ * @return xmlNode* The root xmlNode of a valid XML mapping document. On invalid document NULL is returned.
+ */
+xmlNode *dmiMAP_GetRootElement(xmlDoc *mapdoc) {
+ xmlNode *rootnode = NULL;
+
+ // Find the root tag and locate our mapping
+ rootnode = xmlDocGetRootElement(mapdoc);
+ assert( rootnode != NULL );
+
+ // Verify that the root node got the right name
+ if( (rootnode == NULL)
+ || (xmlStrcmp(rootnode->name, (xmlChar *) "dmidecode_mapping") != 0 )) {
+ PyReturnError(PyExc_IOError, "Invalid XML-Python mapping file. "
+ "Root node is not 'dmidecode_mapping'");
+ }
+
+ // Verify that it's of a version we support
+ if( strcmp(dmixml_GetAttrValue(rootnode, "version"), "1") != 0 ) {
+ PyReturnError(PyExc_RuntimeError, "Unsupported XML-Python mapping file format. "
+ "Only version 1 is supported");
+ }
+ return rootnode;
+}
+
+
+/**
+ * Internal function which looks up the given Type ID among TypeMap nodes and and parses
+ * the found XML nodes into a ptzMAP
+ * @author David Sommerseth <davids@redhat.com>
+ * @param xmlNode* The node where the TypeMapping tags are found
+ * @param const char* The typeid to parse to a ptzMAP
+ * @return ptzMAP* The parsed result of the XML nodes
+ */
+ptzMAP *_dmimap_parse_mapping_node_typeid(xmlNode *mapnode, const char *typeid) {
+ xmlNode *node = NULL;
+
+ assert( mapnode != NULL);
+
+ // Find the <TypeMap> tag with our type ID
+ node = dmixml_FindNodeByAttr_NoCase(mapnode, "TypeMap", "id", typeid);
+ if( node == NULL ) {
+ // No exception handling possible here, as we don't return PyObject
+ fprintf(stderr,"** WARNING: Could not find any XML->Python "
+ "mapping for type ID '%s'", typeid);
+ return NULL;
+ }
+ // Create an internal map structure and return this structure
+ return _do_dmimap_parsing_typeid(node);
+}
+
+
+/**
+ * Exported function for parsing a XML mapping document for a given Type ID to a ptzMAP
+ * @author David Sommerseth <davids@redhat.com>
+ * @param xmlDoc* Pointer to the XML mapping document
+ * @param const char* The Type ID to create the map for
+ * @return ptzMAP* The parsed XML containing as a ptzMAP
+ */
+ptzMAP *dmiMAP_ParseMappingXML_TypeID(xmlDoc *xmlmap, int typeid) {
+ xmlNode *node = NULL;
+ char typeid_s[16];
+
+ node = dmiMAP_GetRootElement(xmlmap);
+ if( node == NULL ) {
+ PyReturnError(PyExc_RuntimeError, "Could not locate root XML node for mapping file");
+ }
+
+ memset(&typeid_s, 0, 16);
+ snprintf(typeid_s, 14, "0x%02X", typeid);
+
+ // Find the <TypeMapping> section
+ node = dmixml_FindNode(node, "TypeMapping");
+ assert( node != NULL );
+ return _dmimap_parse_mapping_node_typeid(node, typeid_s);
+}
+
+
+/**
+ * Internal parser for GroupMapping (group of types). Converts a given GroupMapping to a ptzMAP
+ * from a XML node set
+ * @author Nima Talebi <nima@autonomy.net.au>
+ * @author David Sommerseth <davids@redhat.com>
+ * @param xmlNode* The source XML nodes of what to parse to a ptzMAP
+ * @param xmlDoc* A pointer to the source map, used for further parsing of each type defined in the GroupMapping
+ * @return ptzMAP* The resulting ptzMAP of the parsed xmlNode group mapping
+ */
+ptzMAP *_do_dmimap_parsing_group(xmlNode *node, xmlDoc *xmlmap) {
+ ptzMAP *retmap = NULL;
+ xmlNode *ptr_n = NULL, *map_n = NULL, *typemap = NULL;
+ char *type_id;
+
+ // Go to the next XML_ELEMENT_NODE
+ foreach_xmlnode(node, map_n) {
+ if( map_n->type == XML_ELEMENT_NODE ) {
+ break;
+ }
+ }
+ if( map_n == NULL ) {
+ PyReturnError(PyExc_RuntimeError, "Could not find any valid XML nodes");
+ }
+
+ // Check that our "root" node is as expected
+ if( xmlStrcmp(node->name, (xmlChar *) "Mapping") != 0 ) {
+ PyReturnError(PyExc_NameError, "Expected to find <Mapping> node");
+ }
+
+ // Go to the first <TypeMap> node
+ map_n = dmixml_FindNode(node, "TypeMap");
+ if( map_n == NULL ) {
+ PyReturnError(PyExc_NameError, "Could not locate any <TypeMap> nodes");
+ }
+
+ // Get the root element of the <TypeMapping> tag, needed for further parsing
+ typemap = dmixml_FindNode(xmlDocGetRootElement(xmlmap), "TypeMapping");
+ if( typemap == NULL ) {
+ PyReturnError(PyExc_NameError, "Could not locate the <TypeMapping> node");
+ }
+
+ // Loop through it's children
+ foreach_xmlnode(map_n, ptr_n) {
+ // Validate if we have the right node name
+ if( xmlStrcmp(ptr_n->name, (xmlChar *) "TypeMap") != 0 ) {
+ continue; // Skip unexpected tag names
+ }
+
+ // Make sure that we have an id attribute before trying to locate that in th
+ if( (type_id = dmixml_GetAttrValue(ptr_n, "id")) != NULL) {
+ ptzMAP *map = NULL;
+
+ map = _dmimap_parse_mapping_node_typeid(typemap, type_id);
+ if( map ) {
+ retmap = ptzmap_AppendMap(retmap, map);
+ }
+ }
+ }
+ return retmap;
+}
+
+
+/**
+ * Exported function which parses a given GroupMapping (consisting of
+ * one or more TypeMaps) into a ptzMAP
+ * @author David Sommerseth <davids@redhat.com>
+ * @param xmlDoc* Pointer to the XML document holding the mapping
+ * @param const char* Defines which group mapping to parse to a ptzMAP
+ * @return ptzMAP* The parsed XML mapping in a ptzMAP
+ */
+ptzMAP *dmiMAP_ParseMappingXML_GroupName(xmlDoc *xmlmap, const char *mapname) {
+ xmlNode *node = NULL;
+
+ // Validate the XML mapping document and get the root element
+ node = dmiMAP_GetRootElement(xmlmap);
+ if( node == NULL ) {
+ PyReturnError(PyExc_RuntimeError, "No valid mapping XML recieved");
+ }
+
+ // Find the <GroupMapping> section
+ node = dmixml_FindNode(node, "GroupMapping");
+ if( node == NULL ) {
+ PyReturnError(PyExc_NameError, "Could not find the <GroupMapping> node");
+ }
+
+ // Find the <Mapping> section matching our request (mapname)
+ node = dmixml_FindNodeByAttr(node, "Mapping", "name", mapname);
+ if( node == NULL ) {
+ PyReturnError(PyExc_NameError, "No group mapping for '%s' was found "
+ "in the XML-Python mapping file", mapname);
+ }
+
+ // Create an internal map structure and return this structure
+ return _do_dmimap_parsing_group(node, xmlmap);
+}
+
+
+/**
+ * Internal function for converting a given mapped value to the appropriate Python data type
+ * @author David Sommerseth <davids@redhat.com>
+ * @param ptzMAP* Pointer to the current mapping entry being parsed
+ * @param const char * String which contains the value to be converted to a Python value
+ * @return PyObject * The converted value as a Python object
+ */
+inline PyObject *StringToPyObj(ptzMAP *val_m, const char *instr) {
+ PyObject *value;
+ const char *workstr = NULL;
+
+ if( instr == NULL ) {
+ return Py_None;
+ }
+
+ if( (val_m->emptyIsNone == 1) || (val_m->emptyValue != NULL) ) {
+ char *cp = strdup(instr);
+ char *cp_p = NULL;
+ assert( cp != NULL );
+
+ // Trim the string for trailing spaces
+ cp_p = cp + strlen(cp) - 1;
+ while( (cp_p >= cp) && (*cp_p == ' ') ) {
+ *cp_p = 0;
+ cp_p--;
+ }
+
+ // If our copy pointer is the same
+ // or less than the starting point,
+ // there is no data here
+ if( cp_p <= cp ) {
+ free(cp);
+ if( val_m->emptyIsNone == 1 ) {
+ return Py_None;
+ }
+ if( val_m->emptyValue != NULL ) {
+ workstr = (const char *)val_m->emptyValue;
+ }
+ } else {
+ free(cp);
+ }
+ }
+
+ if( workstr == NULL ) {
+ workstr = instr;
+ }
+
+
+ switch( val_m->type_value ) {
+ case ptzINT:
+ case ptzLIST_INT:
+ value = PyInt_FromLong(atoi(workstr));
+ break;
+
+ case ptzFLOAT:
+ case ptzLIST_FLOAT:
+ value = PyFloat_FromDouble(atof(workstr));
+ break;
+
+ case ptzBOOL:
+ case ptzLIST_BOOL:
+ value = PyBool_FromLong((atoi(workstr) == 1 ? 1:0));
+ break;
+
+ case ptzSTR:
+ case ptzLIST_STR:
+ value = PyString_FromString(workstr);
+ break;
+
+ default:
+ fprintf(stderr, "Invalid type '%i' for value '%s'\n", val_m->type_value, instr);
+ value = Py_None;
+ }
+ return value;
+}
+
+
+/**
+ * Retrieves a value from the data XML doc (via XPath Context) based on a XPath query
+ * @author David Sommerseth <davids@redhat.com>
+ * @param xmlXPathContext* Pointer to the XPath context holding the source data
+ * @param const char* The XPath expression where to find the data
+ * @return xmlXPathObject* If data is found, it is returned in an XPath object for further processing
+ */
+
+xmlXPathObject *_get_xpath_values(xmlXPathContext *xpctx, const char *xpath) {
+ xmlChar *xp_xpr = NULL;
+ xmlXPathObject *xp_obj = NULL;
+
+ if( xpath == NULL ) {
+ return NULL;
+ }
+
+ xp_xpr = xmlCharStrdup(xpath);
+ xp_obj = xmlXPathEvalExpression(xp_xpr, xpctx);
+ assert( xp_obj != NULL );
+ free(xp_xpr);
+
+ return xp_obj;
+}
+
+
+/**
+ * Retrieves the value which is to be used as the key value in a Python dictionary.
+ * @author David Sommerseth <davids@redhat.com>
+ * @param char* Pointer to the return buffer for the value
+ * @param size_t Size of the return buffer
+ * @param ptzMAP* Pointer to the current mapping entry which is being parsed
+ * @param xmlXPathContext* Pointer to the XPath context containing the source data
+ * @param int Defines which of the XPath results to use, if more is found
+ * @returns char* Returns a pointer to the return buffer (parameter 1) if key value
+ * is found, or NULL if not found
+ */
+char *_get_key_value(char *key, size_t buflen, ptzMAP *map_p, xmlXPathContext *xpctx, int idx) {
+ xmlXPathObject *xpobj = NULL;
+
+ memset(key, 0, buflen);
+
+ switch( map_p->type_key ) {
+ case ptzCONST:
+ strncpy(key, map_p->key, buflen-1);
+ break;
+
+ case ptzSTR:
+ case ptzINT:
+ case ptzFLOAT:
+ xpobj = _get_xpath_values(xpctx, map_p->key);
+ if( xpobj == NULL ) {
+ return NULL;
+ }
+ if( dmixml_GetXPathContent(key, buflen, xpobj, idx) == NULL ) {
+ xmlXPathFreeObject(xpobj);
+ return NULL;
+ }
+ xmlXPathFreeObject(xpobj);
+ break;
+
+ default:
+ fprintf(stderr, "Unknown key type: %i\n", map_p->type_key);
+ return NULL;
+ }
+ // We consider to have a key, if the first byte is a readable
+ // character (usually starting at 0x20/32d)
+ return ((key != NULL) && (strlen(key) > 0) ? key : NULL) ;
+}
+
+
+/**
+ * Simple define to properly add a key/value pair to a Python dictionary
+ * @author David Sommerseth <davids@redhat.com>
+ * @param PyObject* Pointer to the Python dictionary to be updated
+ * @param const char* String containing the key value
+ * @param PyObject* Pointer to the Python value
+ */
+
+#define PyADD_DICT_VALUE(p, k, v) { \
+ PyDict_SetItemString(p, k, v); \
+ if( v != Py_None ) { \
+ Py_DECREF(v); \
+ } \
+ }
+
+
+/**
+ * Internal function for adding a XPath result to the resulting Python dictionary
+ * @author David Sommerseth <davids@redhat.com>
+ * @param PyObject* Pointer to the resulting Python dictionary
+ * @param xmlXPathContext* Pointer to the XPath context containing the source data
+ * (used for retrieving the key value)
+ * @param ptzMAP* Pointer to the current mapping entry being parsed
+ * @param xmlXPathObject* Pointer to XPath object containing the data value(s) for the dictionary
+ */
+inline void _add_xpath_result(PyObject *pydat, xmlXPathContext *xpctx, ptzMAP *map_p, xmlXPathObject *value) {
+ int i = 0;
+ char *key = NULL;
+ char *val = NULL;
+
+ assert( pydat != NULL && value != NULL );
+
+ key = (char *) malloc(258);
+ assert( key != NULL );
+
+ val = (char *) malloc(4098);
+ assert( val != NULL );
+
+ switch( value->type ) {
+ case XPATH_NODESET:
+ if( value->nodesetval == NULL ) {
+ break;
+ }
+ if( value->nodesetval->nodeNr == 0 ) {
+ if( _get_key_value(key, 256, map_p, xpctx, 0) != NULL ) {
+ PyADD_DICT_VALUE(pydat, key, Py_None);
+ }
+ } else {
+ for( i = 0; i < value->nodesetval->nodeNr; i++ ) {
+ if( _get_key_value(key, 256, map_p, xpctx, i) != NULL ) {
+ dmixml_GetXPathContent(val, 4097, value, i);
+ PyADD_DICT_VALUE(pydat, key, StringToPyObj(map_p, val));
+ }
+ }
+ }
+ break;
+ default:
+ if( _get_key_value(key, 256, map_p, xpctx, 0) != NULL ) {
+ dmixml_GetXPathContent(val, 4097, value, 0);
+ PyADD_DICT_VALUE(pydat, key, StringToPyObj(map_p, val));
+ }
+ break;
+ }
+ free(key);
+ free(val);
+}
+
+
+/**
+ * Internal XML parser routine, which traverses the given mapping table,
+ * returning a Python structure accordingly to the map. Data for the Python dictionary is
+ * take from the input XML node.
+ * @author David Sommerseth <davids@redhat.com>
+ * @param PyObject* Pointer to the Python dictionary of the result
+ * @param ptzMAP* Pointer to the starting point for the further parsing
+ * @param xmlNode* Pointer to the XML node containing the source data
+ * @param int For debug purpose only, to keep track of which element being parsed
+ * @return PyObject* Pointer to the input Python dictionary
+ */
+PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int elmtid) {
+ char *key = NULL;
+ xmlXPathContext *xpctx = NULL;
+ xmlDoc *xpdoc = NULL;
+ xmlXPathObject *xpo = NULL;
+ PyObject *value = NULL;
+ int i;
+
+ xpdoc = xmlNewDoc((xmlChar *) "1.0");
+ assert( xpdoc != NULL );
+ xmlDocSetRootElement(xpdoc, xmlCopyNode(data_n, 1));
+
+ xpctx = xmlXPathNewContext(xpdoc);
+ assert( xpctx != NULL );
+ xpctx->node = data_n;
+
+ key = (char *) malloc(258);
+ assert( key != NULL );
+
+ // Extract value
+ switch( map_p->type_value ) {
+ case ptzCONST:
+ if( _get_key_value(key, 256, map_p, xpctx, 0) != NULL ) {
+ value = PyString_FromString(map_p->value);
+ PyADD_DICT_VALUE(retdata, key, value);
+ } else {
+ PyReturnError(PyExc_ValueError, "Could not get key value: %s [%i] (Defining key: %s)",
+ map_p->rootpath, elmtid, map_p->key);
+ }
+ break;
+
+ case ptzSTR:
+ case ptzINT:
+ case ptzFLOAT:
+ case ptzBOOL:
+ xpo = _get_xpath_values(xpctx, map_p->value);
+ if( xpo != NULL ) {
+ _add_xpath_result(retdata, xpctx, map_p, xpo);
+ xmlXPathFreeObject(xpo);
+ }
+ break;
+
+ case ptzLIST_STR:
+ case ptzLIST_INT:
+ case ptzLIST_FLOAT:
+ case ptzLIST_BOOL:
+ xpo = _get_xpath_values(xpctx, map_p->value);
+ if( xpo != NULL ) {
+ if( _get_key_value(key, 256, map_p, xpctx, 0) != NULL ) {
+ if( (xpo->nodesetval != NULL) && (xpo->nodesetval->nodeNr > 0) ) {
+ value = PyList_New(0);
+
+ // If we're working on a fixed list, create one which contains
+ // only Py_None objects. Otherwise the list will be filled with
+ // <nil> elements.
+ if( map_p->fixed_list_size > 0 ) {
+ for( i = 0; i < map_p->fixed_list_size; i++ ) {
+ PyList_Append(value, Py_None);
+ }
+ }
+
+ for( i = 0; i < xpo->nodesetval->nodeNr; i++ ) {
+ char *valstr = NULL;
+ valstr = (char *) malloc(4098);
+ dmixml_GetXPathContent(valstr, 4097, xpo, i);
+
+ // If we have a fixed list and we have a index value for the list
+ if( (map_p->fixed_list_size > 0) && (map_p->list_index != NULL) ) {
+ char *idx = NULL;
+
+ idx = dmixml_GetAttrValue(xpo->nodesetval->nodeTab[i],
+ map_p->list_index);
+ if( idx != NULL ) {
+ PyList_SetItem(value, atoi(idx)-1,
+ StringToPyObj(map_p, valstr)
+ );
+ }
+ } else {
+ // No list index - append the value
+ PyList_Append(value, StringToPyObj(map_p, valstr));
+ }
+ free(valstr);
+ }
+ } else {
+ value = Py_None;
+ }
+ PyADD_DICT_VALUE(retdata, key, value);
+ xmlXPathFreeObject(xpo);
+ } else {
+ PyReturnError(PyExc_ValueError, "Could not get key value: "
+ "%s [%i] (Defining key: %s)",
+ map_p->rootpath, elmtid, map_p->key);
+ }
+ }
+ break;
+
+ case ptzDICT:
+ // Traverse children nodes
+ if( map_p->child == NULL ) {
+ break;
+ }
+ if( _get_key_value(key, 256, map_p, xpctx, 0) == NULL ) {
+ PyReturnError(PyExc_ValueError,
+ "Could not get key value: %s [%i] (Defining key: %s)",
+ map_p->rootpath, elmtid, map_p->key);
+ }
+ // Use recursion when procession child elements
+ value = pythonizeXMLnode(map_p->child, data_n);
+ PyADD_DICT_VALUE(retdata, key, (value != NULL ? value : Py_None));
+ break;
+
+ case ptzLIST_DICT: // List of dict arrays
+ if( map_p->child == NULL ) {
+ break;
+ }
+ if( _get_key_value(key, 256, map_p, xpctx, 0) == NULL ) {
+ PyReturnError(PyExc_ValueError,
+ "Could not get key value: %s [%i] (Defining key: %s)",
+ map_p->rootpath, elmtid, map_p->key);
+ }
+
+ // Iterate all nodes which is found in the 'value' XPath
+ xpo = _get_xpath_values(xpctx, map_p->value);
+ if( (xpo == NULL) || (xpo->nodesetval == NULL) || (xpo->nodesetval->nodeNr == 0) ) {
+ if( xpo != NULL ) {
+ xmlXPathFreeObject(xpo);
+ }
+ PyReturnError(PyExc_ValueError,
+ "Could not get key value: %s [%i] (Defining key: %s)",
+ map_p->rootpath, elmtid, map_p->key);
+ }
+
+ // Prepare a data list
+ value = PyList_New(0);
+
+ // If we're working on a fixed list, create one which contains
+ // only Py_None objects. Otherwise the list will be filled with
+ // <nil> elements.
+ if( map_p->fixed_list_size > 0 ) {
+ for( i = 0; i < map_p->fixed_list_size; i++ ) {
+ PyList_Append(value, Py_None);
+ }
+ }
+
+ for( i = 0; i < xpo->nodesetval->nodeNr; i++ ) {
+ PyObject *dataset = NULL;
+
+ dataset = pythonizeXMLnode(map_p->child, xpo->nodesetval->nodeTab[i]);
+ if( dataset != NULL ) {
+ // If we have a fixed list and we have a index value for the list
+ if( (map_p->fixed_list_size > 0) && (map_p->list_index != NULL) ) {
+ char *idx = NULL;
+ idx = dmixml_GetAttrValue(xpo->nodesetval->nodeTab[i],
+ map_p->list_index);
+ if( idx != NULL ) {
+ PyList_SetItem(value, atoi(idx)-1, dataset);
+ }
+ } else {
+ // No list index - append the value
+ PyList_Append(value, dataset);
+ }
+ } else {
+ // If NULL, something is wrong - exception is already set.
+ return NULL;
+ }
+ }
+ PyADD_DICT_VALUE(retdata, key, value);
+ xmlXPathFreeObject(xpo);
+ break;
+
+ default:
+ fprintf(stderr, "Unknown value type: %i\n", map_p->type_value);
+ break;
+ }
+
+ free(key);
+ xmlXPathFreeContext(xpctx);
+ xmlFreeDoc(xpdoc);
+ return retdata;
+}
+
+
+/**
+ * Exported function, for parsing a XML node to a Python dictionary based on the given ptzMAP
+ * @author David Sommerseth <davids@redhat.com>
+ * @param ptzMAP* The map descriping the resulting Python dictionary
+ * @param xmlNode* XML node pointer to the source data to be used for populating the Python dictionary
+ */
+PyObject *pythonizeXMLnode(ptzMAP *in_map, xmlNode *data_n) {
+ xmlXPathContext *xpctx = NULL;
+ xmlDoc *xpdoc = NULL;
+ PyObject *retdata = NULL;
+ ptzMAP *map_p = NULL;
+ char *key = NULL;
+
+ if( (in_map == NULL) || (data_n == NULL) ) {
+ PyReturnError(PyExc_RuntimeError, "pythonXMLnode() - xmlNode or ptzMAP is NULL");
+ }
+
+ key = (char *) malloc(258);
+ if( key == NULL ) {
+ PyReturnError(PyExc_MemoryError, "Could not allocate temporary buffer");
+ }
+
+ // Loop through all configured elements
+ retdata = PyDict_New();
+ foreach_xmlnode(in_map, map_p) {
+ if( (map_p->type_value == ptzDICT) && (map_p->rootpath != NULL) ) {
+ xmlXPathObject *xpo = NULL;
+ int i;
+
+ // Set the root node in the XPath context
+ xpdoc = xmlNewDoc((xmlChar *) "1.0");
+ assert( xpdoc != NULL );
+ xmlDocSetRootElement(xpdoc, xmlCopyNode(data_n, 1));
+
+ xpctx = xmlXPathNewContext(xpdoc);
+ if( xpctx == NULL ) {
+ PyReturnError(PyExc_MemoryError, "Could not setup new XPath context");
+ }
+ xpctx->node = data_n;
+
+ xpo = _get_xpath_values(xpctx, map_p->rootpath);
+ if( (xpo != NULL) && (xpo->nodesetval != NULL) && (xpo->nodesetval->nodeNr > 0) ) {
+ for( i = 0; i < xpo->nodesetval->nodeNr; i++ ) {
+ xpctx->node = xpo->nodesetval->nodeTab[i];
+
+ if( _get_key_value(key, 256, map_p, xpctx, 0) != NULL ) {
+ PyObject *res = _deep_pythonize(retdata, map_p,
+ xpo->nodesetval->nodeTab[i], i);
+ if( res == NULL ) {
+ // Exit if we get NULL - something is wrong
+ //and exception is set
+ return NULL;
+ }
+ }
+ }
+ xmlXPathFreeContext(xpctx);
+ xmlFreeDoc(xpdoc);
+ }
+#ifdef DEBUG
+ else {
+ fprintf(stderr, "** pythonizeXMLnode :: Could not locate node for key value: "
+ "root path '%s', key '%s'\n", map_p->rootpath, map_p->key);
+ }
+#endif
+ if( xpo != NULL ) {
+ xmlXPathFreeObject(xpo); xpo = NULL;
+ }
+ } else {
+ PyObject *res = _deep_pythonize(retdata, map_p, data_n, 0);
+ if( res == NULL ) {
+ // Exit if we get NULL - something is wrong
+ //and exception is set
+ return NULL;
+ }
+ }
+ }
+ free(key);
+ return retdata;
+}
+
+
+/**
+ * Exported function, for parsing a XML document to a Python dictionary based on the given ptzMAP
+ * @author David Sommerseth <davids@redhat.com>
+ * @param ptzMAP* The map descriping the resulting Python dictionary
+ * @param xmlDoc* XML document pointer to the source data to be used for populating the Python dictionary
+ */
+PyObject *pythonizeXMLdoc(ptzMAP *map, xmlDoc *doc)
+{
+ xmlNode *node = NULL;
+
+ node = xmlDocGetRootElement(doc);
+ return pythonizeXMLnode(map, node);
+}
+
+
+#if 0
+// Simple independent main function - only for debugging
+int main(int argc, char **argv) {
+ xmlDoc *doc = NULL, *data = NULL;
+ ptzMAP *map = NULL;
+ PyObject *pydat = NULL;
+
+ Py_Initialize();
+
+ doc = xmlReadFile("pymap.xml", NULL, 0);
+ assert( doc != NULL );
+
+ map = dmiMAP_ParseMappingXML_GroupName(doc, argv[1]);
+ // map = dmiMAP_ParseMappingXML_TypeID(doc, atoi(rgv[1]));
+ ptzmap_Dump(map);
+ printf("----------------------\n");
+ assert(map != NULL);
+
+ data = xmlReadFile(argv[2], NULL, 0);
+ assert( data != NULL );
+
+ pydat = pythonizeXMLdoc(map, data);
+ assert( pydat != NULL );
+
+ Py_INCREF(pydat);
+ printf("\n\n");
+ PyObject_Print(pydat, stdout, 0);
+ Py_DECREF(pydat);
+ printf("\n\n");
+ ptzmap_Free(map);
+ xmlFreeDoc(data);
+ xmlFreeDoc(doc);
+
+ return 0;
+}
+#endif
+
+#if 0
+// Simple test module for Python - only for debugging
+PyObject* demo_xmlpy()
+{
+ xmlDoc *doc = NULL, *mapping_xml = NULL;
+ ptzMAP *mapping = NULL;
+ PyObject *ret = NULL;
+
+ // Read the XML-Python mapping setup
+ mapping_xml = xmlReadFile("pythonmap.xml", NULL, 0);
+ assert( mapping_xml != NULL );
+
+ mapping = dmiMAP_ParseMappingXML(mapping_xml, "bios");
+ assert( mapping != NULL );
+
+ // Read XML data from file
+ doc = xmlReadFile("cpu.xml", NULL, 0);
+ assert( doc != NULL );
+
+ // Create a PyObject out of the XML indata
+ ret = pythonizeXMLdoc(mapping, doc);
+
+ // Clean up and return the data
+ ptzmap_Free(mapping);
+ xmlFreeDoc(doc);
+ xmlFreeDoc(mapping_xml);
+
+ return ret;
+}
+
+static PyMethodDef DemoMethods[] = {
+ {"xmlpy", demo_xmlpy, METH_NOARGS, ""},
+ {NULL, NULL, 0, NULL}
+};
+
+PyMODINIT_FUNC initxmlpythonizer(void) {
+ PyObject *module =
+ Py_InitModule3((char *)"xmlpythonizer", DemoMethods,
+ "XML to Python Proof-of-Concept Python Module");
+
+ PyObject *version = PyString_FromString(VERSION);
+ Py_INCREF(version);
+ PyModule_AddObject(module, "version", version);
+}
+#endif // Python test module
+
+
diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h
new file mode 100644
index 0000000..df60140
--- /dev/null
+++ b/src/xmlpythonizer.h
@@ -0,0 +1,60 @@
+/* Converts XML docs and nodes to Python dicts and lists by
+ * using an XML file which describes the Python dict layout
+ *
+ * Copyright 2009 David Sommerseth <davids@redhat.com>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For the avoidance of doubt the "preferred form" of this code is one which
+ * is in an open unpatent encumbered format. Where cryptographic key signing
+ * forms part of the process of creating an executable the information
+ * including keys needed to generate an equivalently functional executable
+ * are deemed to be part of the source code.
+ */
+
+#ifndef _XMLPYTHONIZER_H
+#define _XMLPYTHONIZER_H
+
+typedef enum ptzTYPES_e { ptzCONST, ptzSTR, ptzINT, ptzFLOAT, ptzBOOL,
+ ptzLIST_STR, ptzLIST_INT, ptzLIST_FLOAT, ptzLIST_BOOL,
+ ptzDICT, ptzLIST_DICT } ptzTYPES;
+
+typedef struct ptzMAP_s {
+ char *rootpath; // XML root path for the data - if NULL, XML document is the root document.
+
+ ptzTYPES type_key; // Valid types: ptzCONST, ptzSTR, ptzINT, ptzFLOAT
+ char *key; // for ptzCONST key contains a static string, other types an XPath to XML data
+ ptzTYPES type_value;
+ char *value; // for ptzCONST key contains a static string,
+ // the rest of types, an XPath to XML data
+ int fixed_list_size; // Only to be used on lists
+ char *list_index ; // Only to be used on fixed lists
+ int emptyIsNone; // If set to 1, empty input (right trimmed) strings sets the result to Py_None
+ char *emptyValue; // If set, this value will be used when input is empty
+ struct ptzMAP_s *child; // Only used for type_value == (ptzDICT || ptzLIST_DICT)
+ struct ptzMAP_s *next; // Pointer chain
+
+} ptzMAP;
+
+xmlNode *dmiMAP_GetRootElement(xmlDoc *mapdoc);
+ptzMAP *dmiMAP_ParseMappingXML_TypeID(xmlDoc *xmlmap, int typeid);
+ptzMAP *dmiMAP_ParseMappingXML_GroupName(xmlDoc *xmlmap, const char *mapname);
+#define ptzmap_Free(ptr) { ptzmap_Free_func(ptr); ptr = NULL; }
+void ptzmap_Free_func(ptzMAP *ptr);
+
+PyObject *pythonizeXMLdoc(ptzMAP *map, xmlDoc *xmldoc);
+PyObject *pythonizeXMLnode(ptzMAP *map, xmlNode *nodes);
+
+#endif // _XMLPYTHONIZER_H
diff --git a/unit-tests/Makefile b/unit-tests/Makefile
new file mode 100644
index 0000000..01706a3
--- /dev/null
+++ b/unit-tests/Makefile
@@ -0,0 +1,34 @@
+## This one is important to get right ...
+## We need to link in the libxml2mod.so file from here
+PYLIBDIR := /usr/lib64/python2.5/site-packages
+PYLIBDIR := /usr/lib/python-support/python-libxml2/python2.5
+
+# Defaults, should be fine
+CFLAGS=-I. $(shell xml2-config --cflags) -g -Wall $(shell python-config --cflags)
+
+LIBS=$(shell xml2-config --libs) -lxml2mod $(shell python-config --libs)
+LIBDIR=-L $(PYLIBDIR)
+
+.SUFFIX=.c .o .so
+
+all : test
+
+demomodule.so : demo.o dmixml.o
+ @echo "Linking: $@"
+ @gcc -fPIC --shared -o $@ $^ $(LIBS) $(LIBDIR)
+
+.c.o :
+ @echo "Compiling $<"
+ @gcc -fPIC -c $< $(CFLAGS)
+
+#test : demomodule.so
+test :
+ @echo "=========================================="
+ @echo " Running proof-of-concept code"
+ @echo "=========================================="
+ @echo ""
+ @python unit
+
+clean :
+ rm -f *.{py[oc],o,so} *~
+
diff --git a/unit-tests/POCDemo.py b/unit-tests/POCDemo.py
new file mode 100644
index 0000000..475a62b
--- /dev/null
+++ b/unit-tests/POCDemo.py
@@ -0,0 +1,12 @@
+import libxml2
+import demomodule # This is our core module
+
+class POCDemo:
+ """Demo of a wrapper class to return proper python libxml2 objects"""
+
+ def GetXMLdoc(self):
+ return libxml2.xmlDoc( _obj = demomodule.dump_doc() )
+
+ def GetXMLnode(self):
+ return libxml2.xmlNode( _obj = demomodule.dump_node() )
+
diff --git a/unit-tests/demo.c b/unit-tests/demo.c
new file mode 100644
index 0000000..265f3cb
--- /dev/null
+++ b/unit-tests/demo.c
@@ -0,0 +1,99 @@
+/*
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For the avoidance of doubt the "preferred form" of this code is one which
+ * is in an open unpatent encumbered format. Where cryptographic key signing
+ * forms part of the process of creating an executable the information
+ * including keys needed to generate an equivalently functional executable
+ * are deemed to be part of the source code.
+ */
+
+#include "demo.h"
+
+xmlNode *gen_nodes(const char *entry ) {
+ xmlNode *c_xmlNode_root = NULL;
+ xmlNode *c_xmlNode_tag = NULL;
+
+ // Prepare a root node
+ c_xmlNode_root = xmlNewNode(NULL, (xmlChar *) "dmixml_demo");
+ assert( c_xmlNode_root != NULL );
+
+ dmixml_AddAttribute(c_xmlNode_root, "entrypoint", "%s", entry);
+
+ // Populate XML
+ dmixml_AddTextChild(c_xmlNode_root, "Test", "Yes, just testing");
+
+ c_xmlNode_tag = dmixml_AddTextChild(c_xmlNode_root, "tag1", "Another test");
+ dmixml_AddAttribute(c_xmlNode_tag, "TestTagID", "%i", 1);
+
+ c_xmlNode_tag = c_xmlNode_root;
+ int i;
+ for(i = 0; i <= 3; ++i) {
+ c_xmlNode_tag = xmlNewChild(c_xmlNode_tag, NULL, (xmlChar *) "subtag", NULL);
+ dmixml_AddAttribute(c_xmlNode_tag, "SubLevel", "%i", i);
+ }
+ dmixml_AddTextContent(c_xmlNode_tag, "%s - Adding data to the tag at sublevel %i", "TEST", i-1);
+
+ return c_xmlNode_root;
+}
+
+
+
+
+PyObject* demo_dump_doc() {
+ PyObject *py_xmlDoc = NULL;
+ xmlDoc *c_xmlDoc = NULL;
+
+ // Create an XML document
+ c_xmlDoc = xmlNewDoc((xmlChar *) "1.0");
+ assert( c_xmlDoc != NULL );
+
+ // Generate XML nodes and assign the root node to the document
+ xmlDocSetRootElement( c_xmlDoc, gen_nodes("demo_dump_doc") );
+
+ py_xmlDoc = libxml_xmlDocPtrWrap((xmlDocPtr) c_xmlDoc);
+ Py_INCREF(py_xmlDoc);
+
+ return py_xmlDoc;
+}
+
+PyObject* demo_dump_node() {
+ PyObject *py_xmlNode = NULL;
+ xmlNode *nodes = NULL;
+
+ nodes = gen_nodes("demo_dump_node");
+ py_xmlNode = libxml_xmlNodePtrWrap((xmlNodePtr) nodes);
+ Py_INCREF(py_xmlNode);
+
+ return py_xmlNode;
+}
+
+
+
+static PyMethodDef DemoMethods[] = {
+ { "dump_doc", demo_dump_doc, METH_NOARGS, (char *)"Return an XML document" },
+ { "dump_node", demo_dump_node, METH_NOARGS, (char *)"Retuen an XML node" },
+ { NULL, NULL, 0, NULL }
+};
+
+PyMODINIT_FUNC initdemomodule(void) {
+ PyObject *module =
+ Py_InitModule3((char *)"demomodule", DemoMethods,
+ "LibXML2 DMIDecode Proof-of-Concept Python Module");
+
+ PyObject *version = PyString_FromString("0.10");
+ Py_INCREF(version);
+ PyModule_AddObject(module, "version", version);
+}
diff --git a/unit-tests/demo.h b/unit-tests/demo.h
new file mode 100644
index 0000000..21a5468
--- /dev/null
+++ b/unit-tests/demo.h
@@ -0,0 +1,14 @@
+#include <Python.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <libxml/tree.h>
+#include "libxml_wrap.h"
+
+#include "dmixml.h"
+
+extern PyObject* demo_dump(void);
+PyMODINIT_FUNC initdemomodule(void);
+PyObject* demo_dump_doc(void);
+PyObject* demo_dump_node(void);
diff --git a/unit-tests/dmixml.c b/unit-tests/dmixml.c
new file mode 100644
index 0000000..dbca0c3
--- /dev/null
+++ b/unit-tests/dmixml.c
@@ -0,0 +1,248 @@
+/* Simplified XML API for dmidecode
+ *
+ * Copyright 2009 David Sommerseth <davids@redhat.com>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For the avoidance of doubt the "preferred form" of this code is one which
+ * is in an open unpatent encumbered format. Where cryptographic key signing
+ * forms part of the process of creating an executable the information
+ * including keys needed to generate an equivalently functional executable
+ * are deemed to be part of the source code.
+ */
+
+#include <string.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#include <libxml/tree.h>
+#include <libxml/xpath.h>
+#include <libxml/xmlstring.h>
+
+// Internal function for dmixml_* functions ... builds up a variable xmlChar* string
+xmlChar *dmixml_buildstr(size_t len, const char *fmt, va_list ap) {
+ xmlChar *ret = NULL, *xmlfmt = NULL;
+ xmlChar *ptr = NULL;
+
+ ret = (xmlChar *) malloc(len+2);
+ assert( ret != NULL );
+ memset(ret, 0, len+2);
+
+ xmlfmt = xmlCharStrdup(fmt);
+ assert( xmlfmt != NULL );
+
+ xmlStrVPrintf(ret, len, xmlfmt, ap);
+ free(xmlfmt);
+
+ // Right trim the string
+ ptr = ret + xmlStrlen(ret)-1;
+ while( (ptr >= ret) && (*ptr == ' ') ) {
+ *ptr = 0;
+ ptr--;
+ }
+ return ret;
+}
+
+
+// Adds an XML property/attribute to the given XML node
+//
+// xmldata_n = "<test/>";
+// dmixml_AddAttribute(xmldata_n, "value", "1234");
+// gives: xmldata_n = "<test value="1234/>"
+//
+
+xmlAttr *dmixml_AddAttribute(xmlNode *node, const char *atrname, const char *fmt, ...)
+{
+ xmlChar *val_s = NULL, *atrname_s = NULL;
+ xmlAttr *res = NULL;
+ va_list ap;
+
+ if( (node == NULL) || (atrname == NULL) || (fmt == NULL) ) {
+ return NULL;
+ }
+
+ atrname_s = xmlCharStrdup(atrname);
+ assert( atrname_s != NULL );
+
+ va_start(ap, fmt);
+ val_s = dmixml_buildstr(2048, fmt, ap);
+ va_end(ap);
+
+ res = xmlNewProp(node, atrname_s,
+ (xmlStrcmp(val_s, (xmlChar *) "(null)") == 0 ? NULL : val_s));
+
+ free(atrname_s);
+ free(val_s);
+
+ assert( res != NULL );
+ return res;
+}
+
+
+// Adds a new XML tag to the current node with the given tag name and value.
+//
+// xmldata_n = "<test>";
+// dmixml_AddTextChild(xmldata_n, "sublevel1", "value");
+// gives: xmldata_n = "<test><sublevel1>value</sublevel1></test>"
+//
+xmlNode *dmixml_AddTextChild(xmlNode *node, const char *tagname, const char *fmt, ...)
+{
+ xmlChar *val_s = NULL, *tagname_s = NULL;
+ xmlNode *res = NULL;
+ va_list ap;
+
+ if( (node == NULL) || (tagname == NULL) || (fmt == NULL) ) {
+ return NULL;
+ }
+
+ tagname_s = xmlCharStrdup(tagname);
+ assert( tagname_s != NULL );
+
+ va_start(ap, fmt);
+ val_s = dmixml_buildstr(2048, fmt, ap);
+ va_end(ap);
+
+ // Do not add any contents if the string contents is "(null)"
+ res = xmlNewTextChild(node, NULL, tagname_s,
+ (xmlStrcmp(val_s, (xmlChar *) "(null)") == 0 ? NULL : val_s));
+
+ free(tagname_s);
+ free(val_s);
+
+ assert( res != NULL );
+ return res;
+}
+
+// Adds a text node child to the current XML node
+//
+// xmldata_n = "<testdata/>;
+// dmixml_AddTextContent(xmldata_n, "some data value");
+// gives: xmldata_n = "<testdata>some data value</testdata>"
+//
+xmlNode *dmixml_AddTextContent(xmlNode *node, const char *fmt, ...)
+{
+ xmlChar *val_s = NULL;
+ xmlNode *res = NULL;
+ va_list ap;
+
+ if( (node == NULL) || (fmt == NULL) ) {
+ return NULL;
+ }
+
+ va_start(ap, fmt);
+ val_s = dmixml_buildstr(2048, fmt, ap);
+ va_end(ap);
+
+ if( xmlStrcmp(val_s, (xmlChar *) "(null)") != 0 ) {
+ res = xmlAddChild(node, xmlNewText(val_s));
+ } else {
+ res = node;
+ }
+ free(val_s);
+
+ assert( res != NULL );
+ return res;
+}
+
+
+char *dmixml_GetAttrValue(xmlNode *node, const char *key) {
+ xmlAttr *aptr = NULL;
+ xmlChar *key_s = NULL;
+
+ if( node == NULL ) {
+ return NULL;
+ }
+
+ key_s = xmlCharStrdup(key);
+ assert( key_s != NULL );
+
+ for( aptr = node->properties; aptr != NULL; aptr = aptr->next ) {
+ if( xmlStrcmp(aptr->name, key_s) == 0 ) {
+ free(key_s); key_s = NULL;
+ // FIXME: Should find better way how to return UTF-8 data
+ return (char *)(aptr->children != NULL ? aptr->children->content : NULL);
+ }
+ }
+ free(key_s); key_s = NULL;
+ return NULL;
+}
+
+xmlNode *dmixml_FindNode(xmlNode *node, const char *key) {
+ xmlNode *ptr_n = NULL;
+ xmlChar *key_s = NULL;
+
+ if( node->children == NULL ) {
+ return NULL;
+ }
+
+ key_s = xmlCharStrdup(key);
+ assert( key_s != NULL );
+
+ for( ptr_n = node->children; ptr_n != NULL; ptr_n = ptr_n->next ) {
+ if( (ptr_n->type == XML_ELEMENT_NODE)
+ && (xmlStrcmp(ptr_n->name, key_s) == 0) ) {
+ free(key_s); key_s = NULL;
+ return ptr_n;
+ }
+ }
+ free(key_s); key_s = NULL;
+ return NULL;
+}
+
+inline char *dmixml_GetContent(xmlNode *node) {
+ // FIXME: Should find better way how to return UTF-8 data
+ return (((node != NULL) && (node->children != NULL)) ? (char *) node->children->content : NULL);
+}
+
+inline char *dmixml_GetNodeContent(xmlNode *node, const char *key) {
+ return dmixml_GetContent(dmixml_FindNode(node, key));
+}
+
+char *dmixml_GetXPathContent(char *buf, size_t buflen, xmlXPathObject *xpo, int idx) {
+ memset(buf, 0, buflen);
+
+ if( xpo == NULL ) {
+ return NULL;
+ }
+
+ switch( xpo->type ) {
+ case XPATH_STRING:
+ strncpy(buf, (char *)xpo->stringval, buflen-1);
+ break;
+
+ case XPATH_NUMBER:
+ snprintf(buf, buflen-1, "%f", xpo->floatval);
+ break;
+
+ case XPATH_NODESET:
+ if( (xpo->nodesetval != NULL) && (xpo->nodesetval->nodeNr >= (idx+1)) ) {
+ char *str = dmixml_GetContent(xpo->nodesetval->nodeTab[idx]);
+ if( str != NULL ) {
+ strncpy(buf, str, buflen-1);
+ } else {
+ memset(buf, 0, buflen);
+ }
+ }
+ break;
+
+ default:
+ fprintf(stderr, "dmixml_GetXPathContent(...):: "
+ "Do not know how to handle XPath type %i\n",
+ xpo->type);
+ return NULL;
+ }
+ return buf;
+}
+
diff --git a/unit-tests/dmixml.h b/unit-tests/dmixml.h
new file mode 100644
index 0000000..b1d86c6
--- /dev/null
+++ b/unit-tests/dmixml.h
@@ -0,0 +1,43 @@
+/* Simplified XML API for dmidecode
+ *
+ * Copyright 2009 David Sommerseth <davids@redhat.com>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For the avoidance of doubt the "preferred form" of this code is one which
+ * is in an open unpatent encumbered format. Where cryptographic key signing
+ * forms part of the process of creating an executable the information
+ * including keys needed to generate an equivalently functional executable
+ * are deemed to be part of the source code.
+ */
+
+#ifndef _XMLHELPER_H
+#define _XMLHELPER_H
+
+#include <stdarg.h>
+#include <libxml/tree.h>
+#include <libxml/xpath.h>
+
+xmlAttr *dmixml_AddAttribute(xmlNode *node, const char *atrname, const char *fmt, ...);
+xmlNode *dmixml_AddTextChild(xmlNode *node, const char *tagname, const char *fmt, ...);
+xmlNode *dmixml_AddTextContent(xmlNode *node, const char *fmt, ...);
+
+char *dmixml_GetAttrValue(xmlNode *node, const char *key);
+xmlNode *dmixml_FindNode(xmlNode *, const char *key);
+inline char *dmixml_GetContent(xmlNode *node);
+inline char *dmixml_GetNodeContent(xmlNode *node, const char *key);
+char *dmixml_GetXPathContent(char *buf, size_t buflen, xmlXPathObject *xpo, int idx);
+
+#endif
diff --git a/unit-tests/libxml_wrap.h b/unit-tests/libxml_wrap.h
new file mode 100644
index 0000000..eaa5e96
--- /dev/null
+++ b/unit-tests/libxml_wrap.h
@@ -0,0 +1,249 @@
+#include <Python.h>
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/catalog.h>
+#include <libxml/threads.h>
+#include <libxml/nanoftp.h>
+#include <libxml/nanohttp.h>
+#include <libxml/uri.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/debugXML.h>
+#include <libxml/HTMLparser.h>
+#include <libxml/HTMLtree.h>
+#include <libxml/xinclude.h>
+#include <libxml/xpointer.h>
+#include <libxml/xmlunicode.h>
+#include <libxml/xmlregexp.h>
+#include <libxml/xmlautomata.h>
+#include <libxml/xmlreader.h>
+#ifdef LIBXML_SCHEMAS_ENABLED
+#include <libxml/relaxng.h>
+#include <libxml/xmlschemas.h>
+#endif
+
+/**
+ * ATTRIBUTE_UNUSED:
+ *
+ * Macro used to signal to GCC unused function parameters
+ * Repeated here since the definition is not available when
+ * compiled outside the libxml2 build tree.
+ */
+#ifdef __GNUC__
+#ifdef ATTRIBUTE_UNUSED
+#undef ATTRIBUTE_UNUSED
+#endif
+#ifndef ATTRIBUTE_UNUSED
+#define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
+#endif /* ATTRIBUTE_UNUSED */
+#else
+#define ATTRIBUTE_UNUSED
+#endif
+
+#define PyxmlNode_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyxmlNode_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlNodePtr obj;
+} PyxmlNode_Object;
+
+#define PyxmlXPathContext_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyxmlXPathContext_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlXPathContextPtr obj;
+} PyxmlXPathContext_Object;
+
+#define PyxmlXPathParserContext_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyxmlXPathParserContext_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlXPathParserContextPtr obj;
+} PyxmlXPathParserContext_Object;
+
+#define PyparserCtxt_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyparserCtxt_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlParserCtxtPtr obj;
+} PyparserCtxt_Object;
+
+#define PyValidCtxt_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyValidCtxt_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlValidCtxtPtr obj;
+} PyValidCtxt_Object;
+
+#define Pycatalog_Get(v) (((v) == Py_None) ? NULL : \
+ (((Pycatalog_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlCatalogPtr obj;
+} Pycatalog_Object;
+
+#ifdef LIBXML_REGEXP_ENABLED
+#define PyxmlReg_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyxmlReg_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlRegexpPtr obj;
+} PyxmlReg_Object;
+#endif /* LIBXML_REGEXP_ENABLED */
+
+#ifdef LIBXML_READER_ENABLED
+#define PyxmlTextReader_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyxmlTextReader_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlTextReaderPtr obj;
+} PyxmlTextReader_Object;
+
+#define PyxmlTextReaderLocator_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyxmlTextReaderLocator_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlTextReaderLocatorPtr obj;
+} PyxmlTextReaderLocator_Object;
+#endif
+
+#define PyURI_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyURI_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlErrorPtr obj;
+} PyError_Object;
+
+#define PyError_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyError_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlOutputBufferPtr obj;
+} PyoutputBuffer_Object;
+
+#define PyoutputBuffer_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyoutputBuffer_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlParserInputBufferPtr obj;
+} PyinputBuffer_Object;
+
+#define PyinputBuffer_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyinputBuffer_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlURIPtr obj;
+} PyURI_Object;
+
+/* FILE * have their own internal representation */
+#define PyFile_Get(v) (((v) == Py_None) ? NULL : \
+ (PyFile_Check(v) ? (PyFile_AsFile(v)) : stdout))
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+typedef struct {
+ PyObject_HEAD
+ xmlRelaxNGPtr obj;
+} PyrelaxNgSchema_Object;
+
+#define PyrelaxNgSchema_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyrelaxNgSchema_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlRelaxNGParserCtxtPtr obj;
+} PyrelaxNgParserCtxt_Object;
+
+#define PyrelaxNgParserCtxt_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyrelaxNgParserCtxt_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlRelaxNGValidCtxtPtr obj;
+} PyrelaxNgValidCtxt_Object;
+
+#define PyrelaxNgValidCtxt_Get(v) (((v) == Py_None) ? NULL : \
+ (((PyrelaxNgValidCtxt_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlSchemaPtr obj;
+} PySchema_Object;
+
+#define PySchema_Get(v) (((v) == Py_None) ? NULL : \
+ (((PySchema_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlSchemaParserCtxtPtr obj;
+} PySchemaParserCtxt_Object;
+
+#define PySchemaParserCtxt_Get(v) (((v) == Py_None) ? NULL : \
+ (((PySchemaParserCtxt_Object *)(v))->obj))
+
+typedef struct {
+ PyObject_HEAD
+ xmlSchemaValidCtxtPtr obj;
+} PySchemaValidCtxt_Object;
+
+#define PySchemaValidCtxt_Get(v) (((v) == Py_None) ? NULL : \
+ (((PySchemaValidCtxt_Object *)(v))->obj))
+
+#endif /* LIBXML_SCHEMAS_ENABLED */
+
+PyObject * libxml_intWrap(int val);
+PyObject * libxml_longWrap(long val);
+PyObject * libxml_xmlCharPtrWrap(xmlChar *str);
+PyObject * libxml_constxmlCharPtrWrap(const xmlChar *str);
+PyObject * libxml_charPtrWrap(char *str);
+PyObject * libxml_constcharPtrWrap(const char *str);
+PyObject * libxml_charPtrConstWrap(const char *str);
+PyObject * libxml_xmlCharPtrConstWrap(const xmlChar *str);
+PyObject * libxml_xmlDocPtrWrap(xmlDocPtr doc);
+PyObject * libxml_xmlNodePtrWrap(xmlNodePtr node);
+PyObject * libxml_xmlAttrPtrWrap(xmlAttrPtr attr);
+PyObject * libxml_xmlNsPtrWrap(xmlNsPtr ns);
+PyObject * libxml_xmlAttributePtrWrap(xmlAttributePtr ns);
+PyObject * libxml_xmlElementPtrWrap(xmlElementPtr ns);
+PyObject * libxml_doubleWrap(double val);
+PyObject * libxml_xmlXPathContextPtrWrap(xmlXPathContextPtr ctxt);
+PyObject * libxml_xmlParserCtxtPtrWrap(xmlParserCtxtPtr ctxt);
+PyObject * libxml_xmlXPathParserContextPtrWrap(xmlXPathParserContextPtr ctxt);
+PyObject * libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj);
+PyObject * libxml_xmlValidCtxtPtrWrap(xmlValidCtxtPtr valid);
+PyObject * libxml_xmlCatalogPtrWrap(xmlCatalogPtr obj);
+PyObject * libxml_xmlURIPtrWrap(xmlURIPtr uri);
+PyObject * libxml_xmlOutputBufferPtrWrap(xmlOutputBufferPtr buffer);
+PyObject * libxml_xmlParserInputBufferPtrWrap(xmlParserInputBufferPtr buffer);
+#ifdef LIBXML_REGEXP_ENABLED
+PyObject * libxml_xmlRegexpPtrWrap(xmlRegexpPtr regexp);
+#endif /* LIBXML_REGEXP_ENABLED */
+#ifdef LIBXML_READER_ENABLED
+PyObject * libxml_xmlTextReaderPtrWrap(xmlTextReaderPtr reader);
+PyObject * libxml_xmlTextReaderLocatorPtrWrap(xmlTextReaderLocatorPtr locator);
+#endif
+
+xmlXPathObjectPtr libxml_xmlXPathObjectPtrConvert(PyObject * obj);
+#ifdef LIBXML_SCHEMAS_ENABLED
+PyObject * libxml_xmlRelaxNGPtrWrap(xmlRelaxNGPtr ctxt);
+PyObject * libxml_xmlRelaxNGParserCtxtPtrWrap(xmlRelaxNGParserCtxtPtr ctxt);
+PyObject * libxml_xmlRelaxNGValidCtxtPtrWrap(xmlRelaxNGValidCtxtPtr valid);
+PyObject * libxml_xmlSchemaPtrWrap(xmlSchemaPtr ctxt);
+PyObject * libxml_xmlSchemaParserCtxtPtrWrap(xmlSchemaParserCtxtPtr ctxt);
+PyObject * libxml_xmlSchemaValidCtxtPtrWrap(xmlSchemaValidCtxtPtr valid);
+#endif /* LIBXML_SCHEMAS_ENABLED */
+PyObject * libxml_xmlErrorPtrWrap(xmlErrorPtr error);
+PyObject * libxml_xmlSchemaSetValidErrors(PyObject * self, PyObject * args);
diff --git a/unit-tests/unit b/unit-tests/unit
new file mode 100755
index 0000000..ac3edab
--- /dev/null
+++ b/unit-tests/unit
@@ -0,0 +1,268 @@
+#!/usr/bin/env python
+#.awk '$0 ~ /case [0-9]+: .. 3/ { sys.stdout.write($2 }' src/dmidecode.c|tr ':\n' ', '
+
+from pprint import pprint
+import os, sys, random, tempfile, time
+import commands
+
+DUMPS_D = "private"
+
+def ascii(s, i): return "\033[%d;1m%s\033[0m"%(30+i, str(s))
+def black(s): return "\033[30;1m%s\033[0m"%(str(s))
+def red(s): return "\033[31;1m%s\033[0m"%(str(s))
+def green(s): return "\033[32;1m%s\033[0m"%(str(s))
+def yellow(s): return "\033[33;1m%s\033[0m"%(str(s))
+def blue(s): return "\033[34;1m%s\033[0m"%(str(s))
+def magenta(s): return "\033[35;1m%s\033[0m"%(str(s))
+def cyan(s): return "\033[36;1m%s\033[0m"%(str(s))
+def white(s): return "\033[37;1m%s\033[0m"%(str(s))
+
+DISPATCH = {
+ 1 : red,
+ 2 : green,
+ 3 : yellow,
+ 4 : blue,
+ 5 : magenta,
+ 6 : cyan,
+ 7 : white,
+}
+
+LINE = "%s\n"%(magenta("="*80))
+
+score = {
+ "total" : 0,
+ "skipped" : 0,
+ "passed" : 0,
+ "failed" : 0,
+}
+
+def passed(msg=None, indent=1):
+ global score
+ score["total"] += 1
+ score["passed"] += 1
+ sys.stdout.write("%s\n"%green("PASS"))
+ if msg: sys.stdout.write("%s %s %s\n"%(" "*indent, green("P"), msg))
+def skipped(msg=None, indent=1):
+ global score
+ score["total"] += 1
+ score["skipped"] += 1
+ sys.stdout.write("%s\n"%yellow("SKIP"))
+ if msg: sys.stdout.write("%s %s %s\n"%(" "*indent, yellow("S"), msg))
+def failed(msg=None, indent=1):
+ global score
+ score["total"] += 1
+ score["failed"] += 1
+ sys.stdout.write("%s\n"%red("FAIL"))
+ if msg: sys.stdout.write("%s %s %s\n"%(" "*indent, red("F"), msg))
+def test(r, msg=None, indent=1):
+ if r:
+ passed(msg, indent)
+ return True
+ else:
+ failed(msg, indent)
+ return False
+
+sys.stdout.write(LINE)
+sys.stdout.write(" * Testing for dmidecode (upstream)...")
+dmidecode_bin = True in [os.path.exists(os.path.join(_, "dmidecode")) for _ in os.getenv("PATH").split(':')]
+test(dmidecode_bin)
+
+sys.stdout.write(" * Creation of temporary files...")
+try:
+ FH, DUMP = tempfile.mkstemp()
+ os.unlink(DUMP)
+ os.close(FH)
+ passed()
+except:
+ failed()
+
+sys.stdout.write(LINE)
+try:
+ sys.stdout.write(" * Importing module...")
+ import libxml2
+# from dmidecodemod import *
+ import dmidecode
+ passed()
+
+ sys.stdout.write(" * Version: %s\n"%blue(dmidecode.version))
+ sys.stdout.write(" * DMI Version String: %s\n"%blue(dmidecode.dmi))
+
+ sys.stdout.write(" * Testing that default device is /dev/mem...")
+ test(dmidecode.get_dev() == "/dev/mem")
+
+ sys.stdout.write(" * Testing that write-lock will not break on dump()...")
+ test(not dmidecode.dump())
+
+ sys.stdout.write(" * Testing ability to change device to %s..."%DUMP)
+ test(dmidecode.set_dev(DUMP))
+
+ sys.stdout.write(" * Testing that device has changed to %s..."%DUMP)
+ test(dmidecode.get_dev() == DUMP)
+
+ sys.stdout.write(" * Testing that write on new file is ok...")
+ test(dmidecode.dump())
+
+ sys.stdout.write(" * Testing that file was actually written...")
+ time.sleep(0.1)
+ if test(os.path.exists(DUMP)):
+ os.unlink(DUMP)
+
+ types = range(0, 42)+range(126, 128)
+ bad_types = [-1, -1000, 256]
+ sections = ["bios", "system", "baseboard", "chassis", "processor", "memory", "cache", "connector", "slot"]
+ devices = []
+ if os.path.exists(DUMPS_D):
+ devices.extend([os.path.join(DUMPS_D, _) for _ in os.listdir(DUMPS_D)])
+ else:
+ sys.stdout.write(" * If you have memory dumps to test, create a directory called `%s' and drop them in there.\n"%(DUMPS_D))
+ devices.append("/dev/mem")
+ random.shuffle(types)
+ random.shuffle(devices)
+ random.shuffle(sections)
+
+ for dev in devices:
+ sys.stdout.write(LINE)
+ sys.stdout.write(" * Testing %s..."%yellow(dev)); sys.stdout.flush()
+ try:
+ fH = open(dev, 'r')
+ fH.close()
+ passed()
+ sys.stdout.write(" * Testing set_dev/get_dev on %s..."%(yellow(dev))); sys.stdout.flush()
+ if test(dmidecode.set_dev(dev) and dmidecode.get_dev() == dev):
+ i = 0
+ for section in sections:
+ i += 1
+ sys.stdout.write(" * Testing %s (%d/%d)..."%(cyan(section), i, len(sections))); sys.stdout.flush()
+ try:
+ output = getattr(dmidecode, section)()
+ test(output is not False)
+ if output:
+ sys.stdout.write(" * %s\n"%black(output.keys()))
+ except LookupError, e:
+ failed(e, 2)
+
+ for i in bad_types:
+ sys.stdout.write(" * Testing bad type %s..."%red(i)); sys.stdout.flush()
+ try:
+ output = dmidecode.type(i)
+ test(output is False)
+ except SystemError:
+ failed()
+
+ for i in types:
+ sys.stdout.write(" * Testing type %s..."%red(i)); sys.stdout.flush()
+ try:
+ output = dmidecode.type(i)
+ if dmidecode_bin:
+ _output = commands.getoutput("dmidecode -t %d"%i).strip().split('\n')
+ test(len(_output) == 1 and len(output) == 0 or True)
+ else:
+ test(output is not False)
+ if output:
+ sys.stdout.write(" * %s\n"%output.keys())
+ except IOError, e:
+ failed(e, 2)
+ except LookupError, e:
+ failed(e, 2)
+
+ dmixml = dmidecode.dmidecodeXML()
+ try:
+ sys.stdout.write(" * XML: Swapping result type dmidecodeXML::SetResultType('-')...");
+ sys.stdout.flush()
+ test(not dmixml.SetResultType('-'))
+ except TypeError:
+ sys.stdout.write("Not working => ")
+ passed()
+ except:
+ sys.stdout.write("Accepted => ")
+ failed()
+
+ try:
+ sys.stdout.write(" * XML: Swapping result type - dmidecodeXML::SetResultType(dmidecode.DMIXML_DOC)...");
+ sys.stdout.flush()
+ test(dmixml.SetResultType(dmidecode.DMIXML_DOC))
+ sys.stdout.write(" * XML: Swapping result type - dmidecodeXML::SetResultType(dmidecode.DMIXML_NODE)...");
+ sys.stdout.flush()
+ test(dmixml.SetResultType(dmidecode.DMIXML_NODE))
+ except:
+ failed()
+
+ for i in bad_types:
+ sys.stdout.write(" * XML: Testing bad type - dmidecodeXML::QueryTypeId(%s)..."
+ % red(i))
+ sys.stdout.flush()
+ try:
+ output_node = dmixml.QueryTypeId(i)
+ test(not isinstance(output_node, libxml2.xmlNode))
+ except SystemError:
+ sys.stdout.write("Accepted => ")
+ failed()
+ except TypeError:
+ sys.stdout.write("Not working => ")
+ passed()
+ except ValueError:
+ sys.stdout.write("Not working => ")
+ passed()
+
+ for i in types:
+ sys.stdout.write(" * XML: Testing dmidecodeXML::QueryTypeId(%s)..."
+ % red(i))
+ sys.stdout.flush()
+ try:
+ output_node = dmixml.QueryTypeId(i)
+ test(isinstance(output_node, libxml2.xmlNode))
+ except Exception, e:
+ failed(e, 2)
+ except:
+ failed()
+
+ dmixml.SetResultType(dmidecode.DMIXML_DOC)
+ i = 0
+ for section in sections:
+ i += 1
+ sys.stdout.write(" * XML: Testing dmidecodeXML::QuerySection('%s') (%d/%d)..."
+ % (cyan(section), i, len(sections)))
+ sys.stdout.flush()
+ try:
+ output_doc = dmixml.QuerySection(section)
+ test(isinstance(output_doc, libxml2.xmlDoc))
+ except Exception, e:
+ failed(e, 2)
+ except:
+ failed()
+
+ except IOError:
+ skipped()
+
+except ImportError, err:
+ failed()
+ print err
+
+
+"""
+import libxml2
+from POCDemo import POCDemo
+
+test = POCDemo()
+print "Please note the dmixml_demo/@entrypoint attribute in the root node"
+print
+print "-------- xmlDoc ---------------"
+xmldoc = test.GetXMLdoc()
+xmldoc.saveFormatFileEnc("-", "UTF-8", 1)
+
+print
+print "-------- xmlNode ---------------"
+xmldoc2 = libxml2.newDoc("1.0")
+xmlnode = test.GetXMLnode()
+xmldoc2.setRootElement(xmlnode)
+xmldoc2.saveFormatFileEnc("-", "UTF-8", 1)
+"""
+
+
+
+sys.stdout.write(LINE)
+sys.stdout.write("Devices : %s\n"%cyan(len(devices)))
+sys.stdout.write("Total : %s\n"%blue(score["total"]))
+sys.stdout.write("Skipped : %s\n"%yellow(score["skipped"]))
+sys.stdout.write("Passed : %s\n"%green(score["passed"]))
+sys.stdout.write("Failed : %s\n"%red(score["failed"]))
diff --git a/utils/c-code-indent b/utils/c-code-indent
new file mode 100755
index 0000000..0d5381d
--- /dev/null
+++ b/utils/c-code-indent
@@ -0,0 +1,3 @@
+#!/bin/sh
+PARAM="-npro -kr -nut -bbb -bad -i8 -ts8 -sob -l100 -ss -ncs -cp1 -sc -nsaf -nsai -nsaw -nbbo -hnl -br -ce"
+indent $PARAM "$@"
diff --git a/utils/set_version b/utils/set_version
new file mode 100755
index 0000000..c42f6d6
--- /dev/null
+++ b/utils/set_version
@@ -0,0 +1,56 @@
+#!/bin/sh
+
+if [ $# != 1 ]; then
+ echo "Usage: $0 <new version number>"
+ exit 1
+fi
+
+if [ ! -d ./src -a ! -f redhat.spec ]; then
+ echo "Cannot find the ./src directory or the ./redhat.spec file"
+ echo "Are you in the project root directory?"
+ exit 2
+fi
+
+NEW_VERSION=$1
+OLD_VERSION=$(cd src;python -c "from setup_common import *; print get_version();")
+
+cat <<EOF
+
+ **
+ ** Changing version number
+ **
+
+ Are you sure you want to change the version number?
+
+ From: ${OLD_VERSION}
+ To: ${NEW_VERSION}
+
+EOF
+echo -n " Please confirm: (yes/no) "
+read conf
+
+case $conf in
+ yes|YES)
+ echo
+ echo " ** Updating src/version.h"
+ printf ",s/^#define VERSION \".*\"/#define VERSION \"${NEW_VERSION}\"/\nw\n" | ed src/version.h 2>/dev/null
+
+ echo " ** Updating redhat.spec"
+ printf ",s/^Version: .*/Version: ${NEW_VERSION}/\nw\n" | ed contrib/python-dmidecode.spec 2>/dev/null
+
+ echo
+ echo " ** git add src/version.h redhat.spec"
+ git add src/version.h contrib/python-dmidecode.spec
+ git diff --cached
+ echo
+ echo " REMEMBER to commit this change when you have validated the result"
+ echo
+ ;;
+ *)
+ echo
+ echo
+ echo " ** Not confirmed. Aborting."
+ echo
+ ;;
+esac
+