From 78d0639b14007a0765914c37df70d8021973fc16 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Tue, 28 Apr 2009 00:55:28 +1000 Subject: [PATCH 001/146] Version number fix --- debian/rules | 1 - src/setup-dbg.py | 2 +- src/setup.py | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/debian/rules b/debian/rules index a5b0785..906da77 100755 --- a/debian/rules +++ b/debian/rules @@ -54,7 +54,6 @@ binary-arch: build install dh_md5sums dh_builddeb - ################################################################################ #. Clean clean: diff --git a/src/setup-dbg.py b/src/setup-dbg.py index 1a23240..65f7436 100644 --- a/src/setup-dbg.py +++ b/src/setup-dbg.py @@ -2,7 +2,7 @@ setup( name = "python-dmidecode-dbg", - version = "2.10.3", + version = "2.10.5", description = "Python extension module for dmidecode", author = "Nima Talebi", author_email = "nima@autonomy.net.au", diff --git a/src/setup.py b/src/setup.py index b0999b5..14f16dd 100644 --- a/src/setup.py +++ b/src/setup.py @@ -2,7 +2,7 @@ setup( name = "python-dmidecode", - version = "2.10.3", + version = "2.10.5", description = "Python extension module for dmidecode", author = "Nima Talebi", author_email = "nima@autonomy.net.au", From 178300c991d09062bedb30835ebf903c837e510c Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Wed, 20 May 2009 22:33:04 +1000 Subject: [PATCH 002/146] Preparing to push new fixed version to Debian --- debian/changelog | 9 +++++++++ src/dmidecode.c | 12 ------------ 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/debian/changelog b/debian/changelog index 4cdf996..e9a044f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +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. + + -- Nima Talebi Wed, 20 May 2009 22:32:24 +1000 + python-dmidecode (2.10.5-3) unstable; urgency=low * Converting to pysupport from pycentral. diff --git a/src/dmidecode.c b/src/dmidecode.c index 40cb861..bbf05cf 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -3201,8 +3201,6 @@ PyObject* dmi_decode(struct dmi_header *h, u16 ver) { case 5: /* 3.3.6 Memory Controller Information */ - PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h)); - if(h->length<0x0F) break; _val = dmi_memory_controller_ed_method(data[0x04]); PyDict_SetItemString(caseData, "Error Detecting Method", _val); @@ -3253,8 +3251,6 @@ PyObject* dmi_decode(struct dmi_header *h, u16 ver) { case 6: /* 3.3.7 Memory Module Information */ - PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h)); - if(h->length<0x0C) break; _val = dmi_string_py(h, data[0x04]); PyDict_SetItemString(caseData, "Socket Designation", _val); @@ -3287,8 +3283,6 @@ PyObject* dmi_decode(struct dmi_header *h, u16 ver) { case 7: /* 3.3.8 Cache Information */ - PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h)); - if(h->length<0x0F) break; _val = dmi_string_py(h, data[0x04]); PyDict_SetItemString(caseData, "Socket Designation", _val); @@ -3346,8 +3340,6 @@ PyObject* dmi_decode(struct dmi_header *h, u16 ver) { case 8: /* 3.3.9 Port Connector Information */ - PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h)); - if(h->length<0x09) break; _val = dmi_string_py(h, data[0x04]); PyDict_SetItemString(caseData, "Internal Reference Designator", _val); @@ -3373,8 +3365,6 @@ PyObject* dmi_decode(struct dmi_header *h, u16 ver) { case 9: /* 3.3.10 System Slots */ - PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h)); - if(h->length<0x0C) break; _val = dmi_string_py(h, data[0x04]); PyDict_SetItemString(caseData, "Designation", _val); @@ -3411,8 +3401,6 @@ PyObject* dmi_decode(struct dmi_header *h, u16 ver) { case 11: /* 3.3.12 OEM Strings */ - PyDict_SetItemString(caseData, "dmi_on_board_devices", dmi_on_board_devices(h)); - if(h->length<0x05) break; _val = dmi_oem_strings(h); PyDict_SetItemString(caseData, "Strings", _val); From 693b1d87547be091fe2d8a5ed378c4d33e131623 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Wed, 20 May 2009 23:20:17 +1000 Subject: [PATCH 003/146] Forgot to up the version numbers here --- src/setup-dbg.py | 2 +- src/setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/setup-dbg.py b/src/setup-dbg.py index 65f7436..e4b3b37 100644 --- a/src/setup-dbg.py +++ b/src/setup-dbg.py @@ -2,7 +2,7 @@ setup( name = "python-dmidecode-dbg", - version = "2.10.5", + version = "2.10.6", description = "Python extension module for dmidecode", author = "Nima Talebi", author_email = "nima@autonomy.net.au", diff --git a/src/setup.py b/src/setup.py index 14f16dd..69b1d80 100644 --- a/src/setup.py +++ b/src/setup.py @@ -2,7 +2,7 @@ setup( name = "python-dmidecode", - version = "2.10.5", + version = "2.10.6", description = "Python extension module for dmidecode", author = "Nima Talebi", author_email = "nima@autonomy.net.au", From 5d126d78a77bd41021927ae9bcf9ccc30aeb5ad5 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Wed, 20 May 2009 23:38:51 +1000 Subject: [PATCH 004/146] Final touch (for lintian) prior to dupload --- debian/control | 1 + 1 file changed, 1 insertion(+) diff --git a/debian/control b/debian/control index 750aab2..4874563 100644 --- a/debian/control +++ b/debian/control @@ -25,6 +25,7 @@ Description: Python extension module for dmidecode Package: python-dmidecode-dbg Architecture: any Priority: extra +Section: debug Depends: python-dmidecode (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends}, python-dbg Provides: ${python:Provides} From 39cbdfb56e80cabbd67754d8d77f781e14eaa3da Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 5 Jun 2009 12:25:05 +0200 Subject: [PATCH 005/146] Implemented fix making python-dmidecode work with Python v2.3 This resolves Ticket #7 (http://projects.autonomy.net.au/python-dmidecode/ticket/7) --- src/compat.h | 43 +++++++++++++++++++++++++++++++++++++++++++ src/dmidecodemodule.h | 1 + 2 files changed, 44 insertions(+) create mode 100644 src/compat.h diff --git a/src/compat.h b/src/compat.h new file mode 100644 index 0000000..80a08c6 --- /dev/null +++ b/src/compat.h @@ -0,0 +1,43 @@ +/* Defines to make python-dmidecode work with more Python versions + * + * 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 _COMPAT_H +#define _COMPAT_H + +// Missing in Python 2.3 +#ifndef Py_RETURN_TRUE +#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True +#endif + +// Missing in Python 2.3 +#ifndef Py_RETURN_FALSE +#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False +#endif + +// Missing in Python 2.3 +#ifndef Py_RETURN_NONE +#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None +#endif + +#endif diff --git a/src/dmidecodemodule.h b/src/dmidecodemodule.h index cf1e5f4..2b2bde7 100644 --- a/src/dmidecodemodule.h +++ b/src/dmidecodemodule.h @@ -9,6 +9,7 @@ #include #include +#include "compat.h" #include "version.h" #include "config.h" #include "types.h" From eae46400aa5e9d218ad773f198f3239724c74700 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Wed, 9 Sep 2009 23:04:00 +1000 Subject: [PATCH 006/146] Catching up to Debian --- debian/changelog | 6 ++++++ debian/control | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 01b37e7..f914725 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +python-dmidecode (3.10.6-3) unstable; urgency=low + + * Updating debian/* to generate package. + + -- Nima Talebi Wed, 09 Sep 2009 23:01:48 +1000 + python-dmidecode (3.10.6-2) unstable; urgency=low * Fixed homepage (Closes: #540389). diff --git a/debian/control b/debian/control index f0f88e9..bad8447 100644 --- a/debian/control +++ b/debian/control @@ -6,7 +6,7 @@ Homepage: http://projects.autonomy.net.au/python-dmidecode Maintainer: Nima Talebi Build-Depends: debhelper (> 7), python-support (>= 0.5.3), python, python-all-dev (>= 2.3.5-11), python-all-dbg, electric-fence (> 2) -Standards-Version: 3.8.1 +Standards-Version: 3.8.3 Package: python-dmidecode XB-Python-Version: ${python:Versions} From c285b8c99fc2fcb0d07dc91f4bed64af2395159b Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 23 Sep 2009 09:43:24 +0200 Subject: [PATCH 007/146] Fixed .spec file issues after review from the Fedora community Details can be found here: https://bugzilla.redhat.com/show_bug.cgi?id=515230#c1 The comment regarding check against older Python versions is needed to be able to build RPMs on RHEL4 and RHEL5. --- contrib/python-dmidecode.spec | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/contrib/python-dmidecode.spec b/contrib/python-dmidecode.spec index 0d48fc3..c70f37b 100644 --- a/contrib/python-dmidecode.spec +++ b/contrib/python-dmidecode.spec @@ -1,17 +1,15 @@ %{!?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 +Summary: Python 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 +URL: http://projects.autonomy.net.au/python-dmidecode/ +Source0: http://src.autonomy.net.au/python-dmidecode/%{name}-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root -Requires: libxml2 -Requires: libxml2-python BuildRequires: libxml2-python BuildRequires: libxml2-devel BuildRequires: python-devel @@ -37,7 +35,7 @@ rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root,-) -%doc +%doc README doc/README.upstream doc/LICENSE doc/AUTHORS doc/AUTHORS.upstream %{python_sitearch}/dmidecodemod.so %{python_sitearch}/dmidecode.py %{python_sitearch}/dmidecode.py[co] From 2277a556e4c7e50aa10e677b46efe287872ad116 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 23 Sep 2009 10:27:43 +0200 Subject: [PATCH 008/146] Updated .spec release to -7 --- contrib/python-dmidecode.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/python-dmidecode.spec b/contrib/python-dmidecode.spec index c70f37b..179bbd3 100644 --- a/contrib/python-dmidecode.spec +++ b/contrib/python-dmidecode.spec @@ -4,7 +4,7 @@ Summary: Python module to access DMI data Name: python-dmidecode Version: 3.10.6 -Release: 6%{?dist} +Release: 7%{?dist} License: GPLv2 Group: System Environment/Libraries URL: http://projects.autonomy.net.au/python-dmidecode/ From 8f60441d36bb6c1319b37329d9ba675d0f2dfdf2 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Wed, 9 Sep 2009 23:04:00 +1000 Subject: [PATCH 009/146] Catching up to Debian --- debian/changelog | 6 ++++++ debian/control | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 01b37e7..f914725 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +python-dmidecode (3.10.6-3) unstable; urgency=low + + * Updating debian/* to generate package. + + -- Nima Talebi Wed, 09 Sep 2009 23:01:48 +1000 + python-dmidecode (3.10.6-2) unstable; urgency=low * Fixed homepage (Closes: #540389). diff --git a/debian/control b/debian/control index f0f88e9..bad8447 100644 --- a/debian/control +++ b/debian/control @@ -6,7 +6,7 @@ Homepage: http://projects.autonomy.net.au/python-dmidecode Maintainer: Nima Talebi Build-Depends: debhelper (> 7), python-support (>= 0.5.3), python, python-all-dev (>= 2.3.5-11), python-all-dbg, electric-fence (> 2) -Standards-Version: 3.8.1 +Standards-Version: 3.8.3 Package: python-dmidecode XB-Python-Version: ${python:Versions} From 60c321f6db572d7834bc95cc3d1b6be686df87be Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Wed, 23 Sep 2009 18:30:51 +1000 Subject: [PATCH 010/146] New debian changelog entry. --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index f914725..2dd9228 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +python-dmidecode (3.10.6-4) unstable; urgency=low + + * New Upstream release. + + -- Nima Talebi Wed, 23 Sep 2009 18:29:10 +1000 + python-dmidecode (3.10.6-3) unstable; urgency=low * Updating debian/* to generate package. From efc4b020fd36299b5757d265d32a6bc6ebf2c652 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Wed, 23 Sep 2009 19:07:53 +1000 Subject: [PATCH 011/146] New release (3.10.7) --- contrib/python-dmidecode.spec | 4 ++-- debian/changelog | 4 ++-- src/version.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/contrib/python-dmidecode.spec b/contrib/python-dmidecode.spec index 179bbd3..4d6efdd 100644 --- a/contrib/python-dmidecode.spec +++ b/contrib/python-dmidecode.spec @@ -3,8 +3,8 @@ Summary: Python module to access DMI data Name: python-dmidecode -Version: 3.10.6 -Release: 7%{?dist} +Version: 3.10.7 +Release: 1%{?dist} License: GPLv2 Group: System Environment/Libraries URL: http://projects.autonomy.net.au/python-dmidecode/ diff --git a/debian/changelog b/debian/changelog index 2dd9228..e8190d0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,8 @@ -python-dmidecode (3.10.6-4) unstable; urgency=low +python-dmidecode (3.10.7-1) unstable; urgency=low * New Upstream release. - -- Nima Talebi Wed, 23 Sep 2009 18:29:10 +1000 + -- Nima Talebi Wed, 23 Sep 2009 18:43:29 +1000 python-dmidecode (3.10.6-3) unstable; urgency=low diff --git a/src/version.h b/src/version.h index 70ea80d..133c4e2 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define VERSION "3.10.6" +#define VERSION "3.10.7" From 66ddffc29a5a99f847a8ec8f76f1adbe37c481f6 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Wed, 23 Sep 2009 19:22:24 +1000 Subject: [PATCH 012/146] Added changelog entry for 3.10.7 --- contrib/python-dmidecode.spec | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contrib/python-dmidecode.spec b/contrib/python-dmidecode.spec index 4d6efdd..b2848e6 100644 --- a/contrib/python-dmidecode.spec +++ b/contrib/python-dmidecode.spec @@ -45,6 +45,9 @@ rm -rf $RPM_BUILD_ROOT /usr/share/python-dmidecode/pymap.xml %changelog +* Wed Sep 23 2009 Nima Talebi - 3.10.7-1 +- Updated source0 to new 3.10.7 tar ball + * Wed Jul 13 2009 David Sommerseth - 3.10.6-6 - Only build the python-dmidecode module, not everything From cce0cfdb97d0e6b7d20dc943730981b86f01dc5b Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Mon, 28 Sep 2009 18:41:23 +1000 Subject: [PATCH 013/146] Added libxml2 dependencies. --- debian/changelog | 6 ++++++ debian/control | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index e8190d0..4a8a2fe 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +python-dmidecode (3.10.7-2) unstable; urgency=low + + * Added libxml2 dependencies. + + -- Nima Talebi Mon, 28 Sep 2009 18:41:01 +1000 + python-dmidecode (3.10.7-1) unstable; urgency=low * New Upstream release. diff --git a/debian/control b/debian/control index bad8447..2896939 100644 --- a/debian/control +++ b/debian/control @@ -5,7 +5,8 @@ Priority: optional Homepage: http://projects.autonomy.net.au/python-dmidecode Maintainer: Nima Talebi Build-Depends: debhelper (> 7), python-support (>= 0.5.3), python, - python-all-dev (>= 2.3.5-11), python-all-dbg, electric-fence (> 2) + python-all-dev (>= 2.3.5-11), python-all-dbg, libxml2-dev, python-libxml2, + electric-fence (> 2), Standards-Version: 3.8.3 Package: python-dmidecode From 5ce6a673721eb67fec0d5def75cec08de4eae451 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Mon, 28 Sep 2009 18:59:25 +1000 Subject: [PATCH 014/146] Added note on closing bug --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 4a8a2fe..4491972 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,8 @@ python-dmidecode (3.10.7-2) unstable; urgency=low - * Added libxml2 dependencies. + * Added libxml2 dependencies (Closes: #548669). - -- Nima Talebi Mon, 28 Sep 2009 18:41:01 +1000 + -- Nima Talebi Mon, 28 Sep 2009 18:59:05 +1000 python-dmidecode (3.10.7-1) unstable; urgency=low From 7a2efde2af0afa5649b060126643b6ee91ae7ba8 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 25 Nov 2009 15:55:50 +0100 Subject: [PATCH 015/146] Fixed more python-dmidecode.spec issues after another community review --- contrib/python-dmidecode.spec | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/contrib/python-dmidecode.spec b/contrib/python-dmidecode.spec index b2848e6..7e2b259 100644 --- a/contrib/python-dmidecode.spec +++ b/contrib/python-dmidecode.spec @@ -4,12 +4,13 @@ Summary: Python module to access DMI data Name: python-dmidecode Version: 3.10.7 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv2 Group: System Environment/Libraries URL: http://projects.autonomy.net.au/python-dmidecode/ Source0: http://src.autonomy.net.au/python-dmidecode/%{name}-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root +Requires: libxml2-python BuildRequires: libxml2-python BuildRequires: libxml2-devel BuildRequires: python-devel @@ -42,9 +43,13 @@ rm -rf $RPM_BUILD_ROOT %if "%{python_ver}" >= "2.5" %{python_sitearch}/*.egg-info %endif -/usr/share/python-dmidecode/pymap.xml +%{_datadir}/python-dmidecode/ +%{_datadir}/python-dmidecode/pymap.xml %changelog +* Wed Nov 25 2009 David Sommerseth - 3.10.7-2 +- Fixed some .spec file issues (proper Requires, use _datadir macro) + * Wed Sep 23 2009 Nima Talebi - 3.10.7-1 - Updated source0 to new 3.10.7 tar ball From c029d7c17185c6550d008e50f0b8b9e4029acb2e Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 26 Nov 2009 16:36:54 +0100 Subject: [PATCH 016/146] Fixed more .spec file issues after more reviews --- contrib/python-dmidecode.spec | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/contrib/python-dmidecode.spec b/contrib/python-dmidecode.spec index 7e2b259..be0cd53 100644 --- a/contrib/python-dmidecode.spec +++ b/contrib/python-dmidecode.spec @@ -1,10 +1,10 @@ -%{!?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]")} +%{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")} +%{!?python_ver: %global python_ver %(%{__python} -c "import sys ; print sys.version[:3]")} Summary: Python module to access DMI data Name: python-dmidecode Version: 3.10.7 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv2 Group: System Environment/Libraries URL: http://projects.autonomy.net.au/python-dmidecode/ @@ -44,9 +44,12 @@ rm -rf $RPM_BUILD_ROOT %{python_sitearch}/*.egg-info %endif %{_datadir}/python-dmidecode/ -%{_datadir}/python-dmidecode/pymap.xml %changelog +* Thu Nov 26 2009 David Sommerseth - 3.10.7-3 +- Fixed even more .spec file issues and removed explicit mentioning + of /usr/share/python-dmidecode/pymap.xml + * Wed Nov 25 2009 David Sommerseth - 3.10.7-2 - Fixed some .spec file issues (proper Requires, use _datadir macro) From 82116c58f68e9c80cd0334417f3430d6239450a1 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 27 Nov 2009 17:41:10 +0100 Subject: [PATCH 017/146] Added rpm-md5 Make target This is to build src.rpms which can be built on RHEL distribution. In Fedora 11, RPM changed the file hashing from MD5 to SHA1. The rpm-md5 will use rpmbuild-md5 on these distributions, which then uses the old MD5 hashing. --- Makefile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 107dbdb..98e6df7 100644 --- a/Makefile +++ b/Makefile @@ -47,12 +47,17 @@ tarball: cp -r contrib doc examples Makefile man README src dmidecode.py $(PACKAGE)-$(VERSION) tar -czvf $(PACKAGE)-$(VERSION).tar.gz $(PACKAGE)-$(VERSION) -rpm: tarball +rpm-prep: mkdir -p rpm/{BUILD,RPMS,SRPMS,SPECS,SOURCES} cp contrib/$(PACKAGE).spec rpm/SPECS cp $(PACKAGE)-$(VERSION).tar.gz rpm/SOURCES + +rpm: tarball rpm-prep rpmbuild -ba --define "_topdir $(shell pwd)/rpm" rpm/SPECS/$(PACKAGE).spec +rpm-md5: tarball rpm-prep + rpmbuild-md5 -ba --define "_topdir $(shell pwd)/rpm" rpm/SPECS/$(PACKAGE).spec + unit: $(MAKE) -C unit-tests From dcd9a813205abcaeb179b27771b7a42117d04702 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 10 Dec 2009 19:49:17 +0100 Subject: [PATCH 018/146] Cleaned up the unit test a little bit Don't try to do tests which only root can do if not running as root user and removed not needed code or comments --- unit-tests/unit | 56 ++++++++++++++++++++++--------------------------- 1 file changed, 25 insertions(+), 31 deletions(-) diff --git a/unit-tests/unit b/unit-tests/unit index ac3edab..1dd9c61 100755 --- a/unit-tests/unit +++ b/unit-tests/unit @@ -5,6 +5,8 @@ from pprint import pprint import os, sys, random, tempfile, time import commands +root_user = (os.getuid() == 0 and True or False) + DUMPS_D = "private" def ascii(s, i): return "\033[%d;1m%s\033[0m"%(30+i, str(s)) @@ -63,9 +65,13 @@ def test(r, msg=None, indent=1): return False sys.stdout.write(LINE) -sys.stdout.write(" * Testing for dmidecode (upstream)...") +sys.stdout.write(" * Testing for command line version of dmidecode ...") dmidecode_bin = True in [os.path.exists(os.path.join(_, "dmidecode")) for _ in os.getenv("PATH").split(':')] test(dmidecode_bin) +if root_user: + sys.stdout.write(" * Running test as root user, all tests will be executed\n") +else: + sys.stdout.write(" * %s\n"%red("Running test as normal user, some tests will be skipped")) sys.stdout.write(" * Creation of temporary files...") try: @@ -79,9 +85,11 @@ except: sys.stdout.write(LINE) try: sys.stdout.write(" * Importing module...") + sys.stdout.flush() import libxml2 -# from dmidecodemod import * import dmidecode + if not root_user: + sys.stdout.write("\n%s"%cyan("Not running as root, warning above is expected...")) passed() sys.stdout.write(" * Version: %s\n"%blue(dmidecode.version)) @@ -99,13 +107,16 @@ try: 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()) + if root_user: + 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) + sys.stdout.write(" * Testing that file was actually written...") + time.sleep(0.1) + if test(os.path.exists(DUMP)): + os.unlink(DUMP) + else: + sys.stdout.write(" * %s" %red("Skip testing API function, missing root privileges: dmidecode.dump()\n")) types = range(0, 42)+range(126, 128) bad_types = [-1, -1000, 256] @@ -115,7 +126,12 @@ try: 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") + + if root_user: + devices.append("/dev/mem") + else: + sys.stdout.write(" * %s\n"%red("Running test as normal user, will not try to read /dev/mem\n")) + random.shuffle(types) random.shuffle(devices) random.shuffle(sections) @@ -238,28 +254,6 @@ 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"])) From 734eed972d6065f8b71590b95b9a2f97573a2dcf Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 10 Dec 2009 19:50:30 +0100 Subject: [PATCH 019/146] Added a couple of DMI dumps to be able to run tests as non-root --- .../private/DellPrecisionWorkStation-490.dmp | Bin 0 -> 3919 bytes unit-tests/private/LenovoThinkPad-T61p.dmp | Bin 0 -> 2469 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 unit-tests/private/DellPrecisionWorkStation-490.dmp create mode 100644 unit-tests/private/LenovoThinkPad-T61p.dmp diff --git a/unit-tests/private/DellPrecisionWorkStation-490.dmp b/unit-tests/private/DellPrecisionWorkStation-490.dmp new file mode 100644 index 0000000000000000000000000000000000000000..17e0d6c61811246e0e59c2fac6aecfabf96633b3 GIT binary patch literal 3919 zcmbuC-ES1v8OEP8GyCbUUGHLy4fWWr!I0X_+FtKEs>-hI1)Ho5S$ip_tq?T}S=D%h zZ9b$%cymz&wQ19m+*M6UtF{-tYySX~UR1qHKwLy<9i)CGN-jd>F(4W2K4)fk3<?d0&-=*d_2*XfjJ(2hGv-1!r>SJlRWB8mb^ zQ6X_1*9DIACosjIzy)zZ2wW5wNmtQT6xi6XQ{I^nl@$7lz5)bR0;I8GkU*=&pv4Fo zSPiTK!POvHzgka*RzqZXHB355&nr$+Q#U!x43LItkO?zEwwkSE&agb~`+sTj_B74nVa>yJaon5}8R(9E8cCcfcxs8mPQ8Hzw$lc~{vcYU1`^|px zpm~toW9}iho7>5l86yvwhsaK|lWa5_$+#ION6Zm&ueq1pVeTLY%mH%L93}Ue`^YA< ziG1FCo;++GCM$=CMnEXIr`8qU-uq3U1tE{Z-r?NLj6OO$-K~GFA!$TmMECdf?e8&+ z7)LilFoQarN~hBZ94j9G%Z($E-otL-%aa_P%T4F!^MzUc+l9FwOe~yQklTF&hTIzl z)5nf81E6@J2u0PNkqE}2tP$_!;TY)d9vYAI#`=s{f4>nKj&}oU4OHO)$EvFOjN$fK zIeXeXN$7yq2~DVfR_^m0Hr75}!nJ+c2ek=zQiDf$tV^dTiiWZL^jzWPxx#dAe!eh= z(bO4P|Gb%@u>D_A^1Q%d$cD651$&H$07KGs(AoUi0AUEf&c=R z>2i6csXQxE{bHoo2QO2(l%vT^GM!GP0k2O;%j=s+Wk!?fh}=}3bb6$tN~f;og{i?| zDK$&hjvdKPq@;F9T_4C!3|iyejd9+L2sT zyuKPKt6EaysYxkorEJ+XHaa9#ovqTN$Y8Y z+3lC^l^Tzo!9%w^AEnDXCG&cpbp39{|06LtS2%Tgx^Pa9#-cs?cy8hN!d&iLPCt}C zd+Pi71%0S6yD(RnnaRxoez)p>O;|IuGqYD8$)9~mAI_c0&*rTsFL~i~zVOt5Di^B6 zrAwE(Pje;c=3aoB2Gj_Au8G|2E7^%x^7DmwJUYGrF;1d{>(Sds#LQ}k2 zz}3LVnYs=ERdumPS>IqFg3Smbu(2_M1fP;RPWx~Xzf=^}r45gcjp@7_c0=44O2v)% zfc!_qFb)p%CX*QJ9f(f$3`BcVC;GaEQvFdKM#PBqa4H3xc??^m<}Lm5)Un~MQ!AUP z@x`O&yeOwW_(Vfx8>I?dD|rA5y!v zOwDQj)l<8-Odb1wQhT;c9sla7LvCM+^3uirNemI1%V+2J=zBp+L#}v|3XkG~^ zmMNnZX{wf~I;JX3u1t*798;_0yb^LbrfV~&+cDjnIX#Z)spM>Qq45kqCw$l;4}h&H zj3#mRVKu<@v-mfl#E+e$SwlZom{~Y=Hpk-#3r75vZ!0@O*b$M-w6d%0$>ip9a~E@`<-WD2dNpg@5Lf%=YBX+{;vg%Q_x+2%TTh+MrkY6V5B3}$t;?_e&EvwrfXF)ssRP(cB=!--=fG?F4SWa4Vrm8F2<>Nt_YEm`BD<#T zA~<8SAEAlxHWPt%WEas!6jyP4DRG~`r^v436N2AiFCO4K>BR#Hl_+Y&jf9x|3`rs| zC?+3Zi0~d3lWTZ^(9&XJ5o1L0C2?#Cc_L9cp$m$0>$*hiy67hGa|GYRF9`h_5%@dy zEaD$T@t@eUgnto&DHhQM$l#2+Q&_n?65l$Ev|;@TliSzuP$a)?WaG-bV6 eY0Dw5B+``SXQh1@z=!XO^3`G01T1P;1pW(kdolU| literal 0 HcmV?d00001 diff --git a/unit-tests/private/LenovoThinkPad-T61p.dmp b/unit-tests/private/LenovoThinkPad-T61p.dmp new file mode 100644 index 0000000000000000000000000000000000000000..5815fc0bbc6cb54939e6e83a138f91032526e472 GIT binary patch literal 2469 zcmbVO%Wo4$82@G;_HGgr=Lv*Bh6ZQ?B;MT+oAiaBiMO$1E8ZkPRYgm@tu35gx^{r{ zkU}Yhhtx9?XRhs^&|@q0(sL_SJ@nQKCoV{JzgasETewm?w%0TB`_1=#Gv8x&y^viO z$2j3GG}?MHtFM3YP^LK4+0-!r!oeT>m3zN+I1&HJbWpvgs(1uQ7YRv z^JbA6Vf7YdW)hLv*~VUFvASDX!rNIrK%NkgASmGjMDY+y+mj{9 z0U*HnM_XN)y4%#6b?kD@aRDUx2qTW2Y$ayP8?JM!ghxm}HaBiEUhms@Y0E4grtQc< zMyt1pD}?e%eIA2G?(^U_vy$b{%QZZU)pF5tn67@t>N?eClT)-d89Knw?y*)hRV(3v zS~W%(WQ6`;D`BM&XHJsjp-w1zN|J{=p)<_7kZ_6-dXKab3L%Z=9oIY2F~&IE z*UHdSsgyc1hg+8e6v#`7$2jc`qub=b8B9qm2m%taRL$0>hJN0`C8CBbL2V0O&n_-kS}AKz?uHgm4mWHrRUscpi@> z3V+wx@%5d!2p53VS*-y9ivTxp4_+{&QL9vloAynLHxT1a{VP{%aJ3MIe*e*F;5knY zin@338|V$;0IP6)422wHN6^A&I|R-(V>Xg#RM!{rVDw~Hmg{tou zy94lkWskVIjhD0-2Gm8nF`@R_gTBk`@?^HN#z8!nGxVi-swpL}pG>V%O)bG<>RR4d zE>LZz1n^*Zt|50%4Era>sxg(a*>$^V*_brn_}>HWSIq5);`=}r(>Xo8psyqn>9me7 z4UYmJfEe`Crie$u4*_CEHp5~7?=>TzrD#VE3ftA1wMmz)s^#9ciU7NTkHE^^Sw-H}AbJ06aUJ zf@a_2u4nzY@~e{Rc;q B1mpk! literal 0 HcmV?d00001 From 38537193a62d45db108527d242988f6dc13793af Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 10 Dec 2009 19:52:35 +0100 Subject: [PATCH 020/146] Removed not needed code and fixed Makefile to run test unit test --- unit-tests/Makefile | 30 +---- unit-tests/POCDemo.py | 12 -- unit-tests/demo.c | 99 ---------------- unit-tests/demo.h | 14 --- unit-tests/dmixml.c | 248 -------------------------------------- unit-tests/dmixml.h | 43 ------- unit-tests/libxml_wrap.h | 249 --------------------------------------- 7 files changed, 1 insertion(+), 694 deletions(-) delete mode 100644 unit-tests/POCDemo.py delete mode 100644 unit-tests/demo.c delete mode 100644 unit-tests/demo.h delete mode 100644 unit-tests/dmixml.c delete mode 100644 unit-tests/dmixml.h delete mode 100644 unit-tests/libxml_wrap.h diff --git a/unit-tests/Makefile b/unit-tests/Makefile index 01706a3..be2fcf9 100644 --- a/unit-tests/Makefile +++ b/unit-tests/Makefile @@ -1,33 +1,5 @@ -## 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 + python unit clean : rm -f *.{py[oc],o,so} *~ diff --git a/unit-tests/POCDemo.py b/unit-tests/POCDemo.py deleted file mode 100644 index 475a62b..0000000 --- a/unit-tests/POCDemo.py +++ /dev/null @@ -1,12 +0,0 @@ -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 deleted file mode 100644 index 265f3cb..0000000 --- a/unit-tests/demo.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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 deleted file mode 100644 index 21a5468..0000000 --- a/unit-tests/demo.h +++ /dev/null @@ -1,14 +0,0 @@ -#include -#include -#include -#include - -#include -#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 deleted file mode 100644 index dbca0c3..0000000 --- a/unit-tests/dmixml.c +++ /dev/null @@ -1,248 +0,0 @@ -/* Simplified XML API for dmidecode - * - * Copyright 2009 David Sommerseth - * - * 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 -#include -#include - -#include -#include -#include - -// 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 = ""; -// dmixml_AddAttribute(xmldata_n, "value", "1234"); -// gives: xmldata_n = "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 deleted file mode 100644 index b1d86c6..0000000 --- a/unit-tests/dmixml.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Simplified XML API for dmidecode - * - * Copyright 2009 David Sommerseth - * - * 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 -#include -#include - -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 deleted file mode 100644 index eaa5e96..0000000 --- a/unit-tests/libxml_wrap.h +++ /dev/null @@ -1,249 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef LIBXML_SCHEMAS_ENABLED -#include -#include -#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); From fc09629c0c19c7efdc5ef8781a775293b4ae9416 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 10 Dec 2009 19:57:14 +0100 Subject: [PATCH 021/146] Package the unit-tests and run the unit test after compilation --- Makefile | 2 +- contrib/python-dmidecode.spec | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 98e6df7..6793970 100644 --- a/Makefile +++ b/Makefile @@ -44,7 +44,7 @@ clean: tarball: rm -rf $(PACKAGE)-$(VERSION) mkdir $(PACKAGE)-$(VERSION) - cp -r contrib doc examples Makefile man README src dmidecode.py $(PACKAGE)-$(VERSION) + cp -r contrib doc examples Makefile man README src dmidecode.py unit-tests/ $(PACKAGE)-$(VERSION) tar -czvf $(PACKAGE)-$(VERSION).tar.gz $(PACKAGE)-$(VERSION) rpm-prep: diff --git a/contrib/python-dmidecode.spec b/contrib/python-dmidecode.spec index be0cd53..0c7cba6 100644 --- a/contrib/python-dmidecode.spec +++ b/contrib/python-dmidecode.spec @@ -25,6 +25,9 @@ as python data structures or as XML data using libxml2. %build make build +cd unit-tests +make +cd .. %install rm -rf $RPM_BUILD_ROOT From de2fa9f2628c95470a98703a7679e48447ca0e8a Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 10 Dec 2009 20:11:54 +0100 Subject: [PATCH 022/146] Make the unit test run without installing python-dmidecode Load the newly compiled module from the python build dir and use the local pymap.xml file. --- unit-tests/unit | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/unit-tests/unit b/unit-tests/unit index 1dd9c61..dbb1e2e 100755 --- a/unit-tests/unit +++ b/unit-tests/unit @@ -5,6 +5,11 @@ from pprint import pprint import os, sys, random, tempfile, time import commands +# Setup temporary sys.path() with our build dir +(sysname, nodename, release, version, machine) = os.uname() +pyver = sys.version[:3] +sys.path.insert(0,'../build/lib.%s-%s-%s' % (sysname.lower(), machine, pyver)) + root_user = (os.getuid() == 0 and True or False) DUMPS_D = "private" @@ -130,7 +135,15 @@ try: if root_user: devices.append("/dev/mem") else: - sys.stdout.write(" * %s\n"%red("Running test as normal user, will not try to read /dev/mem\n")) + sys.stdout.write(" * %s\n"%red("Running test as normal user, will not try to read /dev/mem")) + + try: + pymap = '../src/pymap.xml' + sys.stdout.write(" * Loading %s for XML->Python dictonary mapping..." % pymap) + dmidecode.pythonmap(pymap) + passed() + except: + failed() random.shuffle(types) random.shuffle(devices) @@ -181,6 +194,7 @@ try: except LookupError, e: failed(e, 2) + dmixml = dmidecode.dmidecodeXML() try: sys.stdout.write(" * XML: Swapping result type dmidecodeXML::SetResultType('-')..."); From b1293531b4aff02659298138dd5e4321d61d21c0 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 10 Dec 2009 20:14:12 +0100 Subject: [PATCH 023/146] Changed version number to 3.10.8 --- contrib/python-dmidecode.spec | 4 ++-- src/version.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/python-dmidecode.spec b/contrib/python-dmidecode.spec index 0c7cba6..0d8bde2 100644 --- a/contrib/python-dmidecode.spec +++ b/contrib/python-dmidecode.spec @@ -3,8 +3,8 @@ Summary: Python module to access DMI data Name: python-dmidecode -Version: 3.10.7 -Release: 3%{?dist} +Version: 3.10.8 +Release: 1%{?dist} License: GPLv2 Group: System Environment/Libraries URL: http://projects.autonomy.net.au/python-dmidecode/ diff --git a/src/version.h b/src/version.h index 133c4e2..4ea8b89 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define VERSION "3.10.7" +#define VERSION "3.10.8" From 83a56e3ca41c524e036354d48ac3588e7562f0ba Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Sat, 12 Dec 2009 20:16:50 +1100 Subject: [PATCH 024/146] Catch up to the latest --- debian/control | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/debian/control b/debian/control index 2896939..93383b0 100644 --- a/debian/control +++ b/debian/control @@ -4,9 +4,8 @@ Section: python Priority: optional Homepage: http://projects.autonomy.net.au/python-dmidecode Maintainer: Nima Talebi -Build-Depends: debhelper (> 7), python-support (>= 0.5.3), python, - python-all-dev (>= 2.3.5-11), python-all-dbg, libxml2-dev, python-libxml2, - electric-fence (> 2), +Build-Depends: debhelper (>> 7), python-support (>= 0.5.3), python, + python-all-dev (>= 2.3.5-11), python-all-dbg, libxml2-dev, python-libxml2 Standards-Version: 3.8.3 Package: python-dmidecode From 8b1b2266c9eb36ab09bc39522094718e00757502 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Sun, 13 Dec 2009 04:21:35 +1100 Subject: [PATCH 025/146] Cleanup --- debian/changelog | 6 ++++++ doc/AUTHORS | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 4491972..dc103c6 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +python-dmidecode (3.10.7-3) unstable; urgency=low + + * Last of URI fixes (#540389). + + -- Nima Talebi Sun, 13 Dec 2009 04:20:55 +1100 + python-dmidecode (3.10.7-2) unstable; urgency=low * Added libxml2 dependencies (Closes: #548669). diff --git a/doc/AUTHORS b/doc/AUTHORS index b061b5d..6c1d024 100644 --- a/doc/AUTHORS +++ b/doc/AUTHORS @@ -1,4 +1,4 @@ -DEVELOPER AND MAINTAINER OF PYTHON MODULE (http://projects.autonomy.net.au/dmidecode) +DEVELOPER AND MAINTAINER OF PYTHON MODULE (http://projects.autonomy.net.au/python-dmidecode) Nima Talebi David Sommerseth From 08c26fa5a7f24564624ddfefee507cb464aa5f52 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Mon, 28 Sep 2009 18:41:23 +1000 Subject: [PATCH 026/146] Added libxml2 dependencies. --- debian/changelog | 6 ++++++ debian/control | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index e8190d0..4a8a2fe 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +python-dmidecode (3.10.7-2) unstable; urgency=low + + * Added libxml2 dependencies. + + -- Nima Talebi Mon, 28 Sep 2009 18:41:01 +1000 + python-dmidecode (3.10.7-1) unstable; urgency=low * New Upstream release. diff --git a/debian/control b/debian/control index bad8447..2896939 100644 --- a/debian/control +++ b/debian/control @@ -5,7 +5,8 @@ Priority: optional Homepage: http://projects.autonomy.net.au/python-dmidecode Maintainer: Nima Talebi Build-Depends: debhelper (> 7), python-support (>= 0.5.3), python, - python-all-dev (>= 2.3.5-11), python-all-dbg, electric-fence (> 2) + python-all-dev (>= 2.3.5-11), python-all-dbg, libxml2-dev, python-libxml2, + electric-fence (> 2), Standards-Version: 3.8.3 Package: python-dmidecode From adf21b4164619f8d1a3ff1182f1af8a2ffe7c04b Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Mon, 28 Sep 2009 18:59:25 +1000 Subject: [PATCH 027/146] Added note on closing bug --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 4a8a2fe..4491972 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,8 @@ python-dmidecode (3.10.7-2) unstable; urgency=low - * Added libxml2 dependencies. + * Added libxml2 dependencies (Closes: #548669). - -- Nima Talebi Mon, 28 Sep 2009 18:41:01 +1000 + -- Nima Talebi Mon, 28 Sep 2009 18:59:05 +1000 python-dmidecode (3.10.7-1) unstable; urgency=low From e4e5265ae856d22f4ac9fd2e07edc24a7798ebec Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Sat, 12 Dec 2009 20:16:50 +1100 Subject: [PATCH 028/146] Catch up to the latest --- debian/control | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/debian/control b/debian/control index 2896939..93383b0 100644 --- a/debian/control +++ b/debian/control @@ -4,9 +4,8 @@ Section: python Priority: optional Homepage: http://projects.autonomy.net.au/python-dmidecode Maintainer: Nima Talebi -Build-Depends: debhelper (> 7), python-support (>= 0.5.3), python, - python-all-dev (>= 2.3.5-11), python-all-dbg, libxml2-dev, python-libxml2, - electric-fence (> 2), +Build-Depends: debhelper (>> 7), python-support (>= 0.5.3), python, + python-all-dev (>= 2.3.5-11), python-all-dbg, libxml2-dev, python-libxml2 Standards-Version: 3.8.3 Package: python-dmidecode From 041472537108bad870f943e5f0c9170115f5cedb Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Sun, 13 Dec 2009 04:21:35 +1100 Subject: [PATCH 029/146] Cleanup --- debian/changelog | 6 ++++++ doc/AUTHORS | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 4491972..dc103c6 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +python-dmidecode (3.10.7-3) unstable; urgency=low + + * Last of URI fixes (#540389). + + -- Nima Talebi Sun, 13 Dec 2009 04:20:55 +1100 + python-dmidecode (3.10.7-2) unstable; urgency=low * Added libxml2 dependencies (Closes: #548669). diff --git a/doc/AUTHORS b/doc/AUTHORS index b061b5d..6c1d024 100644 --- a/doc/AUTHORS +++ b/doc/AUTHORS @@ -1,4 +1,4 @@ -DEVELOPER AND MAINTAINER OF PYTHON MODULE (http://projects.autonomy.net.au/dmidecode) +DEVELOPER AND MAINTAINER OF PYTHON MODULE (http://projects.autonomy.net.au/python-dmidecode) Nima Talebi David Sommerseth From fdd96b62bfe927d8ec3824f9ac8e7d5e04a8b17b Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Mon, 14 Dec 2009 17:22:59 +1100 Subject: [PATCH 030/146] New release for Debian prepared --- debian/changelog | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/debian/changelog b/debian/changelog index dc103c6..439175d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,13 @@ +python-dmidecode (3.10.8-1) unstable; urgency=low + + * New Upstream release. + * Packaged unit-test to tarball. + * Rewritten unit-test to be able to run as non-root user, where it will not + try to read /dev/mem. + * Added two dmidump data files to the unit-test. + + -- Nima Talebi Mon, 14 Dec 2009 17:11:53 +1100 + python-dmidecode (3.10.7-3) unstable; urgency=low * Last of URI fixes (#540389). From fd80be196a132bd67782bfde4deba910d578b4b7 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Mon, 14 Dec 2009 17:35:46 +1100 Subject: [PATCH 031/146] Adding the other memory dumps too --- unit-tests/private/IBM-x3950-M2.0.dmidump | Bin 0 -> 5103 bytes unit-tests/private/IBM-x3950-M2.1.dmidump | Bin 0 -> 5103 bytes .../private/Parallels-Virtual-Platform.0.dmidump | Bin 0 -> 809 bytes unit-tests/private/PowerEdge-1800.0.dmidump | Bin 0 -> 3075 bytes unit-tests/private/ProLiant-BL460c-G1.0.dmidump | Bin 0 -> 2226 bytes unit-tests/private/ProLiant-DL385-G1.0.dmidump | Bin 0 -> 1673 bytes unit-tests/private/ProLiant-DL385-G1.1.dmidump | Bin 0 -> 1650 bytes unit-tests/private/ProLiant-DL385-G1.2.dmidump | Bin 0 -> 1673 bytes unit-tests/private/ProLiant-DL385-G2.0.dmidump | Bin 0 -> 1641 bytes unit-tests/private/ProLiant-DL580-G5.0.dmidump | Bin 0 -> 4625 bytes unit-tests/private/ProLiant-DL585-G1.0.dmidump | Bin 0 -> 3973 bytes unit-tests/private/ProLiant-DL585-G1.1.dmidump | Bin 0 -> 3973 bytes unit-tests/private/ProLiant-DL585-G1.2.dmidump | Bin 0 -> 3973 bytes unit-tests/private/ProLiant-DL585-G2.0.dmidump | Bin 0 -> 3669 bytes unit-tests/private/ProLiant-DL585-G2.1.dmidump | Bin 0 -> 4098 bytes .../private/VMware-Virtual-Platform.0.dmidump | Bin 0 -> 1745 bytes unit-tests/private/kvm-QEMU.0.dmidump | Bin 0 -> 266 bytes 17 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 unit-tests/private/IBM-x3950-M2.0.dmidump create mode 100644 unit-tests/private/IBM-x3950-M2.1.dmidump create mode 100644 unit-tests/private/Parallels-Virtual-Platform.0.dmidump create mode 100644 unit-tests/private/PowerEdge-1800.0.dmidump create mode 100644 unit-tests/private/ProLiant-BL460c-G1.0.dmidump create mode 100644 unit-tests/private/ProLiant-DL385-G1.0.dmidump create mode 100644 unit-tests/private/ProLiant-DL385-G1.1.dmidump create mode 100644 unit-tests/private/ProLiant-DL385-G1.2.dmidump create mode 100644 unit-tests/private/ProLiant-DL385-G2.0.dmidump create mode 100644 unit-tests/private/ProLiant-DL580-G5.0.dmidump create mode 100644 unit-tests/private/ProLiant-DL585-G1.0.dmidump create mode 100644 unit-tests/private/ProLiant-DL585-G1.1.dmidump create mode 100644 unit-tests/private/ProLiant-DL585-G1.2.dmidump create mode 100644 unit-tests/private/ProLiant-DL585-G2.0.dmidump create mode 100644 unit-tests/private/ProLiant-DL585-G2.1.dmidump create mode 100644 unit-tests/private/VMware-Virtual-Platform.0.dmidump create mode 100644 unit-tests/private/kvm-QEMU.0.dmidump diff --git a/unit-tests/private/IBM-x3950-M2.0.dmidump b/unit-tests/private/IBM-x3950-M2.0.dmidump new file mode 100644 index 0000000000000000000000000000000000000000..5421caacdf0f7659cbc7d8415072a6c8ae2fa561 GIT binary patch literal 5103 zcmc&&TW=f36+S~!BDbHvDdH(m6f$CpyQC;lc``{!4i&Q|L^)^>6v~P_6t^OG z>D{F$B}$}R96L8VdFx}5#1H)e?GMQP?lwOpXdn6%AncjlB{?f`5x#W+iQ1X(a^{@5 ziQCok_SD5l>?Q&C*!CXW|d0#uQqy%o?+8)1pPy(!9pYv|u`p z*`n)~X*fKXs29vR3?_cz6ZjN9gU{g$_!7Q?ui+c`79PN3rq-MRH6|$V;O|(`QA~h87Twi=r=+SIDd6 z7I}@_CU?l|qeU}kMKe}VG$D$9k+;cRa*w=2-W@Hvcvf`LX$X-9sUwz1CnHwLTWAG#2XG7^v9%dqARp zkNkkkoj=igx8SempOx}4ZwX;j3?DZmRH4Pn4Vrs%14oGm1HMzHM3#&0pfUPk$0uaB-h;+(R=r zss%5e&xh}B9A6CIUH>ond;B*~=^8V+&sRWt0KHY+-eZo#QpMHH>t){YwbwD2?$vyi zR*TgV@B7BD9uA0y=cR5V5)M*IVySW2!Pv@JXYXtinL*2rO(IV={7 zgu~E9nofFZ(Que+y5PZL;jl%nmhwy|!eLnslRdRbh($w&u*6}C2aAWpmI04j)|jR)zw|Yv>m->)A`kE{u0GIhP;r?Qhx7vdMlgt?;X4iFAJPo+}y%nc$~Ue z7g(&w{R@ihqY7$muhSkIY_o!iC$ca*(86#mv)N>p>rvRs%6UqC`At0U97e01HnaA1 zexTc~ApJJA+fhiWD@u$Bg68g)$CGWVH_^}?V# zSP97cQ?+G%nLKOD8rljcU)_r%~(f)7Pw26~J&4$Z_d@G#VRoz)x)TvF9qx}n>S zr8-!l;Gn2pr>b!Z0s{;NVKZleC%i@C8_IHWy{Xy_irW$j?J{b2)pkGA6-#fa)}fm@ z-LR>WOyjN2oq>b4bTR{57?Y2k_cL*6mmQx>Na$o zeLGDPQ`<4Leg+Y?FkZU4db3Gue1c$6P_5SRCI(inYq|r(BGhSpFlG#{W21ey!3;0C zwzr@1L^-PEFwIStL82SVQj)HlRt*R1PSWcJ-SDPlMK^eIPWNiMt?uApf%jvgPWLmz z>&9Z3sGnAnv`{YM?%~o-i}S8EpV1c-;2Oa6uiC`_UkEpD{~^pcx=}sC#hlA!SCY6f z&z!$Wq$t1JB!28s{Ft4y$W8KN?+Lhqy%Hgj3n%c)$ZDxv_HVtZf@s@*#lI-KE{g$|!!Sxta0ybL8&YPZ3Bg6IOSbQVr|In6^I;URE0f|M7B6p-SAi&&TCfXi_hMXXDZaw1X^f{R#}T)^d}Fp5~0Am!yDWk!+& z7qKoYeHXmG%+9?MMiJ{0q`W$$#H61IE@EBquIn#L*XC9jM=Z=K&TB&sNK=B3SQ-3! zMD)2G#t}<%igQQgoD+P++9-q7?2hO4FpgN9Q=B)3oEd3a@DZz{4AwJVKW69N4C9F9 zImLNv$cafm7kmQs8LVj6=j|{~pguv)-6030^MX&HK7%#w`rHfS1nLvyyd!dE1fM{C z2CLfjc{hv`sE^3GaNgqINdbOo6S>L1o}yE>+rS&)_YXM{LTT@B=iFDgf*;4RBLw^p D-o81^ literal 0 HcmV?d00001 diff --git a/unit-tests/private/IBM-x3950-M2.1.dmidump b/unit-tests/private/IBM-x3950-M2.1.dmidump new file mode 100644 index 0000000000000000000000000000000000000000..aec4766c62861f222132558e638a5f79536f01b4 GIT binary patch literal 5103 zcmc&&TW=f36+S~!61TEyDNd@ODe3`Q6f$CpTvF5}PbMkJp=#EIC_M zxLGM}j-QXjt`iW?=5ndH`ThNK6yG-Bj{pw?kjNkY7d<@s#}9`b^2jKO9v>I;B}hD# z%dDvBrQEejLY+-z{+57LCYj16)2Y-V(jFm5h3KX4)^6Oc|BL+l9{g6%-gR0m z6)wZ$P=q!3GhBfZybJHa`*0UNf{)=7a3jY==vTaqF<5)H=XtwS(UZi=; zb*&~{wJp=-!9=}a&R{TO=RSqc;B)u_zJ#yfYxoB4!MAW99wiq^g3OX6NfDJ)$&isC zObVt@q{ZY_T5f2jW_N>GXBtMwOqbah%lQ#6mfvG6@wiPK;*vJmB^|Oy_DNr>#G019 zFGi&Xl&-LvOI63^qifO)tHnh}WzlEJbL4>BAkULSaztJjESf$onl|--=$I_}B6*3t zOm31_$gAWQd2O(0=Co+W4vNNQ(bvfv`GC`3UK_HCL)yL)$VMhPzKy zfVlGU>Gm{l|KxOghPQvp+sDtVsic|`KPkH6)^SELm(H{-+oib+9QWDJ;_?FbImbOP zd99N7;`yTgF5>vI|1SK$;_qX>d&1C}#eKd8atv_1Y&bj2by>2oyneOBJHGKcdegm< ztI$fJQsjO2yuOt^e<{d)-*SVvQen2CH4-^IeJcBo%bK)=o82~R;s(bh?sM4q`SnV! zH-6syAKpA5&EK7F7sLDS>2@5ZGVv%OcgLeK0x{wr0EJ>=Wv^x9AwVk)3%5oNyU1a& zSR@>VF3Lp0Q;UYfgz2mYi-p7HxLVRP9SMhJIV|O=jY2FMGK6^!Q$5&NIBWr6d}N1= z;g*NzAltHV^vi~}ZCZ|NR2@3AT*+Oac*jW1X0w#vJD%LgX8n5yZ^O$1=N8sC@E0DZ z0xN)pa%!;)^ig@Oy3=kA4R%=G!V_7V9cW>?w$*4bTX^I*GHQ-eUw$3WJD1T)yT$BX zgCFQQU2EYy6xfw=I)(B0*x;d0SId`k^a*A=25x$(6d&-s7+5)Q9uLA{-Oh|ONPI1m zNtCS)x}ii_bDWNav0vR~wv7vlKGSYuSWu{I=C)yOQ(V}zWjTh+9jzL^8;%d6Tl+2K zGlzqq#WfQM;%!0`50>f<*T6RPmE?J|M&!k}AN z3Es}>ptG9RZg2@d9IeKaCL-*5VsI$IhoUnRJ%$>GZs8bs7+S5ysxAdCsp(C_G#uB~ zT&z%VP}HbV%{&2t9tMMOm^;f8-Xvpd>Ox|*p*eMm+Y$Q*7woSd8L4?f?m#&V{XwWL3AXpSstJb}VftBl6Vt`nL8m;xljKQ@XwC~iJ=_S|k z_EVlHSF>HFi)5K3x~9%2=&EH`aj;^NUNz~OHzmu4$&+)kS2rAO3kM6l9}{)5pP61a z7Q;gQw3?v#QUP}lK|3kVyH36^qsVm$QV#l*m@+E4$aR?y zxZDV%$aM))p6^pY8IxS(x-0}-4#OyNU4oP&nG%;=dTwVyH$aM))UhGpQ6-9E9 z>$22!!RyP^^h;qBxh_G<%Y8~r`IY1%*9Gso{<0J{H^Vq`VNP&f>2p9Cmwe>PsJ-Pc zd|nOX$fY^Kxg~SXNIr6H)ZS_qKCgvwy*yx!+bDie~ATphKyp7HuIHT^~yM=s9^ z&YOKsO!>9s6R1ybMGK$XVVppHf}FSd98k_mK7so5*0k`s6UGVDC&+nQ=1fXHf%^1T zweWc-j1#Dj%sF?~=HE#HerXfA&cB|bHV{6vdCw%CTk;bGqv?iJ^iI;n*0sDX= z@I&Im4c?}jkrO(e=X!G*2N%&BCv?g3BRBM&XcqX6$E)*0v zB8B*+0k@w}fOwCJUeQfunFObHM=#iw^VghGGw{^)7c<|D-SGgusB*e01XqGJHfin! z5jA3vgQDexP#BE5Rt9J(5Lv)2>&1KuWEQkyP)LEA1??EiQiZ6KY^ zrY_Gtb*}hQH^%Z@3xB%a$4+S*iD6Ihd#Up5g F{s0Uxp^^Xq literal 0 HcmV?d00001 diff --git a/unit-tests/private/PowerEdge-1800.0.dmidump b/unit-tests/private/PowerEdge-1800.0.dmidump new file mode 100644 index 0000000000000000000000000000000000000000..c22a86edaf8a335a9f3ebaf4e8b03e86ad8e81a0 GIT binary patch literal 3075 zcmbVOOK%*-7XGTLd!BY?CKDhJAjJ(f2@t1y9-c7>(e~JK40htU#-5ZHi(%ntzb5W2d{%iY{vvb?%tL4p?{i?BclAr>I9z{2sEQ{6r7I3YozM*jNr z*WWpH>hy6{Pue4sU+m`MOL$|le`IL#`|skCZpW|(SK_$x1@6KYMPM7i1b)#Hi&uVp z1K5qU=yzsjWT|rM^qIO-C8K(}QZ3h~E3=T^K(CR9(Q_bU9>^GEg6#mKD0=_E@Nf=E zyK&-w7Y+}acIdA|jaJS&)q$y#jx>vgK{McB&OSlD0FQz*E;QUaiZNR3HciSWhpw*D zp@La3viTm{EaZz_fJi~G4QCqKz7)wV z|Bd%*2(vH`Q|QsL!=*_RL$h^fMmaFoK~3t8_krXVvNRFa!g}D4X*q<`2%~`{{W$%g zX`~6KSr~6JL=bUFT{(u+G~ZiHMfFKdk-~HLN#C7rO##bdN+4VY`6scF7(B zB2gBh@Zr0a$(6Y^sZ6n9Y8$4$VTP2cQ~Hr;SefzN%8V$Jrl7y5G865}jJYP&B-)NB z3x$NnsL1y4;iIPFSd@Jp6B_rqjN&+PaiIyH%PLNguP!u=T1ENh6sJYmR*I+lI%?2p zyY6uzpX&x1*u&~A=z9%2utk@j3M2?qS_wx{-Kc(bFvro>NX7+rjaYHvgxgP%K5YiNGf?tsRbm}tEJQfk`~)ih60kpwv^#b zq(6J)I+C@N(M_bUjBO&_70svPn@C^Twu$tW?VCtnDK|*9B1YQz^nC&8R>>pp4@kF4 z)YGKw2uQa|9=SIl-6~Nxk#b)^x>fQ>gGfsio?4LB?oDI{BqNf0WG*1NQhF2R15zlZ zM-~H8Q%Y~5o`BSqQjsza>CUX6b1OR89di9&Z60OO<*OLJVtNzjNPMvk7w1G+Xo-dn zTx!Fm6*`JS4LWA9{7)>O#w*l!`?~~E3k{8c4)l&CI=efTWR$>)5j+=1#{$|28VPi) z(3aM*!nP9dE~{fj93Y_6ykkZ0L#oM21n5U|+8P zLFeQ2eb@Q8WfL@x5?t78b$%=N5zxPhyQ<~?GdEFTojCO}<`x<=1UQbl-}Ms&cm{Ll ztqB5Xjkz_>KAu}c#5&SsQ3AxQBWpZPfE^hB0XqpIy9ko&7+yxuzjaxukl?3xZAQE@rA}W1ax3LgP6E*68bs33cQW8Y6tKZ|8KEeMUDDx;@Q3IiEG$L zz#b&v+b%7 literal 0 HcmV?d00001 diff --git a/unit-tests/private/ProLiant-BL460c-G1.0.dmidump b/unit-tests/private/ProLiant-BL460c-G1.0.dmidump new file mode 100644 index 0000000000000000000000000000000000000000..76e659d5e8baf262d30c04e84e934daa69c6bee7 GIT binary patch literal 2226 zcma)7OK%%h6#nj=#~s%R@z^FU0;zWqMJ$Liyvlz{2K6<*SwTIw){t%R*(` zbEnq@#@tKz|oH(|+O4Odxpv*9Dx* z8yC~RC8zb2kiroZm4fSPJyq$Vyk4)ZDU}(jRMK#q`vVu#Wa)!qSa?dM9$Kngq!O8w zU=7y56fF9|(1i+H+uGXLl&(~X636jp*+EX~uYgj4-mS;YY2i|3*29VM;gF44w1k`NUhhZc2A~;6vCzdf}8~BmW zl;`KAJFR#Y=e0PWD=MDH`7ZrfsHg8?KYo{fJk;y^JO+3e9|-g33o5=5=c!t>zBcd8 zDBg_oUHXYoFXDWcevwr{`2;?1*ijZME^wc^a z?K}eY5L9t#yOG@JfV9U5G&>+|ERu^3NV{o)G6|{T(SZXDr!mZ=49@qpAa%VYaEUP< zI|rTjN8L$vBznMQ1D6?a#lRIdrXP1!a#5X2G+}6okNXx7f9=Cs`AVOxf z=cJ3uYE166OQA^+4bt$#@6Z0S`YVw z5M1vd7)M_EUF0NcXq>ysmt9XxI0ulaT5PNYt?ZoqVBze zdjP#WxNsCGMR5Cm|2^DyUGO&~eN{B^8BMx#nmSFBW*^P)4;&9nJOEXD*TQZq&BGDw z;q}Mf2-~B6G(o*>GHPp+Q%9RxpqpeFCRwIQtT2fM9%b>Uz4PUErdJ zY-}~!t*u{fxtcz%;d7t_Fpf9kQt#E_Z&o8%vx9n6LsVIe%wilxOC;Cu6u>vROfi)T%IT%cODZjd5nuf z57W)mg4XK(+2@(Mr4&zQJ6B4SI32}A|R&9WRT zxW`Dse`2o*x1aGEyhWuKw0*nAnz@-c* z1@`ejQz!(CrPL4tHUud_0pop;4?)VxKq-bGrDC9zebD+!#Rf`e2s#$bJY52_6DXsTY}e(bQ~rqDHm47%$nd3OsP|fB_F3JY?nQvN6$ejdK0S!6Py_ znsJY)vRF!zqZxVRQU#_Qcv8iaRpO~{@FuMn&*H1J*8A}nyhD516g&D$S)e_@<2)XR z)EmD6QHhTP${Hs=OPI2@iO&=B&e1;bQ6&n6o05v#t!10?W=ygvB-_-o6N)b61fG!WERqG%-w*af`>Vw$Y2t%kMr z{>^qHtbY>Rh&<-@4iC0J-`zhlt?k-+!`uup!OhTEbe?r95K^#l&i@!GarPB(3>=c* zijNiql7GHe_z_snFXx+jQC(I^a{J)^o(a+Hwk+41%5CYgs*bo(%2lOBMFZNv27LZN z2sf27o&BS|!~NX{W;-;SyZ1iZ15~Lzl^jhcUsm*uFoVKirgAh<4j>rNmm7AAohRgyiHRocExY6!^aqq}2^)PKS)<-HqM996_LfoYx#U8U6Hf# zy2YI=E?>*%cS={>+4!o(y$OySS21(`HH)j+_&QKpK#9wMBv}Fqjtvk83ZV6coU`? z2i1sa=2&oK#|p>p#f|tX~{%O3y%jX50DV)Li&N|+iXPt)*9s>UY Dry?f~ literal 0 HcmV?d00001 diff --git a/unit-tests/private/ProLiant-DL385-G1.2.dmidump b/unit-tests/private/ProLiant-DL385-G1.2.dmidump new file mode 100644 index 0000000000000000000000000000000000000000..e8c22bf85a547f58526398effc841c62bf9acbc2 GIT binary patch literal 1673 zcmZ`)-)j?D6#njy`DLxmO+rUu!3)N+4=bI?ueKuC*lca2(O|dFwP?XYX`ytNeOa1? zebIeb{|Lc9L#kGn0Uu`{kCaqx}C=bAP+E(kK$_k{lOoGBiK?4wV;BaG#!M~#UQ8>Ymq^ti=@>*OXK)@JjR4wru5 z+)AW$V|#C7cYA$HFNbvpC+Qn{Ea7lx7tl?TXGhjEc< zV|2`=RJlBqJgD3!yB>2{mS;0JD#0vPSFY*S&h8%N6|Tp-NU@v(MFWT-Knd{1na8rW zkPH&7g@#_)+UZDn<2(WQAV5;yxJUpo2$0m6g)v5jcJJ4_d%97-tdl~#RGJC91%%85 zGD28X!TcnqbAAOd@&j? z8(gNi^u%}jD+ael3Q>N2* zIz6TygEnz?#({$a>O}+HDVUosR!yTS1J5ix^ML0Tp0h&ma~K9Q70UGs3omH*;VJu& zDvQO;*z(Yp)Jr(Yxd6g~I7H(xesJQ)`QUGNZyW`i;_apI&xB90BkC6*#W7F|UljYK7yNFkNj zAY7@tO5JwRWz`=Nz#xsp0tpF;52-(aebr3wo3T9!#Lx2h`kZ^teRJo|+gR&v9G(}l zhkR|cyPb_cI=1G&*KiT20wnNJUhBO*cw}-U-CRX8TtpbngbOoq7&bWNEN4kjJ#5tD zdUJib!FbgA-Y!C&EwFfXZ+GR#&7FPSUYT8()8EF(x#G%Id@fXjkb;*fYl@C+^UTj= zg~1>JY8r~DK1fy=}k={PBwTWQBI<7omHV z-k^qia*epCabdjTXpND=^~j|uF;)34#`@Z_Uftc>=f1%8#OHWya5=!EB7YX}Cdi|| z%SsWrxvkEX>w4|}Zf5082t!FFj#KRBO-QCnQp)30W~g$NI!@J%%E~G0I5h{9EtH9y z^uy0v`?}NqM(6W+WwsFwC!{ioij0hUY2yo!wfJhuU$il^$ zXwjT$^S~1ePY8Hw;VE4TuSZeXn7;u$v+#^9`X%&v-YDgieu?_T^PCFcc^S`Zd>~#0 z6ECLm;w~rK`fI9kEAM5o_DUT8G>E_A7q$lF~<_GFZi3dNZ^|yiAxFj zrbOb3MEI#RkxZnYvP0skMENPtapGEu<)^lZ?8Np{$3#xz_-4FcRq=|qeeTxk-71!| z-_yYBGkATeb$cCG|I2GHnfhkEvGE4%`p(5W^O6AX&*D87?DIXMPY}eBR7gxn+C+*PIEM(RS_zRVq-rk+ zQ}x(WUzZ*$F1=PgQyvC&Bn~J%Bp!l$FRgm2sMvn9>zSPi_N9kzwD#op{lD3nzh^$} ztgSAu{WDH8El94l=JMj&XMg$u{`(WW0WbtWDEwi)+j{)lC84qG2(N_|SeXhTtR1dS zAFfra(~g7h zMy-2Bxpzjrdq$;qMx%SiUYlH@aOHF>nFsALk6Jp9eZ4dEd1x8?duQnL&@v`^XXx|L zGD4etL0T=4^B~=Sk9sf9$H4dcZNO>Eu+ypL!XDra9rY$5-oY}P0qln)!ATW zV{;2P1~@M55~zuQ)g@3D0oEnZ0C-%0$6`;%m%efTYsf7ymt4(TxQ`iGnOi(`JXk%y zu@&I6+(IS^Wz5i|2xXH{)(lOFke!5VGlXT(EuckLbBsA=Xhwuw5we(ThK`6(E(zt# zP*@eQd=ks=h@tEG4CKW^I{WFFtzfbFcJNwd1+NI6Wo6Jz=T+q4mscd78w2_(VlkjQ zfwdDb6ZnJRgZC<0fTMAT1S&1~fi@SHmxJ(_`pp3RL81#SU09nlgftbhVn!F%j~hZO z6++RDg#huR8z&4Q^NAcI6y1(+c4K|>Y!Ds{I)fEs%;>^=S7B{d2(!Ad&{bHU6GB@T z7P|@?O(AsB$>0wY3p+kenm)R^(C~4}^f8wTclbDM`j}6JJA9lmeeCmTFCS}$j|E+5 z`Y45okNvvP^ic{EAB(!s^ic{EAH8%kUXkiP9+@>3g|7>lE)1(psT99VDHXC}))0pC zy0DxIq3FcI&Uy@M3%ao4Td9w^jxbq|b;HM9y0EXSF!6Cf7xs4*CO!`8La(bZ@o^}f z%nl#Jx-wGOGpq|u9~*{`BdKtwkCTRvqp5JGk5h(^V?OKUW5e)qw=Oh&l)}WvJ-X2J zQ3?|u$919UqZA4s%S9+-WrZkupMr;PsO2J2fFyt_Kofv3wVf0z0ZaiVK&1>7slf7E zCL|J&D2Sz2LaHE^RSB&aiY~B(O2`z%aw%a(K`f0DW);LTD50$&mOKfa7>dbbc`Fkd zkJD8UOPPc@1+i>Nm{)ybiIT8SK`ciS78JzNBVoUSSY{+FDu^XTLNA75oLD~O;C%(L zR7hA-5X*vuWz{E^00}D!;&zvCmx8#pB^*!?x3PqS3gVWPa43dioVY#Z;D;5&ttjD$ zg1GG@994bd7L#yHLEKIf?p6@Dj)Z#@#BCzsxPrJP5*Xz1v=Lu;;5bl%10)EdANvv{ zKCjzwoe-*>8u9d4t#uBNH!^U80Nl*LO)^nE9){KFX?&r&m4REB+s=_TVL&33v~#pg z@dYcwP0`L-ZHsvjS)$F_j17T!t9fq2^AG1g0ob<5HepMmLAPnru(qwF!M2%b+|I-8 zK|I2~1K9hWF}U+3J~11Vyua~S_%pWcpkj$5BEa1NxJ$_Vv6G(zyufuWt|H#t0S>+x z9d`&Pz8D*KD5t&{8Fwsh`C?q$VH`JFtjloRU9m39aZANIo8vx;bq;s@2;bYd<8s%J z@af#i@thywk&iohp7$g4nLB+PH$>cDf#WWS`|Ibp^yB`D9M^l?pT|8vaz%#EeLu>H zR*9GVC@)%NUiKsWt+-R+xNzhCc5z&-aeo6GmuTGIAjfqX_cz3c{HP!@hWW4`^^4XB zAMqo!gFB;q)EBRt+!^Dzz~cUPb6iz%e|tDCrMSOwj_U{eyH|mGkcF{Z-?zWU1FQJ{ z7U2F6+@F~H;1oE2C0-vDev9kD7(4*LcX7Bj4lp0H^yA?{co>F2`vWY!c*AMD@tfk! z@Xq4hhqr?_z@scY0(AO`15cjgNCBRnf~OvkHbexMT|`NnMiyyXkwcNW6q#6qQJy06 zEM&fgtYjf8v;T4$K&sC6=&cDj^i?e H%K-lZFqA_F literal 0 HcmV?d00001 diff --git a/unit-tests/private/ProLiant-DL585-G1.0.dmidump b/unit-tests/private/ProLiant-DL585-G1.0.dmidump new file mode 100644 index 0000000000000000000000000000000000000000..8c8d5aef47a3b6f663b62a9db70e18b4a11487eb GIT binary patch literal 3973 zcma)<&2Jk;7{=e3S?`Av#~$19=G&_hDh`$KN74qwp=nK~MTkop(MTXwjTH63 z0aPP#;{rGS8`O`qXrvx0r9IFi7mmGwgjDnFY-hYSYiT#xc=EizeLQ*U_wDZf-p>A; zCKr85j{V-w_Wt}~Il`~M(mOpX!iej@O{h(wzW%}tv0pV?{`}GZk-1*PYjsY z`l9#c?$zt<^OquhxL|jWk8XT(aQ9x+yRp8p9$jtII0e%Zd_&@bt?c>PTgBIY{#%XlkGWG z?~Gx)hNTH?#fuEPmatx};juouNEgY+7ja%lwis>Sy?1zg_ux)+qa9s7`0DFJBCl4@ zgge=AH52Y;!<9^UEgL@Tu^)KUuk10z2_8s-eX); z`ZPJ`?r_g*nQ(f~DY%mfr}vzKTbXcr&ldIr=CdlVR<5mY(9OL|(eBalJ$!h{4|qnQ zLll%)z^X1A zY-L!;0U~P|x@iy}gsi_B*~`$&0pj06hQ4Hza_o%c7~}wTj>R-Mnxl2pIZovOb&k_R z&>zduI_extIY6D`%n+ntG)L>Gb1dfob&eIuC*{~3$x-G2b&l0EIGUq%)H&92fI7$e z5FF3ZI_ex}bAUR>#tHz zg5x<_N1fwx4p8T~G6ctSw2nH*W)2WJ*2+}FV2lq&6(<&$6<8v0EAT`RRuHjJuf=zU zZx2Z|#s;y-tcb~4V_b{eikPB?6jsE5tGZ1MJr-T8FI>sm`H}4HX_6HF=WY#m^6l*F(P5A7_w|dOb|m>tcYo0NNGh( z218b@h$&#mnibLUhO8Trp}P$^YejUjAsa>{bgdynE22XUIcG(5qao+5h|V+Qf)&wa zhFr8FI?9ksMr7z7LoQnponpupBNDp8kWDM10}?WtqR4za>48TN@OYAXU}@voWg~ue zK_@;e(8GY}QGp(@)z-)DcI!fSljw1Q9>d|J=$^O^u>p_Q&WYpT@q)!`e!?Ax1|nY5 z2{|qe&=^mO^dv-MeS~YDzDG|#z$+d%_!eG2e7nAeSG)uCclj>7h?Gx?B<@tOVv0#T zOJT(omkj>O7fMJ5cjY_Ekqq}o$}gybWNy52l`EMSuRP^RhTA6P`^uM?XIKR)kX-u} zRZ(*7H>IW|*M8G#T5|1IQYFc?-;A1(T>F((S#s@HQ5A{16!=LcrO-A?aCzo-uZ1^RsV>{>0G1(Z@yfyiU(soEq!jeco*+ zuNeEMb9B0T`O}+3e<$q4_=5O2onxn~ds|oN_kYGJFP7*95#}-d)+D;3>EVx;=jdg- lO?)Q8G{s4`aN?EYba1*jr*Zl?iC+2iD&8H@eTVK7{RfPAnZ^JB literal 0 HcmV?d00001 diff --git a/unit-tests/private/ProLiant-DL585-G1.1.dmidump b/unit-tests/private/ProLiant-DL585-G1.1.dmidump new file mode 100644 index 0000000000000000000000000000000000000000..2a0c915e0d1371190d3bf40acfd2b8861b77813d GIT binary patch literal 3973 zcma)<&rcgi6vyAptasN2V~=gT{PvbOIBjY1+CXU40|bXa3YAqFDK~-&QY%FuAr8G% zai!jRX>R>*Do9AGm2!wga&V5l^vJELBH_N7WyWi=v^!|MkMH};m$%P5!|vAR#@2a> zvK9nmtFf`RHN2Z~@z>wr8bASnP&i|yR{Q8j!7#Gggr%wn)rFbb{7kJ{okL_82x4sY zeq*C~=Sy$?mMe#eZ1Z4${rl~`L$|R$w=n14@!&FrrfKwbfHH~$=e$P*c2|D_7_MOu z_A||8D0JTa;=tp-*jeg9vSAdhDXY`@YJX?f^xzXd*sSF$b~a$Ge96o>z=#3{q1+V z09L*b3D=_GoJD{wVvRk{^=LR73C~8uQx^G&x~*)h$JqNug?0tnIP?EUyF%iEG%m>Ef!r}TWY0URxcu>3Wdw39_?6t+-#*xJy=k|xwz1)g zos~O@7$EkVJ7yTf8zIUOd(Ry!28iE9yJE+?n06%@7fi(k`{IGz>F4CCKGu5rn2rI; zJ`RMz-acwa*~d%_Q1&q!?_$~&9v95T1@rMh?i4sxeT0kq5g@o9>pguOi~-6%7Qqx0aL5zV5hBqd5h9f$)gtYZOpB~b8cHO% zJ1WnF7I7z3o~9OY*HfgWMcm;OX)6(IP86BcVp51fohdD*x@4ag`?_Sm5((};$}_D+ z+-a2OfEICAQDjDoxPvG%t3=3hsz|OyF2tbDoECFkGOxvamn>)zSGV#U)FQ5Aaiu8F2`%EPP-IDq zxB>#w?E_cco^WKr5x$;;URbL28Be~u%mN%I;5Z5JBmqxIxq934syFLP08bO}6dg`d z=80(l=}-|HCx(Hq7evJLgyKTzFcHHEKF2@@k7p@(=HLs_7dZF%4S4<;p7C{quHyOg zi})^{@h_l$oi@=6|JB+bT75yS-($Dc7&ZOTbdhVw>n$b~J`;GZy+>n0b{x~KZ>Zvjq+;IzE_^*w;U19nkN5aV=+ zoR&9NSKyDgmol%$;1vMw$MAazU`5j1kJr=i+Vg-8xVW3*0T1xNGsVNe!^EQ>4;v4F PH#WQx)d4&*;1R&Tje{s0 literal 0 HcmV?d00001 diff --git a/unit-tests/private/ProLiant-DL585-G1.2.dmidump b/unit-tests/private/ProLiant-DL585-G1.2.dmidump new file mode 100644 index 0000000000000000000000000000000000000000..ca5892c203bfe3f16fa4ceb94488bec23964ec62 GIT binary patch literal 3973 zcma)<&2Jk;7{=e3S?{i$IQH0%H{V{BP;sb)Kaw^e4oz!HQW_KyiV&AHqLDzV8Y$|5 z1E@yg#szNtH>4kF(MUa1N_(J3E*yIU3907US%?fv<~Qiy;4N^cR>h#05WqS5=~!S@j(*w!v>He1wez1wc$yLl1FJTYKm z>x=G}yB~erx_BkjhYNQ1_~^zr2Y2s<-5cv0>)}T&8mC}dgl|Axa2&Yie?)9I`6rPR zIt~**@=A$Q|KFbi`sFY2x^OGsb?V-EuiyXV==NdQqRpLd#JZ{Mrc?7)4cj&>Pi4DK z#XD!%j$vs6TlPZ3uEnfZt$VD;F4JZ5@kN~H;w^^Tckdk@-#xe!-e`qa55D^PkjSgn zQsH(wTuFsH>2Ns}UQ371d+Y}u_R779du|W+yqXFp_nd&wrNYTQC*Uv@PVPAYU-TFk z@`ig@_8m5y?U)vU1{rlPs)7gdQb1&T%FQj^=0`b&jPBpw6)@`J@~>BRR?ppw6+91V?kUjylI`22kf% z8-n9GT1TDZYz9#0SWkkZIa)`ZV~_#VInGHjDaW;u9OpBDI>&`1IGUq%)HyC@0CkQ_ zLvTDt>!@>F&H(BhSCZgpj@D7<*vJ4P$7+eH7>qbh7?qt!U{+wUz^%YzL0CaVLaiFz z84eCfRmS>}$gGITT4h{|+=`f@h7?xB#5ANc5KkDUqakxv#3VGNYeh^wLwZ)kgfpZ+ z5b?)TGDGIAh{*Oe8~255yCO>0`*E6)|ZHIb%gk6+@P+hzVlI@<7C& zJjo3yt%%8B$chy)1q@lWB0AoXwSjoT(A|cdwIVv%kaa7fYYiD#5glsCxq(Q8ZZzb) z714QyT(Ba#%#e##L`NBNX&|03bdMpIt%y!Bk#YnXziRj4jwO9 zwC1PWai}k%HJy^_=YoESDPv65U9yjDkqs6tz6|w=0z({d6MC_N%_9= zCFU7cd6k!3`xR6{a_u*zrX<&X(`s6B?N?Mq$+h2%nvq=ll~hS`?N?T1iMtf|NhPJw zeic=bLi<%!RSNA_Q#BdgzbSuK%}SyD>Z&e<_6t-Xh4!0Ma}u)*+`O8X2ohz4UYnz{aOY|p(4vro!qUSYw z-sDtY|L*fnD}Ke;Kbxbo)vKT0B>FpMFGm+d$Jrb^Tix5bM!)|vR(Y{RFNiRY>9+>a uHBAqHyu3g!TP@-sU^lyVVO_UrH?5j+0SX)240GCR|A)gRy^O(2H9*(1(sfVeMdlLf^-F_I;AABX`y@v3~hozH`yhvG#Vi_ue+S zaRf=*Ti@Q?+wN8Z{P#yV0Z<2E9Nrio9R2y=9(fG5u>)(Z9<-vRsJ9fg5CWS)mjSF3 zwpZJ&-OC%jaJ6&w%6dV=AZ~!+orC?Y&#&J(4A!^0E8XC71c|1@>Ywi$@B_e`;+x`{>Dhs;6c)z%CJpIE5W?E_I%U|{%(^M; zWAA37VTR{qYWDGWGwor<$jSKjiFY%dBxC!Y&5qbPI0p`Xz%or5`pvs{_YZ`0Xpc|$`H9Z>L}0UTd2r+%CG)VH@$-oEJdWij zvh&C!j^`(`^T;GlbraU+4_@-ae0f-y#D1Gr`8 zvRVQ61mJ$Wu!&oG_x65V%q{ao;-eClbIXRyekQKr;sbnx~ zRO*scNK%DSX_+KDN!g>N~}9tcU&tw z{?&_=cXRcy6&s3KLm^ur3@=fIQobRI4HMb`uAQAi*uG2^%K3&)Y^Y=n&Pavs234r$ z85KDoo}Z zqS!E{4d6~>*CA?eQH4gnp%WXXwZXwNB(n}tcbh8Al%#Ze^rG??b9Emv2~! z4f9z;b)>@TM^s@U*U)aohDB`v*UPR$JKUiP&3r?I2EPhEK1QI_&v;arL@*?NL88e9 z1VFPNkYwX>3v74591WK}yoB$E~Q1Rsu5q@+M{FwR;^*0j@4NnbnbDOuOf$&{Sb&M735 zHl>}7lx%3{G?K|im=?xxoHHpogXCbGvne^NopUKUr=9aDIj@}yDY>AXi%2GIQ9GL{ z*&I595(J6Q060~HQ!EJ7uM>kTULM%+fHB?*ms%^yi+O8xDQpwOpYMkjJjA{G$bv`g zWb0xWwtCC>)BV_j$C&LGp^rb%OrfP;WPN6GP@FLDa}(d5vCn?d=o@AM6h2>1O7NtC zFaBo%15Z!G(@(KTA$X6~QM?u7z%3&FVu0rm13a68XN+B1`{XNtzv=ZGTLu550}=#v zE*&PBpsuCEB^T7ObPQ<->Q*|YG=;JVS<(`!K&T)KLfM3DX$yrf#?o=5Ba}C_zX_Aykb}P1c0M zLqs~h^o7D(CY`#h3pGh-QcemrMQBP+35BaAorY`(HBD$*P75_dXhzNmHA`q#&I&b0 zXim-vHBV?>&I`3bXhALrwMb}DE(+Bo)Rav@??un+@Z4F0*{i?*@wJy+zX5nL4KGe! z`1l%}{Wn?bbGX!Tds%>&fUEe*fme9J_WBIG#)a$SJ%v64&JY>655VMzERLvPAhHca V0DsltuR(|R1|8l9xNib}{|8%@kJ3`^JE=uS?9s+?tE)e<)@?MhZIlI#CD$za!I>yqc?{aizG&|C6 zZ*6S9sB1hoD1%3edEB8Fx zF^ZOp6UD+<-=LPxxgK;jRw%ySg?Rz!j4>DRxrey7ZHPakq^puQa9e6d<3Nw~d zv{;vQp$i=Uz%&eM{lb+iJG-vuu3g@{uzUIJC3oF(m(QNNcmcq2M0&y>ohYRznxhj= zdZINt;aco#&F#9~a2_TfJr6&g$G-GLavq7q{`5q09*M+(^h9zVQR0!)vS@cE#)y3w zQvi<~|BVyPH%`21SKMZtm9$dv^!y^6**flS?(FX21p(aFMhHF$`Us&(f-yp9kzkGx z<^k+Hvso#FR|DXcxV(nTwRLGHczZjqg_1TbVFPwvx7nXro#~-;_(Yh(7VNwcO2)8+ zP1t!8rJT;pVJT=M6Q(l5(gLNdFl7x(ZIW>9s30Gf@W8b5HWf6OJuEE& zKey+ut-RyDc3?uW07YFlac31@Di@zb1q9($I7W-f7&u+{MO#_h*l@iL=`2HHlDkpVx{VffzD$c zH&e3zr4y95Q+2Nq7_v!2CRxDqPEv(jy1@?&W3d5jD>((Pd5S9J(+#b_FrGB zRH2Y=SO^To*uZgzCAUF)jVg$A!(w14B@Nl33QMP{f|F|S8-bx58^F#bXW@JAQH6)_9CP=%>zxD>S`Ls!&fi_-Jqn;NWEhO8tgMg+T;E;&&wKtWRi2 zxC|WwLMI0jbuDm|9VkaN1UL*27brU{BJpH#G&~WI)FKj(lYvu@NIXLZP9q?xE*=~M zrx}rWS`3_-h{Pje;ItwV&xL`LBNjzm5Rrx0Swu2i@uJWMeTs+_NcQ_IMPw;lMy)? zJ1Y@ciJes>!;MfC`k>FLh@3*Q-{*8hPRGt#MAl;G43goPiJh|%IU76YB62Qv)+4e$ zaJo5g2Q}eP2@WyWRey{{6x^`j24h;o@87NjcP?I&?p*Ne`=$vuaqr$T;TAjCIN^DX z_5yx&-!|bkmgr@nhhNZ4p{18)J!WX2@SdZW)q0wN_YFE>y{8))PgA->kfF5+(j+%Wbd{sbGyxNosC7QPr@*UlpT ztdDDm0q#x0J;qLUKKc^i8Qrwt7{`CfL4u&hC1;WeYFlzmYJ!@UT$j3_mL)f&A(TnT zl%`M_LK&G63V&KkZb?fhyq%DoOD>d6$dT~oVs$TR3Dzz$|vujgGQbif*z?u2Zd}ns%%yin#j+B#gHUjDF zH0zz-(=a1-OPDf%B>(ukf*(3U1-_M9r!IE}U$TAPJ$2lndoti7_F#Vp)*VfQrWZ`D zU})Mld0v&sTTxpUe*5Xh=kI^_>(j6Q{-rSuA2z?RJ${?jo$eh33OgKlepw@Ml_Ev9LVmsq9Gj3O&r%(S<*i>#-!W1W?ItlwqFWmdFVzYoX}*}uB( zjQNn&T<@{#+2euhpjgyCJYqY1^l0opW_!HPJ??b*Gxz$JLrE!+#1|+e#Z^#DY}e@y z-ODd@}FT~`qv*xMFtKc2a&3pz!glVl*C%=fQ{Vl zBXY@WxW}Ezz~O$VXmMven4I0*yTw|bE7(HBCKE>>g3T9o>I?1X*>q@gvY^b_XIsG^ zeieRWfpS5akyW}BRh1A%t5(0DqgV)93m|zBqNGI=*#J@&Axc^_aW#O{MW_fYN8W%UEy)+N zp?!F-%IbCOwso^i_r*f%kUwp4wEkvtO#%y!;tH;lr+b#@X0q<5NBxJx!_?H6oDQc#|p#TB>aM-A2Pqkt3=^ zg(Y)x12hmomHuZ+FAb^nO>9tWGcZvPF?lHEzW6UsQ7&;U_wF;nh(k{< QPSXE3>U*S|tGDU*Usq~Up8x;= literal 0 HcmV?d00001 diff --git a/unit-tests/private/kvm-QEMU.0.dmidump b/unit-tests/private/kvm-QEMU.0.dmidump new file mode 100644 index 0000000000000000000000000000000000000000..244a3c5eb58d254bacd2799c4a71afe9d073ade8 GIT binary patch literal 266 zcmZvWy$-@46h=P^*1w@`sELV#B)T|BU0gNRp#zCVJM$=Y_eG7bU=%N?o%~?A=bn4P zo{T+DBeB3IwltO1cPJ_cm;+;gG29~bz6RBB?zlHKbg`tn(t1sBLi|r+&v*_V+MM&K zm4sq~afTT=&&RdV!Z literal 0 HcmV?d00001 From 555dc447122b130fed66b194bf307a6862fa903c Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Mon, 14 Dec 2009 18:10:49 +1100 Subject: [PATCH 032/146] Spelling fixes Thanks Lintian! You're a champ! --- src/dmidecode.c | 2 +- src/xmlpythonizer.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index aa2332d..704294b 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -2686,7 +2686,7 @@ void dmi_memory_device_speed(xmlNode *node, u16 code) dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code == 0) { - dmixml_AddAttribute(data_n, "unkown", "1"); + dmixml_AddAttribute(data_n, "unknown", "1"); } else { dmixml_AddAttribute(data_n, "speed_ns", "%.1f", (float) 1000 / code); dmixml_AddAttribute(data_n, "unit", "MHz"); diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index ba018eb..c4c6cb7 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -572,7 +572,7 @@ ptzMAP *dmiMAP_ParseMappingXML_GroupName(xmlDoc *xmlmap, const char *mapname) { // 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"); + PyReturnError(PyExc_RuntimeError, "No valid mapping XML received"); } // Find the section From 2cf5a5499261f2da0e409565f55e400312d2e4a5 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Mon, 14 Dec 2009 19:18:54 +1100 Subject: [PATCH 033/146] Any Python version should do --- examples/dmidump.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/dmidump.py b/examples/dmidump.py index a6c7bf7..ed9908f 100755 --- a/examples/dmidump.py +++ b/examples/dmidump.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2.4 +#!/usr/bin/env python import dmidecode import sys from pprint import pprint From 025732cb750156235d0047fe9d43413497e22a20 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Mon, 14 Dec 2009 19:24:10 +1100 Subject: [PATCH 034/146] Now takes flags for color and verbosity Default is no color, and no verbosity, exiting with a 0 on no failures, and 1 otherwise. --- unit-tests/unit | 533 +++++++++++++++++++++++++++--------------------- 1 file changed, 303 insertions(+), 230 deletions(-) diff --git a/unit-tests/unit b/unit-tests/unit index dbb1e2e..fc9c3dc 100755 --- a/unit-tests/unit +++ b/unit-tests/unit @@ -4,6 +4,7 @@ from pprint import pprint import os, sys, random, tempfile, time import commands +from getopt import getopt # Setup temporary sys.path() with our build dir (sysname, nodename, release, version, machine) = os.uname() @@ -12,265 +13,337 @@ sys.path.insert(0,'../build/lib.%s-%s-%s' % (sysname.lower(), machine, pyver)) root_user = (os.getuid() == 0 and True or False) +ERROR = False +HELP = False +VERBOSITY = 0 +COLOR = False 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)) +try: + opts, args = getopt( + sys.argv[1:], + "hcv", + ["help", "color", "verbose"] + ) + for o, a in opts: + if o in ("-v", "--verbose"): + VERBOSITY += 1 + elif o in ("-c", "--color"): + COLOR = True + elif o in ("-h", "--help"): + HELP = True +except getopt.GetoptError, err: + # print help information and exit: + HELP = True + ERROR = True + +if HELP: + sys.stdout.write(""" +Usage: %s [] + + OPTIONS + + [-h|--help] #. Take a wild guess. + [-c|--color] #. Add pretty ANSI colors. + [-v|--verbose] #. The more you add, the louder it gets. + + NOTES + + Due to developer laziness, a single verbosity flag does nothing, so if + you actually want to get some verbosity, add two verbosity flags (-vv) + +""" % os.path.basename(sys.argv[0])) + sys.exit(ERROR and 1 or 0) + +def ascii(s, i): + return (COLOR and "\033[%d;1m%s\033[0m" or "%d%s") % (30+i, str(s)) +def black(s): + return (COLOR and "\033[30;1m%s\033[0m" or "%s")%(str(s)) +def red(s): + return (COLOR and "\033[31;1m%s\033[0m" or "%s")%(str(s)) +def green(s): + return (COLOR and "\033[32;1m%s\033[0m" or "%s")%(str(s)) +def yellow(s): + return (COLOR and "\033[33;1m%s\033[0m" or "%s")%(str(s)) +def blue(s): + return (COLOR and "\033[34;1m%s\033[0m" or "%s")%(str(s)) +def magenta(s): + return (COLOR and "\033[35;1m%s\033[0m" or "%s")%(str(s)) +def cyan(s): + return (COLOR and "\033[36;1m%s\033[0m" or "%s")%(str(s)) +def white(s): + return (COLOR and "\033[37;1m%s\033[0m" or "%s")%(str(s)) DISPATCH = { - 1 : red, - 2 : green, - 3 : yellow, - 4 : blue, - 5 : magenta, - 6 : cyan, - 7 : white, + 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, + "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)) + global score + score["total"] += 1 + score["passed"] += 1 + vwrite("%s\n"%green("PASS"), 1) + if msg: vwrite("%s %s %s\n"%(" "*indent, green("P"), msg), 1) + 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)) + global score + score["total"] += 1 + score["skipped"] += 1 + vwrite("%s\n"%yellow("SKIP"), 1) + if msg: vwrite("%s %s %s\n"%(" "*indent, yellow("S"), msg), 1) + 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)) + global score + score["total"] += 1 + score["failed"] += 1 + vwrite("%s\n"%red("FAIL"), 1) + if msg: vwrite("%s %s %s\n"%(" "*indent, red("F"), msg), 1) + 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 command line version of dmidecode ...") + if r: + passed(msg, indent) + return True + else: + failed(msg, indent) + return False + +def vwrite(msg, vLevel=0): + if vLevel < VERBOSITY: + sys.stdout.write(msg) + sys.stdout.flush() + +################################################################################ + +#. Let's ignore warnings from the module for the test units... +err = open('/dev/null', 'a+', 0) +os.dup2(err.fileno(), sys.stderr.fileno()) + +vwrite(LINE, 1) +vwrite(" * Testing for command line version of dmidecode ...", 1) dmidecode_bin = True in [os.path.exists(os.path.join(_, "dmidecode")) for _ in os.getenv("PATH").split(':')] test(dmidecode_bin) if root_user: - sys.stdout.write(" * Running test as root user, all tests will be executed\n") + vwrite(" * Running test as root user, all tests will be executed\n", 1) else: - sys.stdout.write(" * %s\n"%red("Running test as normal user, some tests will be skipped")) + vwrite(" * %s\n"%red("Running test as normal user, some tests will be skipped"), 1) -sys.stdout.write(" * Creation of temporary files...") +vwrite(" * Creation of temporary files...", 1) try: - FH, DUMP = tempfile.mkstemp() - os.unlink(DUMP) - os.close(FH) - passed() + FH, DUMP = tempfile.mkstemp() + os.unlink(DUMP) + os.close(FH) + passed() except: - failed() + failed() -sys.stdout.write(LINE) +vwrite(LINE, 1) try: - sys.stdout.write(" * Importing module...") - sys.stdout.flush() - import libxml2 - import dmidecode - if not root_user: - sys.stdout.write("\n%s"%cyan("Not running as root, warning above is expected...")) - 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) - - if root_user: - 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) - else: - sys.stdout.write(" * %s" %red("Skip testing API function, missing root privileges: dmidecode.dump()\n")) - - 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)) - - if root_user: - devices.append("/dev/mem") - else: - sys.stdout.write(" * %s\n"%red("Running test as normal user, will not try to read /dev/mem")) - - try: - pymap = '../src/pymap.xml' - sys.stdout.write(" * Loading %s for XML->Python dictonary mapping..." % pymap) - dmidecode.pythonmap(pymap) + vwrite(" * Importing module...", 1) + import libxml2 + import dmidecode + if not root_user: + vwrite("\n%s"%cyan("Not running as root, warning above is expected..."), 1) passed() - except: - failed() - random.shuffle(types) - random.shuffle(devices) - random.shuffle(sections) + vwrite(" * Version: %s\n"%blue(dmidecode.version), 1) + vwrite(" * DMI Version String: %s\n"%blue(dmidecode.dmi), 1) + + vwrite(" * Testing that default device is /dev/mem...", 1) + test(dmidecode.get_dev() == "/dev/mem") + + vwrite(" * Testing that write-lock will not break on dump()...", 1) + test(not dmidecode.dump()) + + vwrite(" * Testing ability to change device to %s..."%DUMP, 1) + test(dmidecode.set_dev(DUMP)) + + vwrite(" * Testing that device has changed to %s..."%DUMP, 1) + test(dmidecode.get_dev() == DUMP) + + if root_user: + vwrite(" * Testing that write on new file is ok...", 1) + test(dmidecode.dump()) + + vwrite(" * Testing that file was actually written...", 1) + time.sleep(0.1) + if test(os.path.exists(DUMP)): + os.unlink(DUMP) + else: + vwrite( + " * %s\n" % red( + "Skip testing API function, missing root privileges: dmidecode.dump()" + ), 1) + + 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: + vwrite(" * If you have memory dumps to test, create a directory called `%s' and drop them in there.\n" % DUMPS_D, 1) + + if root_user: + devices.append("/dev/mem") + else: + vwrite(" * %s\n"%red("Running test as normal user, will not try to read /dev/mem"), 1) - 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() + pymap = '../src/pymap.xml' + vwrite(" * Loading %s for XML->Python dictonary mapping..." % pymap, 1) + dmidecode.pythonmap(pymap) + passed() + except: + failed() + + random.shuffle(types) + random.shuffle(devices) + random.shuffle(sections) + + for dev in devices: + vwrite(LINE, 1) + vwrite(" * Testing %s..."%yellow(dev), 1) 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 => ") + fH = open(dev, 'r') + fH.close() 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() + vwrite(" * Testing set_dev/get_dev on %s..."%(yellow(dev)), 1) + if test(dmidecode.set_dev(dev) and dmidecode.get_dev() == dev): + i = 0 + for section in sections: + i += 1 + vwrite(" * Testing %s (%d/%d)..."%(cyan(section), i, len(sections)), 1) + try: + output = getattr(dmidecode, section)() + test(output is not False) + if output: + vwrite(" * %s\n"%black(output.keys()), 1) + except LookupError, e: + failed(e, 1) + + for i in bad_types: + vwrite(" * Testing bad type %s..."%red(i), 1) + try: + output = dmidecode.type(i) + test(output is False) + except SystemError: + failed() + + for i in types: + vwrite(" * Testing type %s..."%red(i), 1) + 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: + vwrite(" * %s\n"%output.keys(), 1) + except IOError, e: + failed(e, 1) + except LookupError, e: + failed(e, 1) + + + dmixml = dmidecode.dmidecodeXML() + try: + vwrite(" * XML: Swapping result type dmidecodeXML::SetResultType('-')...", 1) + test(not dmixml.SetResultType('-')) + except TypeError: + vwrite("Not working => ", 1) + passed() + except: + vwrite("Accepted => ", 1) + failed() + + try: + vwrite(" * XML: Swapping result type - dmidecodeXML::SetResultType(dmidecode.DMIXML_DOC)...", 1) + test(dmixml.SetResultType(dmidecode.DMIXML_DOC)) + vwrite(" * XML: Swapping result type - dmidecodeXML::SetResultType(dmidecode.DMIXML_NODE)...", 1) + test(dmixml.SetResultType(dmidecode.DMIXML_NODE)) + except: + failed() + + for i in bad_types: + vwrite(" * XML: Testing bad type - dmidecodeXML::QueryTypeId(%s)..." % red(i), 1) + try: + output_node = dmixml.QueryTypeId(i) + test(not isinstance(output_node, libxml2.xmlNode)) + except SystemError: + vwrite("Accepted => ", 1) + failed() + except TypeError: + vwrite("Not working => ", 1) + passed() + except ValueError: + vwrite("Not working => ", 1) + passed() + + for i in types: + vwrite(" * XML: Testing dmidecodeXML::QueryTypeId(%s, 2)..." % red(i), 1) + try: + output_node = dmixml.QueryTypeId(i) + test(isinstance(output_node, libxml2.xmlNode)) + except Exception, e: + failed(e, 1) + except: + failed() + + dmixml.SetResultType(dmidecode.DMIXML_DOC) + i = 0 + for section in sections: + i += 1 + vwrite(" * %s (%d/%d)..." % ( + "XML: Testing dmidecodeXML::QuerySection('%s')" % cyan( + section + ), i, len(sections) + ), 1) + try: + output_doc = dmixml.QuerySection(section) + test(isinstance(output_doc, libxml2.xmlDoc)) + except Exception, e: + failed(e, 1) + except: + failed() + + except IOError: + skipped() except ImportError, err: - failed() - print err - -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"])) + failed() + print err + +vwrite(LINE, 1) +vwrite("Devices : %s\n"%cyan(len(devices)), 1) +vwrite("Total : %s\n"%blue(score["total"]), 1) +vwrite("Skipped : %s\n"%yellow(score["skipped"]), 1) +vwrite("Passed : %s\n"%green(score["passed"]), 1) +vwrite("Failed : %s\n"%red(score["failed"]), 1) + +sys.exit(score[failed] != 0 and 1 or 0) From 980a04b7c43dcd067add9cf56ae0183d7b6f5d0b Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Mon, 14 Dec 2009 16:05:38 +0100 Subject: [PATCH 035/146] Fixed missing quotes, which lead all tests to fail --- unit-tests/unit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unit-tests/unit b/unit-tests/unit index fc9c3dc..404c9c7 100755 --- a/unit-tests/unit +++ b/unit-tests/unit @@ -346,4 +346,4 @@ vwrite("Skipped : %s\n"%yellow(score["skipped"]), 1) vwrite("Passed : %s\n"%green(score["passed"]), 1) vwrite("Failed : %s\n"%red(score["failed"]), 1) -sys.exit(score[failed] != 0 and 1 or 0) +sys.exit(score["failed"] != 0 and 1 or 0) From 3d24b5a99f0d57d9db98935aa8a7e471e7defbab Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Mon, 14 Dec 2009 16:06:08 +0100 Subject: [PATCH 036/146] Run unit tests with more verbose info --- unit-tests/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unit-tests/Makefile b/unit-tests/Makefile index be2fcf9..95086c1 100644 --- a/unit-tests/Makefile +++ b/unit-tests/Makefile @@ -1,5 +1,5 @@ test : - python unit + python unit -vv clean : rm -f *.{py[oc],o,so} *~ From 2b34fc482c99cc1011cc7eae9da4b3dc3d1ab2c7 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Mon, 14 Dec 2009 19:39:25 +1100 Subject: [PATCH 037/146] Added WARN as an alternative to soft failures --- unit-tests/unit | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/unit-tests/unit b/unit-tests/unit index 404c9c7..7802942 100755 --- a/unit-tests/unit +++ b/unit-tests/unit @@ -90,6 +90,7 @@ score = { "total" : 0, "skipped" : 0, "passed" : 0, + "warned" : 0, "failed" : 0, } @@ -107,6 +108,13 @@ def skipped(msg=None, indent=1): vwrite("%s\n"%yellow("SKIP"), 1) if msg: vwrite("%s %s %s\n"%(" "*indent, yellow("S"), msg), 1) +def warned(msg=None, indent=1): + global score + score["total"] += 1 + score["warned"] += 1 + vwrite("%s\n"%yellow("WARN"), 1) + if msg: vwrite("%s %s %s\n"%(" "*indent, yellow("S"), msg), 1) + def failed(msg=None, indent=1): global score score["total"] += 1 @@ -114,12 +122,12 @@ def failed(msg=None, indent=1): vwrite("%s\n"%red("FAIL"), 1) if msg: vwrite("%s %s %s\n"%(" "*indent, red("F"), msg), 1) -def test(r, msg=None, indent=1): +def test(r, msg=None, indent=1, bad=failed): if r: passed(msg, indent) return True else: - failed(msg, indent) + bad(msg, indent) return False def vwrite(msg, vLevel=0): @@ -135,8 +143,12 @@ os.dup2(err.fileno(), sys.stderr.fileno()) vwrite(LINE, 1) vwrite(" * Testing for command line version of dmidecode ...", 1) -dmidecode_bin = True in [os.path.exists(os.path.join(_, "dmidecode")) for _ in os.getenv("PATH").split(':')] -test(dmidecode_bin) +dmidecode_bin = True in [ + os.path.exists( + os.path.join(_, "dmidecode") + ) for _ in os.getenv("PATH").split(':') +] +test(dmidecode_bin, bad=warned) if root_user: vwrite(" * Running test as root user, all tests will be executed\n", 1) else: @@ -343,6 +355,7 @@ vwrite(LINE, 1) vwrite("Devices : %s\n"%cyan(len(devices)), 1) vwrite("Total : %s\n"%blue(score["total"]), 1) vwrite("Skipped : %s\n"%yellow(score["skipped"]), 1) +vwrite("Warned : %s\n"%yellow(score["warned"]), 1) vwrite("Passed : %s\n"%green(score["passed"]), 1) vwrite("Failed : %s\n"%red(score["failed"]), 1) From 1d501fb001a1ab201cd5fb38e1a011d3bb13a045 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Mon, 14 Dec 2009 17:45:59 +0100 Subject: [PATCH 038/146] Take endinanness into consideration when compiling --- src/setup-dbg.py | 4 +++- src/setup.py | 4 +++- src/setup_common.py | 8 ++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/setup-dbg.py b/src/setup-dbg.py index 9602abc..faced4c 100644 --- a/src/setup-dbg.py +++ b/src/setup-dbg.py @@ -42,6 +42,7 @@ # misc info dmidec_version = get_version() +macros = get_macros() # # Python setup @@ -73,7 +74,8 @@ include_dirs = incdir, library_dirs = libdir, libraries = libs, - undef_macros = [ "NDEBUG" ] + undef_macros = [ "NDEBUG" ], + define_macros = macros ) ], py_modules = [ "dmidecode" ] diff --git a/src/setup.py b/src/setup.py index d33db64..b65957c 100644 --- a/src/setup.py +++ b/src/setup.py @@ -42,6 +42,7 @@ # misc info dmidec_version = get_version() +macros = get_macros() # # Python setup @@ -73,7 +74,8 @@ include_dirs = incdir, library_dirs = libdir, libraries = libs, - undef_macros = [ "NDEBUG" ] + undef_macros = [ "NDEBUG" ], + define_macros = macros ) ], py_modules = [ "dmidecode" ] diff --git a/src/setup_common.py b/src/setup_common.py index fdf5c8c..209ccef 100644 --- a/src/setup_common.py +++ b/src/setup_common.py @@ -91,3 +91,11 @@ def get_version(): return version +def get_macros(): + "Sets macros which is relevant for all setup*.py files" + + macros = [] + if sys.byteorder == 'big': + macros.append(("ALIGNMENT_WORKAROUND", None)) + return macros + From e22cd7e0abeaae055f1daacc262f1715c5cebc74 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Mon, 14 Dec 2009 17:53:17 +0100 Subject: [PATCH 039/146] Do not try to dump DMI data if test hardware do not support it --- unit-tests/unit | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/unit-tests/unit b/unit-tests/unit index 7802942..8025e1a 100755 --- a/unit-tests/unit +++ b/unit-tests/unit @@ -187,7 +187,7 @@ try: vwrite(" * Testing that device has changed to %s..."%DUMP, 1) test(dmidecode.get_dev() == DUMP) - if root_user: + if root_user and dmidecode.dmi is not None: vwrite(" * Testing that write on new file is ok...", 1) test(dmidecode.dump()) @@ -196,10 +196,16 @@ try: if test(os.path.exists(DUMP)): os.unlink(DUMP) else: - vwrite( - " * %s\n" % red( - "Skip testing API function, missing root privileges: dmidecode.dump()" - ), 1) + if dmidecode.dmi is None: + vwrite( + " * %s\n" % yellow( + "Skipped testing API function, hardware does not have DMI data" + ), 1) + else: + vwrite( + " * %s\n" % red( + "Skip testing API function, missing root privileges: dmidecode.dump()" + ), 1) types = range(0, 42)+range(126, 128) bad_types = [-1, -1000, 256] @@ -220,10 +226,11 @@ try: else: vwrite(" * If you have memory dumps to test, create a directory called `%s' and drop them in there.\n" % DUMPS_D, 1) - if root_user: + if root_user and dmidecode.dmi is not None: devices.append("/dev/mem") else: - vwrite(" * %s\n"%red("Running test as normal user, will not try to read /dev/mem"), 1) + if dmidecode.dmi is not None: + vwrite(" * %s\n"%red("Running test as normal user, will not try to read /dev/mem"), 1) try: pymap = '../src/pymap.xml' From 1a576387020480c3b5eb25c4c1d605181df0c315 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Mon, 14 Dec 2009 18:01:45 +0100 Subject: [PATCH 040/146] Fixed errornous log line --- unit-tests/unit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unit-tests/unit b/unit-tests/unit index 8025e1a..d2b94bb 100755 --- a/unit-tests/unit +++ b/unit-tests/unit @@ -325,7 +325,7 @@ try: passed() for i in types: - vwrite(" * XML: Testing dmidecodeXML::QueryTypeId(%s, 2)..." % red(i), 1) + vwrite(" * XML: Testing dmidecodeXML::QueryTypeId(%s)..." % red(i), 1) try: output_node = dmixml.QueryTypeId(i) test(isinstance(output_node, libxml2.xmlNode)) From 616b584fce9116d34ce7aa3fe0b41ea0033581dc Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Mon, 14 Dec 2009 20:00:11 +0100 Subject: [PATCH 041/146] Updated utils/set_version to be more intelligent with the .spec file - Reset the Release variable in the .spec file to 1 - Add a changelog entry with the new version --- utils/set_version | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/utils/set_version b/utils/set_version index c42f6d6..97c18c9 100755 --- a/utils/set_version +++ b/utils/set_version @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash if [ $# != 1 ]; then echo "Usage: $0 " @@ -14,6 +14,26 @@ fi NEW_VERSION=$1 OLD_VERSION=$(cd src;python -c "from setup_common import *; print get_version();") +# Prepare ChangeLog entry for the python-dmidecode.spec file +TSTAMP="$(date +%a\ %b\ %d\ %Y)" +FNAME="$(git config user.name)" +EMAIL="$(git config user.email)" +CHLOG="$TSTAMP $FNAME <$EMAIL> - ${NEW_VERSION}-1" + +# Prepare regexp script to modify python-dmidecode.spec +{ +cat < .chversion + +# Get confirmation of version change cat </dev/null - echo " ** Updating redhat.spec" - printf ",s/^Version: .*/Version: ${NEW_VERSION}/\nw\n" | ed contrib/python-dmidecode.spec 2>/dev/null - + echo " ** Updating contrib/python-dmidecode.spec" + cat .chversion | ed contrib/python-dmidecode.spec 2> /dev/null + if [ $? = 0 ]; then + rm -f .chversion + fi echo - echo " ** git add src/version.h redhat.spec" + echo " ** git add src/version.h contrib/python-dmidecode.spec" git add src/version.h contrib/python-dmidecode.spec + echo "-----------------------------------------------------------------------------------" git diff --cached + echo "-----------------------------------------------------------------------------------" echo - echo " REMEMBER to commit this change when you have validated the result" + echo " ** **" + echo " ** REMEMBER to COMMIT this change when you have validated the result **" + echo " ** **" echo ;; *) From 086c7c441d109f608172341e1cc14f04e57df50d Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 15 Dec 2009 11:32:01 +0100 Subject: [PATCH 042/146] Removed yet another dmidecode.dump() test when running as non-root --- unit-tests/unit | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/unit-tests/unit b/unit-tests/unit index d2b94bb..fcd11fa 100755 --- a/unit-tests/unit +++ b/unit-tests/unit @@ -178,8 +178,9 @@ try: vwrite(" * Testing that default device is /dev/mem...", 1) test(dmidecode.get_dev() == "/dev/mem") - vwrite(" * Testing that write-lock will not break on dump()...", 1) - test(not dmidecode.dump()) + if root_user: + vwrite(" * Testing that write-lock will not break on dump()...", 1) + test(not dmidecode.dump()) vwrite(" * Testing ability to change device to %s..."%DUMP, 1) test(dmidecode.set_dev(DUMP)) @@ -199,7 +200,7 @@ try: if dmidecode.dmi is None: vwrite( " * %s\n" % yellow( - "Skipped testing API function, hardware does not have DMI data" + "Skipped testing dump() function, hardware does not have DMI data" ), 1) else: vwrite( From ede0c5c66531831986fc95b24632b0561ef075d6 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 15 Dec 2009 11:53:36 +0100 Subject: [PATCH 043/146] Improved some log lines --- unit-tests/unit | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/unit-tests/unit b/unit-tests/unit index fcd11fa..8f9184b 100755 --- a/unit-tests/unit +++ b/unit-tests/unit @@ -169,7 +169,7 @@ try: import libxml2 import dmidecode if not root_user: - vwrite("\n%s"%cyan("Not running as root, warning above is expected..."), 1) + vwrite("\n%s"%cyan("Not running as root, a warning above can be expected..."), 1) passed() vwrite(" * Version: %s\n"%blue(dmidecode.version), 1) @@ -200,7 +200,7 @@ try: if dmidecode.dmi is None: vwrite( " * %s\n" % yellow( - "Skipped testing dump() function, hardware does not have DMI data" + "Skipped testing dump() function, dmidecode does not have access to DMI data" ), 1) else: vwrite( @@ -293,7 +293,7 @@ try: dmixml = dmidecode.dmidecodeXML() try: - vwrite(" * XML: Swapping result type dmidecodeXML::SetResultType('-')...", 1) + vwrite(" * XML: Swapping result type dmidecodeXML::SetResultType('-') - invalid type... ", 1) test(not dmixml.SetResultType('-')) except TypeError: vwrite("Not working => ", 1) @@ -303,9 +303,9 @@ try: failed() try: - vwrite(" * XML: Swapping result type - dmidecodeXML::SetResultType(dmidecode.DMIXML_DOC)...", 1) + vwrite(" * XML: Swapping result type - dmidecodeXML::SetResultType(dmidecode.DMIXML_DOC) - valid type...", 1) test(dmixml.SetResultType(dmidecode.DMIXML_DOC)) - vwrite(" * XML: Swapping result type - dmidecodeXML::SetResultType(dmidecode.DMIXML_NODE)...", 1) + vwrite(" * XML: Swapping result type - dmidecodeXML::SetResultType(dmidecode.DMIXML_NODE) - valid type...", 1) test(dmixml.SetResultType(dmidecode.DMIXML_NODE)) except: failed() From 7a93063f3c85de467890902c3e1cdf3913f1d5c8 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Tue, 15 Dec 2009 10:33:57 +1100 Subject: [PATCH 044/146] Endian-aware code --- debian/changelog | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 439175d..34959b4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,12 +1,13 @@ python-dmidecode (3.10.8-1) unstable; urgency=low * New Upstream release. + * Big-endian and little-endian approved. * Packaged unit-test to tarball. * Rewritten unit-test to be able to run as non-root user, where it will not try to read /dev/mem. * Added two dmidump data files to the unit-test. - -- Nima Talebi Mon, 14 Dec 2009 17:11:53 +1100 + -- Nima Talebi Tue, 15 Dec 2009 10:33:31 +1100 python-dmidecode (3.10.7-3) unstable; urgency=low From 2963939d58332c509d1849e438352ea0e3490e5b Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 17 Dec 2009 19:13:58 +0100 Subject: [PATCH 045/146] Improved set_dev() function This function would often fail during the unit test. Most probably because the complete error checking was a bit odd. Rewritten the error checks to be a bit more sane. Also improved error situations, where it will now throw an exception with an error message instead of just returning False. --- src/dmidecodemodule.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 5c74124..003051b 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -594,24 +594,36 @@ static PyObject *dmidecode_set_dev(PyObject * self, PyObject * arg) && (strcmp(global_options->dumpfile, f) == 0) ) { Py_RETURN_TRUE; } + if( (f == NULL) || (strlen(f) < 0) ) { + PyReturnError(PyExc_RuntimeError, "set_dev() file name string cannot be empty"); + } - stat(f, &buf); + errno = 0; + if( stat(f, &buf) < 0 ) { + if( errno == ENOENT ) { + // If this file does not exist, that's okay. + // python-dmidecode will create it. + global_options->dumpfile = strdup(f); + Py_RETURN_TRUE; + } + PyReturnError(PyExc_RuntimeError, strerror(errno)); + } if(S_ISCHR(buf.st_mode)) { - if(memcmp(PyString_AsString(arg), "/dev/mem", 8) == 0) { + if(memcmp(f, "/dev/mem", 8) == 0) { if( global_options->dumpfile != NULL ) { free(global_options->dumpfile); global_options->dumpfile = NULL; } Py_RETURN_TRUE; } else { - Py_RETURN_FALSE; + PyReturnError(PyExc_RuntimeError, "Invalid memory device: %s", f); } - } else if(!S_ISDIR(buf.st_mode)) { + } else if(S_ISREG(buf.st_mode) || S_ISLNK(buf.st_mode) ) { global_options->dumpfile = strdup(f); Py_RETURN_TRUE; } } - Py_RETURN_FALSE; + PyReturnError(PyExc_RuntimeError, "set_dev(): Invalid input"); } static PyObject *dmidecode_set_pythonxmlmap(PyObject * self, PyObject * arg) From 5a2df385687e947d9d34859ff2b772b56accb627 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Tue, 15 Dec 2009 11:24:31 +1100 Subject: [PATCH 046/146] Updated for 3.10.8 --- contrib/python-dmidecode.spec | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/contrib/python-dmidecode.spec b/contrib/python-dmidecode.spec index 0d8bde2..90ae9c8 100644 --- a/contrib/python-dmidecode.spec +++ b/contrib/python-dmidecode.spec @@ -49,6 +49,15 @@ rm -rf $RPM_BUILD_ROOT %{_datadir}/python-dmidecode/ %changelog + +* Thu Dec 15 2009 Nima Talebi - 3.10.8-1 +- New Upstream release. +- Big-endian and little-endian approved. +- Packaged unit-test to tarball. +- Rewritten unit-test to be able to run as non-root user, where it will not + try to read /dev/mem. +- Added two dmidump data files to the unit-test. + * Thu Nov 26 2009 David Sommerseth - 3.10.7-3 - Fixed even more .spec file issues and removed explicit mentioning of /usr/share/python-dmidecode/pymap.xml From 5d26fd4b09109664198539618a8679685fa18607 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Sun, 20 Dec 2009 11:19:42 +1100 Subject: [PATCH 047/146] Changes necessary to keep Debian packages sane Both setup.py and setup-dbg.py install the same file, namely: /usr/share/pyshared/dmidecode.py This generated Bug#561904. This commit closes this bug. --- Makefile | 8 +++++++- src/setup-dbg.py | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 6793970..fce6c72 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,8 @@ VERSION := $(shell cd src;python -c "from setup_common import *; print get_versi PACKAGE := python-dmidecode 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 +SO := build/lib.linux-$(shell uname -m)-$(PY_VER)/dmidecodemod.so +SHELL := /bin/bash ############################################################################### .PHONY: build dmidump install uninstall clean tarball rpm unit version @@ -65,3 +66,8 @@ version: @echo "python-dmidecode: $(VERSION)" @echo "python version: $(PY_VER) ($(PY))" +conflicts: + @comm -12 \ + <(dpkg-deb -c ../../DPKGS/python-dmidecode_$(VERSION)-1_amd64.deb | awk '$$NF!~/\/$$/{print$$NF}'|sort) \ + <(dpkg-deb -c ../../DPKGS/python-dmidecode-dbg_$(VERSION)-1_amd64.deb | awk '$$NF!~/\/$$/{print$$NF}'|sort) + diff --git a/src/setup-dbg.py b/src/setup-dbg.py index faced4c..b91e3e0 100644 --- a/src/setup-dbg.py +++ b/src/setup-dbg.py @@ -78,5 +78,5 @@ define_macros = macros ) ], - py_modules = [ "dmidecode" ] + py_modules = [ "dmidecode-dbg" ] ) From 1b810386b0191cd68209f98b23310ba453e90865 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Sun, 20 Dec 2009 11:21:17 +1100 Subject: [PATCH 048/146] Closes Bug#561904 --- debian/changelog | 6 ++++++ debian/rules | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 34959b4..5b45cc1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +python-dmidecode (3.10.8-2) unstable; urgency=low + + * Resolved conflict between standard and debug package (Closes: #561904). + + -- Nima Talebi Sun, 20 Dec 2009 11:17:37 +1100 + python-dmidecode (3.10.8-1) unstable; urgency=low * New Upstream release. diff --git a/debian/rules b/debian/rules index 906da77..fca75cb 100755 --- a/debian/rules +++ b/debian/rules @@ -13,6 +13,7 @@ build-ext-%: python$* src/setup.py build touch $@ build-dbg-ext-%: + cp dmidecode.py dmidecode-dbg.py python$*-dbg src/setup-dbg.py build touch $@ @@ -60,7 +61,7 @@ clean: dh_testdir dh_testroot $(MAKE) -f Makefile clean - dh_clean build-stamp install-stamp \ + dh_clean build-stamp install-stamp dmidecode-dbg.py \ $(PYVERS:%=install-ext-%) $(PYVERS:%=build-ext-%) \ $(PYVERS:%=install-dbg-ext-%) $(PYVERS:%=build-dbg-ext-%) From 21b8547681620006fe357d90d15e7f7667dcdb91 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Wed, 6 Jan 2010 16:06:43 +1100 Subject: [PATCH 049/146] Applied patch from Scott Kitterman --- debian/changelog | 7 +++++++ debian/control | 2 +- debian/rules | 8 ++++++-- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/debian/changelog b/debian/changelog index 5b45cc1..0464057 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +python-dmidecode (3.10.9-1) lucid; urgency=low + + * Add --install-layout=deb to debian/rules setup.py install to prevent files + from landing in /usr/local. + + -- Scott Kitterman Tue, 05 Jan 2010 22:02:29 -0500 + python-dmidecode (3.10.8-2) unstable; urgency=low * Resolved conflict between standard and debug package (Closes: #561904). diff --git a/debian/control b/debian/control index 93383b0..ba2ea7b 100644 --- a/debian/control +++ b/debian/control @@ -5,7 +5,7 @@ Priority: optional Homepage: http://projects.autonomy.net.au/python-dmidecode Maintainer: Nima Talebi Build-Depends: debhelper (>> 7), python-support (>= 0.5.3), python, - python-all-dev (>= 2.3.5-11), python-all-dbg, libxml2-dev, python-libxml2 + python-all-dev (>= 2.5.4-2), python-all-dbg, libxml2-dev, python-libxml2 Standards-Version: 3.8.3 Package: python-dmidecode diff --git a/debian/rules b/debian/rules index fca75cb..c33d38d 100755 --- a/debian/rules +++ b/debian/rules @@ -31,10 +31,14 @@ install: install-stamp dh_installman install-stamp: build-stamp $(PYVERS:%=install-ext-%) $(PYVERS:%=install-dbg-ext-%) install-ext-%: - python$* src/setup.py install --root $(CURDIR)/debian/$(PACKAGE) + python$* src/setup.py install \ + --root $(CURDIR)/debian/$(PACKAGE) \ + --install-layout=deb touch $@ install-dbg-ext-%: - python$*-dbg src/setup-dbg.py install --root $(CURDIR)/debian/$(PACKAGE)-dbg + python$*-dbg src/setup-dbg.py install \ + --root $(CURDIR)/debian/$(PACKAGE)-dbg \ + --install-layout=deb #find $(CURDIR)/debian/$(PACKAGE)-dbg/usr/lib/python$*/ ! -type d ! -name '*_d\.so' -delete #find $(CURDIR)/debian/$(PACKAGE)-dbg/usr/lib/python$*/ -depth -empty -delete touch $@ From 91e9ccb035aee85e34f2dca3ee910412ea5b3117 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Wed, 6 Jan 2010 16:08:12 +1100 Subject: [PATCH 050/146] New upstream release --- debian/changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/debian/changelog b/debian/changelog index 0464057..d7a6017 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,6 @@ python-dmidecode (3.10.9-1) lucid; urgency=low + * New upstream bug-fix release. * Add --install-layout=deb to debian/rules setup.py install to prevent files from landing in /usr/local. From 778906214a5bf603e51a093907e37f04de90993f Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Wed, 6 Jan 2010 16:29:35 +1100 Subject: [PATCH 051/146] Added bug id --- debian/changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index d7a6017..795079b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,7 +2,7 @@ python-dmidecode (3.10.9-1) lucid; urgency=low * New upstream bug-fix release. * Add --install-layout=deb to debian/rules setup.py install to prevent files - from landing in /usr/local. + from landing in /usr/local (Closes: Bug#563883). -- Scott Kitterman Tue, 05 Jan 2010 22:02:29 -0500 From 125162cc1eede0c2964c2d72a5c170dff3d9ca5a Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Thu, 7 Jan 2010 00:16:53 +1100 Subject: [PATCH 052/146] Forgot to update versioning information (Despite dazo automating the process with a script, it was obviously still too difficult). --- contrib/python-dmidecode.spec | 5 ++++- src/version.h | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/contrib/python-dmidecode.spec b/contrib/python-dmidecode.spec index 90ae9c8..d01e831 100644 --- a/contrib/python-dmidecode.spec +++ b/contrib/python-dmidecode.spec @@ -3,7 +3,7 @@ Summary: Python module to access DMI data Name: python-dmidecode -Version: 3.10.8 +Version: 3.10.9 Release: 1%{?dist} License: GPLv2 Group: System Environment/Libraries @@ -49,6 +49,9 @@ rm -rf $RPM_BUILD_ROOT %{_datadir}/python-dmidecode/ %changelog +* Thu Jan 07 2010 Nima Talebi - 3.10.9-1 +- Update to new release + * Thu Dec 15 2009 Nima Talebi - 3.10.8-1 - New Upstream release. diff --git a/src/version.h b/src/version.h index 4ea8b89..eef20b6 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define VERSION "3.10.8" +#define VERSION "3.10.9" From b0de4453c466339c7751bf8595a965b19da579e2 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 7 Jan 2010 16:45:30 +0100 Subject: [PATCH 053/146] Removed not needed information --- src/efi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/efi.c b/src/efi.c index 9802171..57a7a5c 100644 --- a/src/efi.c +++ b/src/efi.c @@ -67,7 +67,6 @@ int address_from_efi(size_t * address) *(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; } From 0769e2e4d553d974af17f41159a010d6959044fc Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 7 Jan 2010 16:49:08 +0100 Subject: [PATCH 054/146] Make sure const char *filename is not a wild pointer --- src/efi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/efi.c b/src/efi.c index 57a7a5c..8c38e38 100644 --- a/src/efi.c +++ b/src/efi.c @@ -45,7 +45,7 @@ int address_from_efi(size_t * address) { FILE *efi_systab; - const char *filename; + const char *filename = NULL; char linebuf[64]; int ret; From 2d12f753c24bcd8fb959e850ea303b0db55e2e9b Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 8 Jan 2010 13:12:27 +0100 Subject: [PATCH 055/146] Removed struct dmi_minor. It was not used anywhere. --- src/dmihelper.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/dmihelper.h b/src/dmihelper.h index d89c024..55a2843 100644 --- a/src/dmihelper.h +++ b/src/dmihelper.h @@ -111,14 +111,6 @@ static const dmi_codes_major dmiCodesMajor[] = { {-1, NULL, NULL, NULL} }; -typedef struct _dmi_minor { - long id; - dmi_codes_major *major; - char *key; - char value[MAXVAL]; - struct _dmi_minor *next; -} dmi_minor; - /*** dmiopt.h ***/ typedef struct _options { const char *devmem; From f06734946d5c5fb29a0cd24785101921f78c7756 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 8 Jan 2010 15:28:16 +0100 Subject: [PATCH 056/146] Moved write_dump() over to dmidump.c, as this is the only user of this function --- src/dmidump.c | 38 ++++++++++++++++++++++++++++++++++++++ src/util.c | 36 ------------------------------------ 2 files changed, 38 insertions(+), 36 deletions(-) diff --git a/src/dmidump.c b/src/dmidump.c index a07c975..641b937 100644 --- a/src/dmidump.c +++ b/src/dmidump.c @@ -51,6 +51,44 @@ static void overwrite_dmi_address(u8 * buf) buf[0x0B] = 0; } + +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; +} + + int dumpling(u8 * buf, const char *dumpfile, u8 mode) { u32 base; diff --git a/src/util.c b/src/util.c index 014b75d..9bd86c5 100644 --- a/src/util.c +++ b/src/util.c @@ -154,39 +154,3 @@ void *mem_chunk(size_t base, size_t len, const char *devmem) 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; -} - From fb3f735aaf84e6b6d2f37907ed9e6a8b014e76bb Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 8 Jan 2010 18:31:47 +0100 Subject: [PATCH 057/146] Added a new log API --- src/dmilog.c | 211 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/dmilog.h | 55 ++++++++++++++ 2 files changed, 266 insertions(+) create mode 100644 src/dmilog.c create mode 100644 src/dmilog.h diff --git a/src/dmilog.c b/src/dmilog.c new file mode 100644 index 0000000..acc465f --- /dev/null +++ b/src/dmilog.c @@ -0,0 +1,211 @@ +/* + * 2009 (C) David Sommerseth + * + * 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 dmilog.h + * @brief A simple log module + * @author David Sommerseth + */ + +#include +#include +#include +#include + +#include "dmilog.h" + +/** + * Allocates memory for a new Log_t record + * + * @return Returns a pointer to a new Log_t record, otherwise NULL on error + */ +Log_t * log_init() +{ + Log_t *ret = NULL; + + ret = (Log_t *) calloc(1, sizeof(Log_t)+2); + if( !ret ) { + fprintf(stderr, "** ERROR ** Could not allocate memory for log data\n"); + } + ret->level = -1; // Initialised - chain header pointer always have -1. + return ret; +} + + + + +/** + * Registers a new log entry + * + * @param logp Pointer to an allocated Log_t record. New records will be appended to the end + * @param level syslog log level values. LOG_ERR and LOG_WARNING are allowed + * @param fmt stdarg based string with the log contents + * + * @return Returns 1 on successful registration of log entry, otherwise -1 and error is printed to stderr + */ +int log_append(Log_t *logp, int level, const char *fmt, ...) +{ + Log_t *ptr = NULL; + va_list ap; + + // Go the end of the record chain + ptr = logp; + while( ptr && ptr->next ) { + ptr = ptr->next; + } + + + if( ptr && ((level == LOG_ERR) || (level == LOG_WARNING)) ) { + ptr->next = log_init(); + if( ptr->next ) { + ptr->next->message = (char *) calloc(1, 4098); + } + } + + va_start(ap, fmt); + if( !ptr || !ptr->next || !ptr->next->message ) { + fprintf(stderr, "** ERROR ** Failed to save log entry\n"); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + va_end(ap); + return -1; + } + + ptr->next->level = level; + vsnprintf(ptr->next->message, 4096, fmt, ap); + ptr->next->message = realloc(ptr->next->message, strlen(ptr->next->message)+2); + va_end(ap); + + return 1; +} + + +/** + * Retrieve all log entries in the Log_t record chain with the corresponding log level. + * One string will be returned, with all log entries separated with newline. + * + * @param logp Pointer to Log_t record chain with log data + * @param level Log entries to retrieve + * + * @return Returns a pointer to a buffer with all log lines. This must be freed after usage. + */ +char * log_retrieve(Log_t *logp, int level) +{ + char *ret = NULL; + size_t len = 0; + Log_t *ptr = NULL; + + if( !logp ) { + return NULL; + } + + for( ptr = logp; ptr != NULL; ptr = ptr->next ) { + if( ptr && ptr->level == level ) { + if( ret ) { + ret = realloc(ret, strlen(ptr->message)+len+3); + } else { + ret = calloc(1, strlen(ptr->message)+2); + } + + if( !ret ) { + fprintf(stderr, + "** ERROR ** Could not allocate log retrieval memory buffer\n"); + return NULL; + } + strcat(ret, ptr->message); + strcat(ret, "\n"); + ptr->read++; + len = strlen(ret); + } + } + return ret; +} + + +/** + * Remove only log records of a particular log level from the log chain. Only + * records that have been read (by using log_retrieve()) will be removed unless + * the unread argument == 1. + * + * @param logp Pointer to log chain to work on + * @param level Log level to remove + * @param unread Set to 1 to also clear unread log entriesz + * + * @return Returns number of removed elements. + */ +size_t log_clear_partial(Log_t *logp, int level, int unread) +{ + Log_t *ptr = NULL, *prev = NULL; + size_t elmnt = 0; + + if( !logp ) { + return 0; + } + + prev = logp; + for( ptr = logp->next; ptr != NULL; ptr = ptr->next ) { + if( !ptr ) { + break; + } + + // Only remove log entries which is of the expected log level + // and that have been read. + if( (ptr->level == level) && ((unread == 1) || (ptr->read > 0)) ) { + prev->next = ptr->next; + if( ptr->message ) { + free(ptr->message); + ptr->message = NULL; + } + free(ptr); + ptr = prev; + elmnt++; + } + prev = ptr; + } + + return elmnt; +} + + +/** + * Free all memory used by a Log_t pointer chain. + * + * @param logp Pointer to log entries to free up. + */ +void log_close(Log_t *logp) +{ + Log_t *ptr = NULL, *next = NULL; + + ptr = logp; + while( ptr ) { + next = ptr->next; + ptr->next = NULL; + if( ptr->message ) { + free(ptr->message); + ptr->message = NULL; + } + free(ptr); + ptr = next; + } +} diff --git a/src/dmilog.h b/src/dmilog.h new file mode 100644 index 0000000..98d0780 --- /dev/null +++ b/src/dmilog.h @@ -0,0 +1,55 @@ +/* + * 2009 (C) David Sommerseth + * + * 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 dmilog.h + * @brief A simple log module + * @author David Sommerseth + */ + + +#ifndef DMILOG_H +#define DMILOG_H + +#include +#include + +/** + * Struct defining log records. Organised as a pointer chain. + */ +struct _Log_t { + int level; /**< Log type, based on syslog levels (LOG_ERR|LOG_WARNING) */ + char *message; /**< Formated log text */ + unsigned int read; /**< Number of times this log entry has been read */ + struct _Log_t *next; /**< Next log entry */ +}; +typedef struct _Log_t Log_t; + +Log_t * log_init(); +int log_append(Log_t *logp, int level, const char *fmt, ...); +char * log_retrieve(Log_t *logp, int level); +size_t log_clear_partial(Log_t *logp, int level, int unread); +void log_close(Log_t *logp); + +#endif From fbc7a2ea8f6510f14a5f670dbd1ed8d7b87bac20 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 8 Jan 2010 19:20:43 +0100 Subject: [PATCH 058/146] Don't print false error warning if logp == NULL --- src/dmilog.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/dmilog.c b/src/dmilog.c index acc465f..e9b89e8 100644 --- a/src/dmilog.c +++ b/src/dmilog.c @@ -85,7 +85,13 @@ int log_append(Log_t *logp, int level, const char *fmt, ...) va_start(ap, fmt); if( !ptr || !ptr->next || !ptr->next->message ) { - fprintf(stderr, "** ERROR ** Failed to save log entry\n"); + if( logp ) { + // Only print this if we logp is pointing somewhere. + // If it is NULL, the caller did not establish a log + // buffer on purpose (like dmidump.c) - thus this is + // not an error with saving the log entry. + fprintf(stderr, "** ERROR ** Failed to save log entry\n"); + } vfprintf(stderr, fmt, ap); fprintf(stderr, "\n"); va_end(ap); From 2d69406de843db678c84cb397afab03e0573c468 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 8 Jan 2010 19:24:33 +0100 Subject: [PATCH 059/146] Implement a global log buffer and start porting fprint() -> log_append() --- src/dmidecodemodule.c | 97 ++++++++++++++++++++++++++++++++----------- src/dmihelper.h | 2 + 2 files changed, 75 insertions(+), 24 deletions(-) diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 003051b..61e3b9a 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -48,16 +48,13 @@ #include "dmidecodemodule.h" #include "dmixml.h" #include "dmierror.h" +#include "dmilog.h" #include "version.h" #include "dmidump.h" #include 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; @@ -65,9 +62,15 @@ static void init(options *opt) opt->dmiversion_n = NULL; opt->mappingxml = NULL; opt->python_xml_map = strdup(PYTHON_XML_MAP); + opt->logdata = log_init(); + + /* sanity check */ + if(sizeof(u8) != 1 || sizeof(u16) != 2 || sizeof(u32) != 4 || '\0' != 0) { + log_append(opt->logdata, LOG_WARNING, "%s: compiler incompatibility\n", "dmidecodemodule"); + } } -int parse_opt_type(const char *arg) +int parse_opt_type(Log_t *logp, const char *arg) { while(*arg != '\0') { int val; @@ -75,11 +78,11 @@ int parse_opt_type(const char *arg) val = strtoul(arg, &next, 0); if(next == arg) { - fprintf(stderr, "Invalid type keyword: %s\n", arg); + log_append(logp, LOG_ERR, "Invalid type keyword: %s\n", arg); return -1; } if(val > 0xff) { - fprintf(stderr, "Invalid type number: %i\n", val); + log_append(logp, LOG_ERR, "Invalid type number: %i\n", val); return -1; } @@ -110,7 +113,7 @@ xmlNode *dmidecode_get_version(options *opt) /* 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((buf = mem_chunk(opt->logdata, 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 ) { @@ -125,10 +128,10 @@ xmlNode *dmidecode_get_version(options *opt) } } else { /* Read from /dev/mem */ /* First try EFI (ia64, Intel-based Mac) */ - efi = address_from_efi(&fp); + efi = address_from_efi(opt->logdata, &fp); if(efi == EFI_NOT_FOUND) { /* Fallback to memory scan (x86, x86_64) */ - if((buf = mem_chunk(0xF0000, 0x10000, opt->devmem)) != NULL) { + if((buf = mem_chunk(opt->logdata, 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); @@ -148,7 +151,7 @@ xmlNode *dmidecode_get_version(options *opt) ver_n = NULL; } else { // Process as EFI - if((buf = mem_chunk(fp, 0x20, opt->devmem)) != NULL) { + if((buf = mem_chunk(opt->logdata, fp, 0x20, opt->devmem)) != NULL) { ver_n = smbios_decode_get_version(buf, opt->devmem); if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) { found++; @@ -161,7 +164,7 @@ xmlNode *dmidecode_get_version(options *opt) free(buf); } if( !found ) { - fprintf(stderr, "No SMBIOS nor DMI entry point found, sorry."); + log_append(opt->logdata, LOG_WARNING, "No SMBIOS nor DMI entry point found, sorry."); } return ver_n; } @@ -182,19 +185,19 @@ int dmidecode_get_xml(options *opt, xmlNode* dmixml_n) 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); + log_append(opt->logdata, LOG_WARNING, "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((buf = mem_chunk(opt->logdata, 0, 0x20, opt->dumpfile)) != NULL) { if(memcmp(buf, "_SM_", 4) == 0) { - if(smbios_decode(opt->type, buf, opt->dumpfile, dmixml_n)) + if(smbios_decode(opt->logdata, 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)) + if(legacy_decode(opt->logdata, opt->type, buf, opt->dumpfile, dmixml_n)) found++; } } else { @@ -202,18 +205,20 @@ int dmidecode_get_xml(options *opt, xmlNode* dmixml_n) } } else { /* Read from /dev/mem */ /* First try EFI (ia64, Intel-based Mac) */ - efi = address_from_efi(&fp); + efi = address_from_efi(opt->logdata, &fp); if(efi == EFI_NOT_FOUND) { /* Fallback to memory scan (x86, x86_64) */ - if((buf = mem_chunk(0xF0000, 0x10000, opt->devmem)) != NULL) { + if((buf = mem_chunk(opt->logdata, 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)) { + if(smbios_decode(opt->logdata, 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)) + if(legacy_decode(opt->logdata, opt->type, + buf + fp, opt->devmem, dmixml_n)) found++; } } @@ -222,9 +227,9 @@ int dmidecode_get_xml(options *opt, xmlNode* dmixml_n) } else if(efi == EFI_NO_SMBIOS) { ret = 1; } else { - if((buf = mem_chunk(fp, 0x20, opt->devmem)) == NULL) + if((buf = mem_chunk(opt->logdata, fp, 0x20, opt->devmem)) == NULL) ret = 1; - else if(smbios_decode(opt->type, buf, opt->devmem, dmixml_n)) + else if(smbios_decode(opt->logdata, opt->type, buf, opt->devmem, dmixml_n)) found++; // TODO: dmixml_AddAttribute(dmixml_n, "efi_address", "0x%08x", efiAddress); } @@ -297,9 +302,11 @@ xmlNode *__dmidecode_xml_getsection(options *opt, const char *section) { } // Parse the typeid string to a an integer - opt->type = parse_opt_type(typeid); + opt->type = parse_opt_type(opt->logdata, typeid); if(opt->type == -1) { - PyReturnError(PyExc_RuntimeError, "Invalid type id '%s'", typeid); + char *err = log_retrieve(opt->logdata, LOG_ERR); + log_clear_partial(opt->logdata, LOG_ERR, 0); + PyReturnError(PyExc_RuntimeError, "Invalid type id '%s' -- %s", typeid, err); } // Parse the DMI data and put the result into dmixml_n node chain. @@ -647,6 +654,29 @@ static PyObject *dmidecode_set_pythonxmlmap(PyObject * self, PyObject * arg) } +static PyObject * dmidecode_get_warnings(PyObject *self, PyObject *null) +{ + char *warn = NULL; + PyObject *ret = NULL; + + warn = log_retrieve(global_options->logdata, LOG_WARNING); + if( warn ) { + ret = PyString_FromString(warn); + free(warn); + } else { + ret = Py_None; + } + return ret; +} + + +static PyObject * dmidecode_clear_warnings(PyObject *self, PyObject *null) +{ + log_clear_partial(global_options->logdata, LOG_WARNING, 1); + Py_RETURN_TRUE; +} + + static PyMethodDef DMIDataMethods[] = { {(char *)"dump", dmidecode_dump, METH_NOARGS, (char *)"Dump dmidata to set file"}, {(char *)"get_dev", dmidecode_get_dev, METH_NOARGS, @@ -681,6 +711,13 @@ static PyMethodDef DMIDataMethods[] = { {(char *)"xmlapi", dmidecode_xmlapi, METH_KEYWORDS, (char *) "Internal API for retrieving data as raw XML data"}, + + {(char *)"get_warnings", dmidecode_get_warnings, METH_NOARGS, + (char *) "Retrieve warnings from operations"}, + + {(char *)"clear_warnings", dmidecode_clear_warnings, METH_NOARGS, + (char *) "Clear all warnings"}, + {NULL, NULL, 0, NULL} }; @@ -708,6 +745,18 @@ void destruct_options(void *ptr) opt->dumpfile = NULL; } + if( opt->logdata != NULL ) { + char *warn = NULL; + + log_clear_partial(opt->logdata, LOG_WARNING, 0); + warn = log_retrieve(opt->logdata, LOG_WARNING); + if( warn ) { + fprintf(stderr, "\n** COLLECTED WARNINGS **\n%s** END OF WARNINGS **\n\n", warn); + free(warn); + } + log_close(opt->logdata); + } + free(ptr); } diff --git a/src/dmihelper.h b/src/dmihelper.h index 55a2843..8d07feb 100644 --- a/src/dmihelper.h +++ b/src/dmihelper.h @@ -53,6 +53,7 @@ #include #include "types.h" +#include "dmilog.h" #define MAXVAL 1024 @@ -120,6 +121,7 @@ typedef struct _options { char *python_xml_map; xmlNode *dmiversion_n; char *dumpfile; + Log_t *logdata; } options; #endif From 101070880e270118aa1f3992e2734a667dde575e Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 8 Jan 2010 19:26:58 +0100 Subject: [PATCH 060/146] More fprintf() -> log_append() porting --- src/dmidecode.c | 24 ++++++++++++------------ src/dmidecode.h | 5 +++-- src/dmidecodemodule.h | 8 ++++---- src/efi.c | 6 ++++-- src/efi.h | 2 +- src/util.c | 22 ++++++++++------------ src/util.h | 3 ++- 7 files changed, 36 insertions(+), 34 deletions(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index 704294b..0fd8f1b 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -4842,7 +4842,7 @@ dmi_codes_major *find_dmiMajor(const struct dmi_header *h) return NULL; } -static void dmi_table(int type, u32 base, u16 len, u16 num, u16 ver, const char *devmem, xmlNode *xmlnode) +static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver, const char *devmem, xmlNode *xmlnode) { u8 *buf; u8 *data; @@ -4865,10 +4865,10 @@ static void dmi_table(int type, u32 base, u16 len, u16 num, u16 ver, const char info_n = NULL; } - if((buf = mem_chunk(base, len, devmem)) == NULL) { - fprintf(stderr, "Table is unreachable, sorry." + if((buf = mem_chunk(logp, base, len, devmem)) == NULL) { + log_append(logp, LOG_WARNING, "Table is unreachable, sorry." #ifndef USE_MMAP - "Try compiling dmidecode with -DUSE_MMAP."; + "Try compiling dmidecode with -DUSE_MMAP." #endif "\n"); return; @@ -4889,7 +4889,7 @@ static void dmi_table(int type, u32 base, u16 len, u16 num, u16 ver, const char ** table is broken. */ if(h.length < 4) { - fprintf(stderr, "Invalid entry length (%i). DMI table is broken! Stop.", + log_append(logp, LOG_WARNING, "Invalid entry length (%i). DMI table is broken! Stop.", (unsigned int)h.length); break; } @@ -4955,10 +4955,10 @@ static void dmi_table(int type, u32 base, u16 len, u16 num, u16 ver, const char } if(i != num) - fprintf(stderr, "Wrong DMI structures count: %d announced, only %d decoded.\n", num, - i); + log_append(logp, LOG_WARNING, + "Wrong DMI structures count: %d announced, only %d decoded.\n", num, i); if(data - buf != len) - fprintf(stderr, + log_append(logp, LOG_WARNING, "Wrong DMI structures length: %d bytes announced, structures occupy %d bytes.\n", len, (unsigned int)(data - buf)); @@ -5017,7 +5017,7 @@ xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem) return data_n; } -int smbios_decode(int type, u8 *buf, const char *devmem, xmlNode *xmlnode) +int smbios_decode(Log_t *logp, int type, u8 *buf, const char *devmem, xmlNode *xmlnode) { int check = _smbios_decode_check(buf); @@ -5033,7 +5033,7 @@ int smbios_decode(int type, u8 *buf, const char *devmem, xmlNode *xmlnode) 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, + dmi_table(logp, type, DWORD(buf + 0x18), WORD(buf + 0x16), WORD(buf + 0x1C), ver, devmem, xmlnode); } return check; @@ -5072,12 +5072,12 @@ xmlNode *legacy_decode_get_version(u8 * buf, const char *devmem) return data_n; } -int legacy_decode(int type, u8 *buf, const char *devmem, xmlNode *xmlnode) +int legacy_decode(Log_t *logp, 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), + dmi_table(logp, 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 10412c6..926bd5d 100644 --- a/src/dmidecode.h +++ b/src/dmidecode.h @@ -21,6 +21,7 @@ #include #include "dmihelper.h" +#include "dmierror.h" struct dmi_header { u8 type; @@ -35,8 +36,8 @@ void to_dmi_header(struct dmi_header *h, u8 * data); 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 smbios_decode(Log_t *logp, int type, u8 *buf, const char *devmem, xmlNode *xmlnode); +int legacy_decode(Log_t *logp, int type, u8 *buf, const char *devmem, xmlNode *xmlnode); const char *dmi_string(const struct dmi_header *dm, u8 s); void dmi_system_uuid(xmlNode *node, const u8 * p, u16 ver); diff --git a/src/dmidecodemodule.h b/src/dmidecodemodule.h index c0be3a1..3600ba9 100644 --- a/src/dmidecodemodule.h +++ b/src/dmidecodemodule.h @@ -66,12 +66,12 @@ xmlNode *dmidecode_get_version(options *); extern void dmi_dump(xmlNode *node, struct dmi_header *h); -extern int address_from_efi(size_t * address); +extern int address_from_efi(Log_t *logp, 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 int smbios_decode(Log_t *logp, int type, u8 *buf, const char *devmem, xmlNode *node); +extern int legacy_decode(Log_t *logp, 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); +extern void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem); PyMODINIT_FUNC initdmidecode(void); diff --git a/src/efi.c b/src/efi.c index 8c38e38..af0a813 100644 --- a/src/efi.c +++ b/src/efi.c @@ -28,6 +28,8 @@ #include #include #include + +#include "dmilog.h" #include "efi.h" /** @@ -42,7 +44,7 @@ * @param size_t* * @return returns EFI_NOT_FOUND or EFI_NO_SMBIOS */ -int address_from_efi(size_t * address) +int address_from_efi(Log_t *logp, size_t * address) { FILE *efi_systab; const char *filename = NULL; @@ -75,7 +77,7 @@ int address_from_efi(size_t * address) perror(filename); if(ret == EFI_NO_SMBIOS) - fprintf(stderr, "%s: SMBIOS entry point missing\n", filename); + log_append(logp, LOG_WARNING, "%s: SMBIOS entry point missing\n", filename); return ret; } diff --git a/src/efi.h b/src/efi.h index 240fb01..dc03834 100644 --- a/src/efi.h +++ b/src/efi.h @@ -30,6 +30,6 @@ #define EFI_NOT_FOUND (-1) #define EFI_NO_SMBIOS (-2) -int address_from_efi(size_t * address); +int address_from_efi(Log_t *logp, size_t * address); #endif diff --git a/src/util.c b/src/util.c index 9bd86c5..ba1a89a 100644 --- a/src/util.c +++ b/src/util.c @@ -47,9 +47,10 @@ #include "types.h" #include "util.h" +#include "dmilog.h" #ifndef USE_MMAP -static int myread(int fd, u8 * buf, size_t count, const char *prefix) +static int myread(Log_t *logp, int fd, u8 * buf, size_t count, const char *prefix) { ssize_t r = 1; size_t r2 = 0; @@ -68,7 +69,7 @@ static int myread(int fd, u8 * buf, size_t count, const char *prefix) if(r2 != count) { close(fd); - fprintf(stderr, "%s: Unexpected end of file\n", prefix); + log_append(logp, LOG_WARNING, "%s: Unexpected end of file\n", prefix); return -1; } @@ -90,7 +91,7 @@ int checksum(const u8 * buf, size_t len) * Copy a physical memory chunk into a memory buffer. * This function allocates memory. */ -void *mem_chunk(size_t base, size_t len, const char *devmem) +void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem) { void *p; int fd; @@ -101,12 +102,12 @@ void *mem_chunk(size_t base, size_t len, const char *devmem) #endif if((fd = open(devmem, O_RDONLY)) == -1) { - perror(devmem); + log_append(logp, LOG_WARNING, "%s: %s", devmem, strerror(errno)); return NULL; } if((p = malloc(len)) == NULL) { - perror("malloc"); + log_append(logp, LOG_WARNING, "malloc: %s", strerror(errno)); return NULL; } #ifdef USE_MMAP @@ -122,8 +123,7 @@ void *mem_chunk(size_t base, size_t len, const char *devmem) */ mmp = mmap(0, mmoffset + len, PROT_READ, MAP_SHARED, fd, base - mmoffset); if(mmp == MAP_FAILED) { - fprintf(stderr, "%s: ", devmem); - perror("mmap"); + log_append(logp, LOG_WARNING, "%s (mmap): %s", devmem, strerror(errno)); free(p); return NULL; } @@ -131,18 +131,16 @@ void *mem_chunk(size_t base, size_t len, const char *devmem) memcpy(p, (u8 *) mmp + mmoffset, len); if(munmap(mmp, mmoffset + len) == -1) { - fprintf(stderr, "%s: ", devmem); - perror("munmap"); + log_append(logp, LOG_WARNING, "%s (munmap): %s", devmem, strerror(errno)); } #else /* USE_MMAP */ if(lseek(fd, base, SEEK_SET) == -1) { - fprintf(stderr, "%s: ", devmem); - perror("lseek"); + log_append(logp, LOG_WARNING, "%s (lseek): %s", devmem, strerror(errno)); free(p); return NULL; } - if(myread(fd, p, len, devmem) == -1) { + if(myread(logp, fd, p, len, devmem) == -1) { free(p); return NULL; } diff --git a/src/util.h b/src/util.h index 3effd0c..a93af6b 100644 --- a/src/util.h +++ b/src/util.h @@ -22,9 +22,10 @@ #include #include "types.h" +#include "dmilog.h" #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) int checksum(const u8 * buf, size_t len); -void *mem_chunk(size_t base, size_t len, const char *devmem); +void *mem_chunk(Log_t *logp, 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); From 8462924ea831699ad3e5a2e6c25add902cf11bad Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 8 Jan 2010 19:27:35 +0100 Subject: [PATCH 061/146] Port dmidump to use the new log API This port will not create a new log buffer (Log_t), but log_append() will print errors to stderr in this case, as the log buffer pointer is NULL. --- Makefile | 4 ++-- src/dmidump.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index fce6c72..1d82922 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ $(PY)-dmidecodemod.so: $(SO) $(SO): $(PY) src/setup.py build -dmidump : src/util.o src/efi.o +dmidump : src/util.o src/efi.o src/dmilog.o $(CC) -o $@ src/dmidump.c $^ -g -Wall -D_DMIDUMP_MAIN_ install: @@ -35,7 +35,7 @@ uninstall: clean: -$(PY) src/setup.py clean --all - -rm -f *.so lib/*.o core dmidump + -rm -f *.so lib/*.o core dmidump src/*.o -rm -rf build -rm -rf rpm -rm -rf src/setup_common.py[oc] diff --git a/src/dmidump.c b/src/dmidump.c index 641b937..fc67481 100644 --- a/src/dmidump.c +++ b/src/dmidump.c @@ -109,7 +109,7 @@ int dumpling(u8 * buf, const char *dumpfile, u8 mode) u8 *buff; - if((buff = mem_chunk(base, len, DEFAULT_MEM_DEV)) != NULL) { + if((buff = mem_chunk(NULL, base, len, DEFAULT_MEM_DEV)) != NULL) { //. Part 1. #ifdef NDEBUG printf("# Writing %d bytes to %s.\n", len, dumpfile); @@ -156,10 +156,10 @@ int dump(const char *memdev, const char *dumpfile) u8 *buf; /* First try EFI (ia64, Intel-based Mac) */ - efi = address_from_efi(&fp); + efi = address_from_efi(NULL, &fp); if(efi == EFI_NOT_FOUND) { /* Fallback to memory scan (x86, x86_64) */ - if((buf = mem_chunk(0xF0000, 0x10000, memdev)) != NULL) { + if((buf = mem_chunk(NULL, 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)) @@ -175,7 +175,7 @@ int dump(const char *memdev, const char *dumpfile) } else if(efi == EFI_NO_SMBIOS) { ret = -1; } else { - if((buf = mem_chunk(fp, 0x20, memdev)) == NULL) + if((buf = mem_chunk(NULL, fp, 0x20, memdev)) == NULL) ret = -1; else if(dumpling(buf, dumpfile, NON_LEGACY)) found++; From ba6c5a8be14d309955640bac1c14580e6ca61bee Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 8 Jan 2010 19:28:43 +0100 Subject: [PATCH 062/146] Update Python build rules --- src/setup-dbg.py | 1 + src/setup.py | 1 + 2 files changed, 2 insertions(+) diff --git a/src/setup-dbg.py b/src/setup-dbg.py index b91e3e0..9bbeb21 100644 --- a/src/setup-dbg.py +++ b/src/setup-dbg.py @@ -67,6 +67,7 @@ "src/dmidecode.c", "src/dmixml.c", "src/dmierror.c", + "src/dmilog.c", "src/xmlpythonizer.c", "src/efi.c", "src/dmidump.c" diff --git a/src/setup.py b/src/setup.py index b65957c..aecad71 100644 --- a/src/setup.py +++ b/src/setup.py @@ -67,6 +67,7 @@ "src/dmidecode.c", "src/dmixml.c", "src/dmierror.c", + "src/dmilog.c", "src/xmlpythonizer.c", "src/efi.c", "src/dmidump.c" From 24af40698f1486c899333ea1f129e87590cdee7e Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 8 Jan 2010 19:56:21 +0100 Subject: [PATCH 063/146] Ported fprintf() -> log_append() on XML functions --- src/dmidecodemodule.c | 10 ++-- src/dmixml.c | 9 ++-- src/dmixml.h | 2 +- src/xmlpythonizer.c | 108 +++++++++++++++++++++++------------------- src/xmlpythonizer.h | 8 ++-- 5 files changed, 74 insertions(+), 63 deletions(-) diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 61e3b9a..93a956b 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -44,11 +44,11 @@ #include #include "libxml_wrap.h" -#include "xmlpythonizer.h" #include "dmidecodemodule.h" #include "dmixml.h" #include "dmierror.h" #include "dmilog.h" +#include "xmlpythonizer.h" #include "version.h" #include "dmidump.h" #include @@ -343,7 +343,7 @@ static PyObject *dmidecode_get_group(options *opt, const char *section) } // Convert the retrieved XML nodes to a Python dictionary - mapping = dmiMAP_ParseMappingXML_GroupName(opt->mappingxml, section); + mapping = dmiMAP_ParseMappingXML_GroupName(opt->logdata, opt->mappingxml, section); if( mapping == NULL ) { // Exception already set xmlFreeNode(dmixml_n); @@ -351,7 +351,7 @@ static PyObject *dmidecode_get_group(options *opt, const char *section) } // Generate Python dict out of XML node - pydata = pythonizeXMLnode(mapping, dmixml_n); + pydata = pythonizeXMLnode(opt->logdata, mapping, dmixml_n); // Clean up and return the resulting Python dictionary ptzmap_Free(mapping); @@ -406,7 +406,7 @@ static PyObject *dmidecode_get_typeid(options *opt, int typeid) } // Convert the retrieved XML nodes to a Python dictionary - mapping = dmiMAP_ParseMappingXML_TypeID(opt->mappingxml, opt->type); + mapping = dmiMAP_ParseMappingXML_TypeID(opt->logdata, opt->mappingxml, opt->type); if( mapping == NULL ) { // FIXME: Should we raise an exception here? // Now it passes the unit-test @@ -414,7 +414,7 @@ static PyObject *dmidecode_get_typeid(options *opt, int typeid) } // Generate Python dict out of XML node - pydata = pythonizeXMLnode(mapping, dmixml_n); + pydata = pythonizeXMLnode(opt->logdata, mapping, dmixml_n); // Clean up and return the resulting Python dictionary ptzmap_Free(mapping); diff --git a/src/dmixml.c b/src/dmixml.c index 5d9f1a1..6f1fd77 100644 --- a/src/dmixml.c +++ b/src/dmixml.c @@ -41,6 +41,7 @@ #include #include +#include "dmilog.h" #include "dmixml.h" /** @@ -323,7 +324,7 @@ inline char *dmixml_GetNodeContent(xmlNode *node, const char *key) { * 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) { +char *dmixml_GetXPathContent(Log_t *logp, char *buf, size_t buflen, xmlXPathObject *xpo, int idx) { memset(buf, 0, buflen); if( xpo == NULL ) { @@ -351,9 +352,9 @@ char *dmixml_GetXPathContent(char *buf, size_t buflen, xmlXPathObject *xpo, int break; default: - fprintf(stderr, "dmixml_GetXPathContent(...):: " - "Do not know how to handle XPath type %i\n", - xpo->type); + log_append(logp, LOG_WARNING, "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 index 3dc32e5..7bbbb76 100644 --- a/src/dmixml.h +++ b/src/dmixml.h @@ -74,6 +74,6 @@ xmlNode *__dmixml_FindNodeByAttr(xmlNode *, const char *, const char *, const ch 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); +char *dmixml_GetXPathContent(Log_t *logp, char *buf, size_t buflen, xmlXPathObject *xpo, int idx); #endif diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index c4c6cb7..8596a9d 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -82,6 +82,7 @@ #include "util.h" #include "dmixml.h" #include "dmierror.h" +#include "dmilog.h" #include "xmlpythonizer.h" #include "version.h" @@ -279,7 +280,7 @@ void ptzmap_Dump_func(const ptzMAP *ptr, int level) * @param const char* String value containing the key/value type * @return ptzTYPES The type value */ -inline ptzTYPES _convert_maptype(const char *str) { +inline ptzTYPES _convert_maptype(Log_t *logp, const char *str) { if( strcmp(str, "string") == 0 ) { return ptzSTR; } else if( strcmp(str, "constant") == 0 ) { @@ -303,7 +304,8 @@ inline ptzTYPES _convert_maptype(const char *str) { } else if( strcmp(str, "list:dict") == 0 ) { return ptzLIST_DICT; } else { - fprintf(stderr, "Unknown field type: %s - defaulting to 'constant'\n", str); + log_append(logp, LOG_WARNING, + "Unknown field type: %s - defaulting to 'constant'\n", str); return ptzCONST; } } @@ -315,7 +317,7 @@ inline ptzTYPES _convert_maptype(const char *str) { * @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 *_do_dmimap_parsing_typeid(Log_t *logp, xmlNode *node) { ptzMAP *retmap = NULL; xmlNode *ptr_n = NULL, *map_n = NULL;; @@ -352,10 +354,10 @@ ptzMAP *_do_dmimap_parsing_typeid(xmlNode *node) { // Get the attributes defining key, keytype, value and valuetype key = dmixml_GetAttrValue(ptr_n, "key"); - type_key = _convert_maptype(dmixml_GetAttrValue(ptr_n, "keytype")); + type_key = _convert_maptype(logp, dmixml_GetAttrValue(ptr_n, "keytype")); value = dmixml_GetAttrValue(ptr_n, "value"); - type_value = _convert_maptype(dmixml_GetAttrValue(ptr_n, "valuetype")); + type_value = _convert_maptype(logp, dmixml_GetAttrValue(ptr_n, "valuetype")); rootpath = dmixml_GetAttrValue(ptr_n, "rootpath"); @@ -374,7 +376,7 @@ ptzMAP *_do_dmimap_parsing_typeid(xmlNode *node) { // 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)); + _do_dmimap_parsing_typeid(logp, ptr_n->children->next)); } else { char *tmpstr = NULL; @@ -452,7 +454,7 @@ xmlNode *dmiMAP_GetRootElement(xmlDoc *mapdoc) { * @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) { +ptzMAP *_dmimap_parse_mapping_node_typeid(Log_t *logp, xmlNode *mapnode, const char *typeid) { xmlNode *node = NULL; assert( mapnode != NULL); @@ -461,12 +463,12 @@ ptzMAP *_dmimap_parse_mapping_node_typeid(xmlNode *mapnode, const char *typeid) 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); + log_append(logp, LOG_WARNING, "** 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); + return _do_dmimap_parsing_typeid(logp, node); } @@ -477,7 +479,7 @@ ptzMAP *_dmimap_parse_mapping_node_typeid(xmlNode *mapnode, const char *typeid) * @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) { +ptzMAP *dmiMAP_ParseMappingXML_TypeID(Log_t *logp, xmlDoc *xmlmap, int typeid) { xmlNode *node = NULL; char typeid_s[16]; @@ -492,7 +494,7 @@ ptzMAP *dmiMAP_ParseMappingXML_TypeID(xmlDoc *xmlmap, int typeid) { // Find the section node = dmixml_FindNode(node, "TypeMapping"); assert( node != NULL ); - return _dmimap_parse_mapping_node_typeid(node, typeid_s); + return _dmimap_parse_mapping_node_typeid(logp, node, typeid_s); } @@ -505,7 +507,7 @@ ptzMAP *dmiMAP_ParseMappingXML_TypeID(xmlDoc *xmlmap, int typeid) { * @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 *_do_dmimap_parsing_group(Log_t *logp, xmlNode *node, xmlDoc *xmlmap) { ptzMAP *retmap = NULL; xmlNode *ptr_n = NULL, *map_n = NULL, *typemap = NULL; char *type_id; @@ -548,7 +550,7 @@ ptzMAP *_do_dmimap_parsing_group(xmlNode *node, xmlDoc *xmlmap) { if( (type_id = dmixml_GetAttrValue(ptr_n, "id")) != NULL) { ptzMAP *map = NULL; - map = _dmimap_parse_mapping_node_typeid(typemap, type_id); + map = _dmimap_parse_mapping_node_typeid(logp, typemap, type_id); if( map ) { retmap = ptzmap_AppendMap(retmap, map); } @@ -566,7 +568,7 @@ ptzMAP *_do_dmimap_parsing_group(xmlNode *node, xmlDoc *xmlmap) { * @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) { +ptzMAP *dmiMAP_ParseMappingXML_GroupName(Log_t *logp, xmlDoc *xmlmap, const char *mapname) { xmlNode *node = NULL; // Validate the XML mapping document and get the root element @@ -589,7 +591,7 @@ ptzMAP *dmiMAP_ParseMappingXML_GroupName(xmlDoc *xmlmap, const char *mapname) { } // Create an internal map structure and return this structure - return _do_dmimap_parsing_group(node, xmlmap); + return _do_dmimap_parsing_group(logp, node, xmlmap); } @@ -600,7 +602,7 @@ ptzMAP *dmiMAP_ParseMappingXML_GroupName(xmlDoc *xmlmap, const char *mapname) { * @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) { +inline PyObject *StringToPyObj(Log_t *logp, ptzMAP *val_m, const char *instr) { PyObject *value; const char *workstr = NULL; @@ -663,7 +665,9 @@ inline PyObject *StringToPyObj(ptzMAP *val_m, const char *instr) { break; default: - fprintf(stderr, "Invalid type '%i' for value '%s'\n", val_m->type_value, instr); + log_append(logp, LOG_WARNING, + "Invalid type '%i' for value '%s'\n", + val_m->type_value, instr); value = Py_None; } return value; @@ -706,7 +710,9 @@ xmlXPathObject *_get_xpath_values(xmlXPathContext *xpctx, const char *xpath) { * @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) { +char *_get_key_value(Log_t *logp, char *key, size_t buflen, + ptzMAP *map_p, xmlXPathContext *xpctx, int idx) +{ xmlXPathObject *xpobj = NULL; memset(key, 0, buflen); @@ -723,7 +729,7 @@ char *_get_key_value(char *key, size_t buflen, ptzMAP *map_p, xmlXPathContext *x if( xpobj == NULL ) { return NULL; } - if( dmixml_GetXPathContent(key, buflen, xpobj, idx) == NULL ) { + if( dmixml_GetXPathContent(logp, key, buflen, xpobj, idx) == NULL ) { xmlXPathFreeObject(xpobj); return NULL; } @@ -731,7 +737,7 @@ char *_get_key_value(char *key, size_t buflen, ptzMAP *map_p, xmlXPathContext *x break; default: - fprintf(stderr, "Unknown key type: %i\n", map_p->type_key); + log_append(logp, LOG_WARNING, "Unknown key type: %i\n", map_p->type_key); return NULL; } // We consider to have a key, if the first byte is a readable @@ -765,7 +771,7 @@ char *_get_key_value(char *key, size_t buflen, ptzMAP *map_p, xmlXPathContext *x * @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) { +inline void _add_xpath_result(Log_t *logp, PyObject *pydat, xmlXPathContext *xpctx, ptzMAP *map_p, xmlXPathObject *value) { int i = 0; char *key = NULL; char *val = NULL; @@ -784,22 +790,22 @@ inline void _add_xpath_result(PyObject *pydat, xmlXPathContext *xpctx, ptzMAP *m break; } if( value->nodesetval->nodeNr == 0 ) { - if( _get_key_value(key, 256, map_p, xpctx, 0) != NULL ) { + if( _get_key_value(logp, 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)); + if( _get_key_value(logp, key, 256, map_p, xpctx, i) != NULL ) { + dmixml_GetXPathContent(logp, val, 4097, value, i); + PyADD_DICT_VALUE(pydat, key, StringToPyObj(logp, 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)); + if( _get_key_value(logp, key, 256, map_p, xpctx, 0) != NULL ) { + dmixml_GetXPathContent(logp, val, 4097, value, 0); + PyADD_DICT_VALUE(pydat, key, StringToPyObj(logp, map_p, val)); } break; } @@ -819,7 +825,9 @@ inline void _add_xpath_result(PyObject *pydat, xmlXPathContext *xpctx, ptzMAP *m * @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) { +PyObject *_deep_pythonize(Log_t *logp, PyObject *retdata, + ptzMAP *map_p, xmlNode *data_n, int elmtid) +{ char *key = NULL; xmlXPathContext *xpctx = NULL; xmlDoc *xpdoc = NULL; @@ -841,7 +849,7 @@ PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int // Extract value switch( map_p->type_value ) { case ptzCONST: - if( _get_key_value(key, 256, map_p, xpctx, 0) != NULL ) { + if( _get_key_value(logp, key, 256, map_p, xpctx, 0) != NULL ) { value = PyString_FromString(map_p->value); PyADD_DICT_VALUE(retdata, key, value); } else { @@ -856,7 +864,7 @@ PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int case ptzBOOL: xpo = _get_xpath_values(xpctx, map_p->value); if( xpo != NULL ) { - _add_xpath_result(retdata, xpctx, map_p, xpo); + _add_xpath_result(logp, retdata, xpctx, map_p, xpo); xmlXPathFreeObject(xpo); } break; @@ -867,7 +875,7 @@ PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int 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( _get_key_value(logp, key, 256, map_p, xpctx, 0) != NULL ) { if( (xpo->nodesetval != NULL) && (xpo->nodesetval->nodeNr > 0) ) { value = PyList_New(0); @@ -883,7 +891,7 @@ PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int for( i = 0; i < xpo->nodesetval->nodeNr; i++ ) { char *valstr = NULL; valstr = (char *) malloc(4098); - dmixml_GetXPathContent(valstr, 4097, xpo, i); + dmixml_GetXPathContent(logp, 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) ) { @@ -893,12 +901,13 @@ PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int map_p->list_index); if( idx != NULL ) { PyList_SetItem(value, atoi(idx)-1, - StringToPyObj(map_p, valstr) + StringToPyObj(logp, + map_p, valstr) ); } } else { // No list index - append the value - PyList_Append(value, StringToPyObj(map_p, valstr)); + PyList_Append(value,StringToPyObj(logp,map_p,valstr)); } free(valstr); } @@ -920,13 +929,13 @@ PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int if( map_p->child == NULL ) { break; } - if( _get_key_value(key, 256, map_p, xpctx, 0) == NULL ) { + if( _get_key_value(logp, 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); + value = pythonizeXMLnode(logp, map_p->child, data_n); PyADD_DICT_VALUE(retdata, key, (value != NULL ? value : Py_None)); break; @@ -934,7 +943,7 @@ PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int if( map_p->child == NULL ) { break; } - if( _get_key_value(key, 256, map_p, xpctx, 0) == NULL ) { + if( _get_key_value(logp, 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); @@ -966,7 +975,7 @@ PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int for( i = 0; i < xpo->nodesetval->nodeNr; i++ ) { PyObject *dataset = NULL; - dataset = pythonizeXMLnode(map_p->child, xpo->nodesetval->nodeTab[i]); + dataset = pythonizeXMLnode(logp, 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) ) { @@ -990,7 +999,7 @@ PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int break; default: - fprintf(stderr, "Unknown value type: %i\n", map_p->type_value); + log_append(logp, LOG_WARNING, "Unknown value type: %i\n", map_p->type_value); break; } @@ -1007,7 +1016,7 @@ PyObject *_deep_pythonize(PyObject *retdata, ptzMAP *map_p, xmlNode *data_n, int * @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) { +PyObject *pythonizeXMLnode(Log_t *logp, ptzMAP *in_map, xmlNode *data_n) { xmlXPathContext *xpctx = NULL; xmlDoc *xpdoc = NULL; PyObject *retdata = NULL; @@ -1046,8 +1055,8 @@ PyObject *pythonizeXMLnode(ptzMAP *in_map, xmlNode *data_n) { 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, + if( _get_key_value(logp, key, 256, map_p, xpctx, 0) != NULL ) { + PyObject *res = _deep_pythonize(logp, retdata, map_p, xpo->nodesetval->nodeTab[i], i); if( res == NULL ) { // Exit if we get NULL - something is wrong @@ -1061,15 +1070,16 @@ PyObject *pythonizeXMLnode(ptzMAP *in_map, xmlNode *data_n) { } #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); + log_append(logp, LOG_WARNING, + "** 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); + PyObject *res = _deep_pythonize(logp, retdata, map_p, data_n, 0); if( res == NULL ) { // Exit if we get NULL - something is wrong //and exception is set @@ -1088,12 +1098,12 @@ PyObject *pythonizeXMLnode(ptzMAP *in_map, xmlNode *data_n) { * @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) +PyObject *pythonizeXMLdoc(Log_t *logp, ptzMAP *map, xmlDoc *doc) { xmlNode *node = NULL; node = xmlDocGetRootElement(doc); - return pythonizeXMLnode(map, node); + return pythonizeXMLnode(logp, map, node); } diff --git a/src/xmlpythonizer.h b/src/xmlpythonizer.h index df60140..e6c58bc 100644 --- a/src/xmlpythonizer.h +++ b/src/xmlpythonizer.h @@ -49,12 +49,12 @@ typedef struct ptzMAP_s { } ptzMAP; xmlNode *dmiMAP_GetRootElement(xmlDoc *mapdoc); -ptzMAP *dmiMAP_ParseMappingXML_TypeID(xmlDoc *xmlmap, int typeid); -ptzMAP *dmiMAP_ParseMappingXML_GroupName(xmlDoc *xmlmap, const char *mapname); +ptzMAP *dmiMAP_ParseMappingXML_TypeID(Log_t *logp, xmlDoc *xmlmap, int typeid); +ptzMAP *dmiMAP_ParseMappingXML_GroupName(Log_t *logp, 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); +PyObject *pythonizeXMLdoc(Log_t *logp, ptzMAP *map, xmlDoc *xmldoc); +PyObject *pythonizeXMLnode(Log_t *logp, ptzMAP *map, xmlNode *nodes); #endif // _XMLPYTHONIZER_H From 3a749b795b77da66294d8651ee7c091d41664cc0 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Tue, 12 Jan 2010 12:00:59 +1100 Subject: [PATCH 064/146] New upstream release (v3.10.10) --- contrib/python-dmidecode.spec | 5 ++++- debian/changelog | 15 +++++++++++---- src/version.h | 2 +- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/contrib/python-dmidecode.spec b/contrib/python-dmidecode.spec index d01e831..0154dcc 100644 --- a/contrib/python-dmidecode.spec +++ b/contrib/python-dmidecode.spec @@ -3,7 +3,7 @@ Summary: Python module to access DMI data Name: python-dmidecode -Version: 3.10.9 +Version: 3.10.10 Release: 1%{?dist} License: GPLv2 Group: System Environment/Libraries @@ -49,6 +49,9 @@ rm -rf $RPM_BUILD_ROOT %{_datadir}/python-dmidecode/ %changelog +* Tue Jan 12 2010 Nima Talebi - 3.10.10-1 +- Update to new release + * Thu Jan 07 2010 Nima Talebi - 3.10.9-1 - Update to new release diff --git a/debian/changelog b/debian/changelog index 795079b..2e3f427 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,10 +1,17 @@ -python-dmidecode (3.10.9-1) lucid; urgency=low +python-dmidecode (3.10.10-1) unstable; urgency=low + + * New upstream cleanup release. + * This release has addressed the previously messy error/warning handling. + + -- Nima Talebi Tue, 12 Jan 2010 11:59:27 +1100 + +python-dmidecode (3.10.9-1) unstable; urgency=low * New upstream bug-fix release. * Add --install-layout=deb to debian/rules setup.py install to prevent files - from landing in /usr/local (Closes: Bug#563883). - - -- Scott Kitterman Tue, 05 Jan 2010 22:02:29 -0500 + from landing in /usr/local (Closes: Bug#563883) - thanks to Scott + Kitterman. + -- Nima Talebi Tue, 05 Jan 2010 22:02:29 -0500 python-dmidecode (3.10.8-2) unstable; urgency=low diff --git a/src/version.h b/src/version.h index eef20b6..bbc59e6 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define VERSION "3.10.9" +#define VERSION "3.10.10" From 5ebf67efee2893c4d3dc60ec31a0efeb0894d245 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 5 Feb 2010 15:33:39 +0100 Subject: [PATCH 065/146] Added logging flag to log_append() to change log behaviour Valid flags are: * LOGFL_NORMAL Log all messages to the log context, and send log message to stderr on errors * LOGFL_NODUPS Log only unique messages. Duplicated messages will be removed * LOGFL_NOSTDERR Don't write to stderr, even if errors occur --- src/dmidecode.c | 11 +++--- src/dmidecodemodule.c | 13 ++++--- src/dmilog.c | 79 +++++++++++++++++++++++-------------------- src/dmilog.h | 10 +++++- src/dmixml.c | 6 ++-- src/efi.c | 5 +-- src/util.c | 12 +++---- src/xmlpythonizer.c | 12 +++---- 8 files changed, 83 insertions(+), 65 deletions(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index 0fd8f1b..a29a743 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -4866,7 +4866,7 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver } if((buf = mem_chunk(logp, base, len, devmem)) == NULL) { - log_append(logp, LOG_WARNING, "Table is unreachable, sorry." + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Table is unreachable, sorry." #ifndef USE_MMAP "Try compiling dmidecode with -DUSE_MMAP." #endif @@ -4889,8 +4889,9 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver ** table is broken. */ if(h.length < 4) { - log_append(logp, LOG_WARNING, "Invalid entry length (%i). DMI table is broken! Stop.", - (unsigned int)h.length); + log_append(logp, LOGFL_NORMAL, LOG_WARNING, + "Invalid entry length (%i). DMI table is broken! Stop.", + (unsigned int)h.length); break; } @@ -4955,10 +4956,10 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver } if(i != num) - log_append(logp, LOG_WARNING, + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Wrong DMI structures count: %d announced, only %d decoded.\n", num, i); if(data - buf != len) - log_append(logp, LOG_WARNING, + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Wrong DMI structures length: %d bytes announced, structures occupy %d bytes.\n", len, (unsigned int)(data - buf)); diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 93a956b..dc00279 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -66,7 +66,8 @@ static void init(options *opt) /* sanity check */ if(sizeof(u8) != 1 || sizeof(u16) != 2 || sizeof(u32) != 4 || '\0' != 0) { - log_append(opt->logdata, LOG_WARNING, "%s: compiler incompatibility\n", "dmidecodemodule"); + log_append(opt->logdata, LOGFL_NORMAL, LOG_WARNING, + "%s: compiler incompatibility\n", "dmidecodemodule"); } } @@ -78,11 +79,11 @@ int parse_opt_type(Log_t *logp, const char *arg) val = strtoul(arg, &next, 0); if(next == arg) { - log_append(logp, LOG_ERR, "Invalid type keyword: %s\n", arg); + log_append(logp, LOGFL_NODUPS, LOG_ERR, "Invalid type keyword: %s\n", arg); return -1; } if(val > 0xff) { - log_append(logp, LOG_ERR, "Invalid type number: %i\n", val); + log_append(logp, LOGFL_NODUPS, LOG_ERR, "Invalid type number: %i\n", val); return -1; } @@ -164,7 +165,8 @@ xmlNode *dmidecode_get_version(options *opt) free(buf); } if( !found ) { - log_append(opt->logdata, LOG_WARNING, "No SMBIOS nor DMI entry point found, sorry."); + log_append(opt->logdata, LOGFL_NODUPS, LOG_WARNING, + "No SMBIOS nor DMI entry point found, sorry."); } return ver_n; } @@ -185,7 +187,8 @@ int dmidecode_get_xml(options *opt, xmlNode* dmixml_n) const char *f = opt->dumpfile ? opt->dumpfile : opt->devmem; if(access(f, R_OK) < 0) { - log_append(opt->logdata, LOG_WARNING, "Permission denied to memory file/device (%s)", f); + log_append(opt->logdata, LOGFL_NORMAL, + LOG_WARNING, "Permission denied to memory file/device (%s)", f); return 0; } diff --git a/src/dmilog.c b/src/dmilog.c index e9b89e8..f7ade5d 100644 --- a/src/dmilog.c +++ b/src/dmilog.c @@ -59,51 +59,56 @@ Log_t * log_init() * Registers a new log entry * * @param logp Pointer to an allocated Log_t record. New records will be appended to the end + * @param flags Log flags, to specify logging behaviour * @param level syslog log level values. LOG_ERR and LOG_WARNING are allowed * @param fmt stdarg based string with the log contents * * @return Returns 1 on successful registration of log entry, otherwise -1 and error is printed to stderr + * unless LOGFL_NOSTDERR is set in flags. */ -int log_append(Log_t *logp, int level, const char *fmt, ...) +int log_append(Log_t *logp, Log_f flags, int level, const char *fmt, ...) { - Log_t *ptr = NULL; - va_list ap; - - // Go the end of the record chain - ptr = logp; - while( ptr && ptr->next ) { - ptr = ptr->next; - } - - - if( ptr && ((level == LOG_ERR) || (level == LOG_WARNING)) ) { - ptr->next = log_init(); - if( ptr->next ) { - ptr->next->message = (char *) calloc(1, 4098); - } - } + Log_t *ptr = NULL; + va_list ap; + char logmsg[4098]; + // Prepare log message + memset(&logmsg, 0, 4098); va_start(ap, fmt); - if( !ptr || !ptr->next || !ptr->next->message ) { - if( logp ) { - // Only print this if we logp is pointing somewhere. - // If it is NULL, the caller did not establish a log - // buffer on purpose (like dmidump.c) - thus this is - // not an error with saving the log entry. - fprintf(stderr, "** ERROR ** Failed to save log entry\n"); - } - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - va_end(ap); - return -1; - } - - ptr->next->level = level; - vsnprintf(ptr->next->message, 4096, fmt, ap); - ptr->next->message = realloc(ptr->next->message, strlen(ptr->next->message)+2); - va_end(ap); - - return 1; + vsnprintf(logmsg, 4096, fmt, ap); + va_end(ap); + + // Go the end of the record chain + ptr = logp; + while( ptr && ptr->next ) { + // Ignore duplicated messages if LOGFL_NODUPS is set + if( (flags & LOGFL_NODUPS) && ptr->next && ptr->next->message + && (strcmp(ptr->next->message, logmsg) == 0) ) { + return 1; + } + ptr = ptr->next; + } + + if( ptr && ((level == LOG_ERR) || (level == LOG_WARNING)) ) { + ptr->next = log_init(); + if( ptr->next ) { + ptr->next->level = level; + ptr->next->message = strdup(logmsg); + return 1; + } + } + + if( !(flags & LOGFL_NOSTDERR) ) { + if( logp ) { + // Only print this if we logp is pointing somewhere. + // If it is NULL, the caller did not establish a log + // buffer on purpose (like dmidump.c) - thus this is + // not an error with saving the log entry. + fprintf(stderr, "** ERROR ** Failed to save log entry\n"); + } + fprintf(stderr, "%s\n", logmsg); + } + return -1; } diff --git a/src/dmilog.h b/src/dmilog.h index 98d0780..76c87b6 100644 --- a/src/dmilog.h +++ b/src/dmilog.h @@ -46,8 +46,16 @@ struct _Log_t { }; typedef struct _Log_t Log_t; +/** + * Log flags. These flags can be OR'ed together + */ +typedef enum { LOGFL_NORMAL = 1, /**< Normal behaviour, log everything and use stderr on errors */ + LOGFL_NODUPS = 2, /**< Don't log messages we already have logged */ + LOGFL_NOSTDERR = 4 /**< Don't use stderr even if log functions fails */ +} Log_f; + Log_t * log_init(); -int log_append(Log_t *logp, int level, const char *fmt, ...); +int log_append(Log_t *logp, Log_f flags, int level, const char *fmt, ...); char * log_retrieve(Log_t *logp, int level); size_t log_clear_partial(Log_t *logp, int level, int unread); void log_close(Log_t *logp); diff --git a/src/dmixml.c b/src/dmixml.c index 6f1fd77..6f6aa60 100644 --- a/src/dmixml.c +++ b/src/dmixml.c @@ -352,9 +352,9 @@ char *dmixml_GetXPathContent(Log_t *logp, char *buf, size_t buflen, xmlXPathObje break; default: - log_append(logp, LOG_WARNING, "dmixml_GetXPathContent(...):: " - "Do not know how to handle XPath type %i\n", - xpo->type); + log_append(logp, LOGFL_NORMAL, LOG_WARNING, "dmixml_GetXPathContent(...):: " + "Do not know how to handle XPath type %i\n", + xpo->type); return NULL; } return buf; diff --git a/src/efi.c b/src/efi.c index af0a813..171ae30 100644 --- a/src/efi.c +++ b/src/efi.c @@ -76,8 +76,9 @@ int address_from_efi(Log_t *logp, size_t * address) if(fclose(efi_systab) != 0) perror(filename); - if(ret == EFI_NO_SMBIOS) - log_append(logp, LOG_WARNING, "%s: SMBIOS entry point missing\n", filename); + if(ret == EFI_NO_SMBIOS) { + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "%s: SMBIOS entry point missing\n", filename); + } return ret; } diff --git a/src/util.c b/src/util.c index ba1a89a..f0d9f93 100644 --- a/src/util.c +++ b/src/util.c @@ -69,7 +69,7 @@ static int myread(Log_t *logp, int fd, u8 * buf, size_t count, const char *prefi if(r2 != count) { close(fd); - log_append(logp, LOG_WARNING, "%s: Unexpected end of file\n", prefix); + log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s: Unexpected end of file\n", prefix); return -1; } @@ -102,12 +102,12 @@ void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem) #endif if((fd = open(devmem, O_RDONLY)) == -1) { - log_append(logp, LOG_WARNING, "%s: %s", devmem, strerror(errno)); + log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s: %s", devmem, strerror(errno)); return NULL; } if((p = malloc(len)) == NULL) { - log_append(logp, LOG_WARNING, "malloc: %s", strerror(errno)); + log_append(logp, LOGFL_NORMAL, LOG_WARNING, "malloc: %s", strerror(errno)); return NULL; } #ifdef USE_MMAP @@ -123,7 +123,7 @@ void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem) */ mmp = mmap(0, mmoffset + len, PROT_READ, MAP_SHARED, fd, base - mmoffset); if(mmp == MAP_FAILED) { - log_append(logp, LOG_WARNING, "%s (mmap): %s", devmem, strerror(errno)); + log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s (mmap): %s", devmem, strerror(errno)); free(p); return NULL; } @@ -131,11 +131,11 @@ void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem) memcpy(p, (u8 *) mmp + mmoffset, len); if(munmap(mmp, mmoffset + len) == -1) { - log_append(logp, LOG_WARNING, "%s (munmap): %s", devmem, strerror(errno)); + log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s (munmap): %s", devmem, strerror(errno)); } #else /* USE_MMAP */ if(lseek(fd, base, SEEK_SET) == -1) { - log_append(logp, LOG_WARNING, "%s (lseek): %s", devmem, strerror(errno)); + log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s (lseek): %s", devmem, strerror(errno)); free(p); return NULL; } diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index 8596a9d..5342bac 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -304,7 +304,7 @@ inline ptzTYPES _convert_maptype(Log_t *logp, const char *str) { } else if( strcmp(str, "list:dict") == 0 ) { return ptzLIST_DICT; } else { - log_append(logp, LOG_WARNING, + log_append(logp, LOGFL_NORMAL, LOG_WARNING, "Unknown field type: %s - defaulting to 'constant'\n", str); return ptzCONST; } @@ -463,7 +463,7 @@ ptzMAP *_dmimap_parse_mapping_node_typeid(Log_t *logp, xmlNode *mapnode, const c node = dmixml_FindNodeByAttr_NoCase(mapnode, "TypeMap", "id", typeid); if( node == NULL ) { // No exception handling possible here, as we don't return PyObject - log_append(logp, LOG_WARNING, "** WARNING: Could not find any XML->Python " + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "** WARNING: Could not find any XML->Python " "mapping for type ID '%s'", typeid); return NULL; } @@ -665,7 +665,7 @@ inline PyObject *StringToPyObj(Log_t *logp, ptzMAP *val_m, const char *instr) { break; default: - log_append(logp, LOG_WARNING, + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Invalid type '%i' for value '%s'\n", val_m->type_value, instr); value = Py_None; @@ -737,7 +737,7 @@ char *_get_key_value(Log_t *logp, char *key, size_t buflen, break; default: - log_append(logp, LOG_WARNING, "Unknown key type: %i\n", map_p->type_key); + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Unknown key type: %i\n", map_p->type_key); return NULL; } // We consider to have a key, if the first byte is a readable @@ -999,7 +999,7 @@ PyObject *_deep_pythonize(Log_t *logp, PyObject *retdata, break; default: - log_append(logp, LOG_WARNING, "Unknown value type: %i\n", map_p->type_value); + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Unknown value type: %i\n", map_p->type_value); break; } @@ -1070,7 +1070,7 @@ PyObject *pythonizeXMLnode(Log_t *logp, ptzMAP *in_map, xmlNode *data_n) { } #ifdef DEBUG else { - log_append(logp, LOG_WARNING, + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "** pythonizeXMLnode :: Could not locate node for key value: " "root path '%s', key '%s'\n", map_p->rootpath, map_p->key); } From 5abd4b52f056ba09b1c134870586393a223ccc79 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 5 Feb 2010 18:16:43 +0100 Subject: [PATCH 066/146] Removed not needed \n from log_append() entries --- src/dmidecode.c | 6 +++--- src/dmidecodemodule.c | 6 +++--- src/dmixml.c | 2 +- src/efi.c | 2 +- src/util.c | 2 +- src/xmlpythonizer.c | 10 +++++----- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index a29a743..e64d12f 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -4870,7 +4870,7 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver #ifndef USE_MMAP "Try compiling dmidecode with -DUSE_MMAP." #endif - "\n"); + ); return; } @@ -4957,10 +4957,10 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver if(i != num) log_append(logp, LOGFL_NODUPS, LOG_WARNING, - "Wrong DMI structures count: %d announced, only %d decoded.\n", num, i); + "Wrong DMI structures count: %d announced, only %d decoded.", num, i); if(data - buf != len) log_append(logp, LOGFL_NODUPS, LOG_WARNING, - "Wrong DMI structures length: %d bytes announced, structures occupy %d bytes.\n", + "Wrong DMI structures length: %d bytes announced, structures occupy %d bytes.", len, (unsigned int)(data - buf)); free(buf); diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index dc00279..1056a8f 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -67,7 +67,7 @@ static void init(options *opt) /* sanity check */ if(sizeof(u8) != 1 || sizeof(u16) != 2 || sizeof(u32) != 4 || '\0' != 0) { log_append(opt->logdata, LOGFL_NORMAL, LOG_WARNING, - "%s: compiler incompatibility\n", "dmidecodemodule"); + "%s: compiler incompatibility", "dmidecodemodule"); } } @@ -79,11 +79,11 @@ int parse_opt_type(Log_t *logp, const char *arg) val = strtoul(arg, &next, 0); if(next == arg) { - log_append(logp, LOGFL_NODUPS, LOG_ERR, "Invalid type keyword: %s\n", arg); + log_append(logp, LOGFL_NODUPS, LOG_ERR, "Invalid type keyword: %s", arg); return -1; } if(val > 0xff) { - log_append(logp, LOGFL_NODUPS, LOG_ERR, "Invalid type number: %i\n", val); + log_append(logp, LOGFL_NODUPS, LOG_ERR, "Invalid type number: %i", val); return -1; } diff --git a/src/dmixml.c b/src/dmixml.c index 6f6aa60..ba285e8 100644 --- a/src/dmixml.c +++ b/src/dmixml.c @@ -353,7 +353,7 @@ char *dmixml_GetXPathContent(Log_t *logp, char *buf, size_t buflen, xmlXPathObje default: log_append(logp, LOGFL_NORMAL, LOG_WARNING, "dmixml_GetXPathContent(...):: " - "Do not know how to handle XPath type %i\n", + "Do not know how to handle XPath type %i", xpo->type); return NULL; } diff --git a/src/efi.c b/src/efi.c index 171ae30..ae8d0db 100644 --- a/src/efi.c +++ b/src/efi.c @@ -77,7 +77,7 @@ int address_from_efi(Log_t *logp, size_t * address) perror(filename); if(ret == EFI_NO_SMBIOS) { - log_append(logp, LOGFL_NODUPS, LOG_WARNING, "%s: SMBIOS entry point missing\n", filename); + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "%s: SMBIOS entry point missing", filename); } return ret; diff --git a/src/util.c b/src/util.c index f0d9f93..2eebf30 100644 --- a/src/util.c +++ b/src/util.c @@ -69,7 +69,7 @@ static int myread(Log_t *logp, int fd, u8 * buf, size_t count, const char *prefi if(r2 != count) { close(fd); - log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s: Unexpected end of file\n", prefix); + log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s: Unexpected end of file", prefix); return -1; } diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index 5342bac..e318023 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -305,7 +305,7 @@ inline ptzTYPES _convert_maptype(Log_t *logp, const char *str) { return ptzLIST_DICT; } else { log_append(logp, LOGFL_NORMAL, LOG_WARNING, - "Unknown field type: %s - defaulting to 'constant'\n", str); + "Unknown field type: %s - defaulting to 'constant'", str); return ptzCONST; } } @@ -666,7 +666,7 @@ inline PyObject *StringToPyObj(Log_t *logp, ptzMAP *val_m, const char *instr) { default: log_append(logp, LOGFL_NODUPS, LOG_WARNING, - "Invalid type '%i' for value '%s'\n", + "Invalid type '%i' for value '%s'", val_m->type_value, instr); value = Py_None; } @@ -737,7 +737,7 @@ char *_get_key_value(Log_t *logp, char *key, size_t buflen, break; default: - log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Unknown key type: %i\n", map_p->type_key); + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Unknown key type: %i", map_p->type_key); return NULL; } // We consider to have a key, if the first byte is a readable @@ -999,7 +999,7 @@ PyObject *_deep_pythonize(Log_t *logp, PyObject *retdata, break; default: - log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Unknown value type: %i\n", map_p->type_value); + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Unknown value type: %i", map_p->type_value); break; } @@ -1072,7 +1072,7 @@ PyObject *pythonizeXMLnode(Log_t *logp, ptzMAP *in_map, xmlNode *data_n) { else { log_append(logp, LOGFL_NODUPS, LOG_WARNING, "** pythonizeXMLnode :: Could not locate node for key value: " - "root path '%s', key '%s'\n", map_p->rootpath, map_p->key); + "root path '%s', key '%s'", map_p->rootpath, map_p->key); } #endif if( xpo != NULL ) { From 2f943473c302495940e282f0229c1497e1d8c716 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 5 Feb 2010 20:27:09 +0100 Subject: [PATCH 067/146] Improved DMIerror message tag when decoding is not possible Plus some minor code style clean up --- src/dmidecode.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index e64d12f..02dd9b0 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -4934,9 +4934,17 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver } else { handle_n = xmlNewChild(xmlnode, NULL, (xmlChar *) "DMIerror", NULL); assert( handle_n != NULL ); - dmixml_AddTextContent(handle_n, "Data is truncated"); + dmixml_AddTextContent(handle_n, "Data is truncated %i bytes on type 0x%02X", + (next - buf - len), h.type); dmixml_AddAttribute(handle_n, "type", "%i", h.type); dmixml_AddAttribute(handle_n, "truncated", "1"); + dmixml_AddAttribute(handle_n, "length", "%i", (next - buf)); + dmixml_AddAttribute(handle_n, "expected_length", "%i", len); + + log_append(logp, LOGFL_NODUPS, LOG_WARNING, + "DMI/SMBIOS type 0x%02X is exceeding the expected buffer " + "size by %i bytes. Will not decode this entry.", + h.type, (next - buf - len)); } dmixml_AddAttribute(handle_n, "handle", "0x%04x", h.handle); dmixml_AddAttribute(handle_n, "size", "%d", h.length); @@ -4955,14 +4963,16 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver dmixml_AddAttribute(handle_n, "notfound", "1"); } - if(i != num) + if(i != num) { + log_append(logp, LOGFL_NODUPS, LOG_WARNING, + "Wrong DMI structures count: %d announced, only %d decoded.", num, i); + } + + if(data - buf != len) { log_append(logp, LOGFL_NODUPS, LOG_WARNING, - "Wrong DMI structures count: %d announced, only %d decoded.", num, i); - if(data - buf != len) - log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Wrong DMI structures length: %d bytes announced, structures occupy %d bytes.", len, (unsigned int)(data - buf)); - + } free(buf); } From 7dd821c01c9b24f1d70f0703ab7a8c6799e5309f Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Tue, 12 Jan 2010 12:00:59 +1100 Subject: [PATCH 068/146] New upstream release (v3.10.10) --- contrib/python-dmidecode.spec | 5 ++++- debian/changelog | 15 +++++++++++---- src/version.h | 2 +- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/contrib/python-dmidecode.spec b/contrib/python-dmidecode.spec index d01e831..0154dcc 100644 --- a/contrib/python-dmidecode.spec +++ b/contrib/python-dmidecode.spec @@ -3,7 +3,7 @@ Summary: Python module to access DMI data Name: python-dmidecode -Version: 3.10.9 +Version: 3.10.10 Release: 1%{?dist} License: GPLv2 Group: System Environment/Libraries @@ -49,6 +49,9 @@ rm -rf $RPM_BUILD_ROOT %{_datadir}/python-dmidecode/ %changelog +* Tue Jan 12 2010 Nima Talebi - 3.10.10-1 +- Update to new release + * Thu Jan 07 2010 Nima Talebi - 3.10.9-1 - Update to new release diff --git a/debian/changelog b/debian/changelog index 795079b..2e3f427 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,10 +1,17 @@ -python-dmidecode (3.10.9-1) lucid; urgency=low +python-dmidecode (3.10.10-1) unstable; urgency=low + + * New upstream cleanup release. + * This release has addressed the previously messy error/warning handling. + + -- Nima Talebi Tue, 12 Jan 2010 11:59:27 +1100 + +python-dmidecode (3.10.9-1) unstable; urgency=low * New upstream bug-fix release. * Add --install-layout=deb to debian/rules setup.py install to prevent files - from landing in /usr/local (Closes: Bug#563883). - - -- Scott Kitterman Tue, 05 Jan 2010 22:02:29 -0500 + from landing in /usr/local (Closes: Bug#563883) - thanks to Scott + Kitterman. + -- Nima Talebi Tue, 05 Jan 2010 22:02:29 -0500 python-dmidecode (3.10.8-2) unstable; urgency=low diff --git a/src/version.h b/src/version.h index eef20b6..bbc59e6 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define VERSION "3.10.9" +#define VERSION "3.10.10" From bb5d00b80c05cb42326d2c4a0b92a504e587c03f Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Tue, 16 Feb 2010 08:31:59 +1100 Subject: [PATCH 069/146] New feature release (log handling) --- contrib/python-dmidecode.spec | 5 ++++- debian/changelog | 8 ++++++++ src/version.h | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/contrib/python-dmidecode.spec b/contrib/python-dmidecode.spec index 0154dcc..da818e4 100644 --- a/contrib/python-dmidecode.spec +++ b/contrib/python-dmidecode.spec @@ -3,7 +3,7 @@ Summary: Python module to access DMI data Name: python-dmidecode -Version: 3.10.10 +Version: 3.10.11 Release: 1%{?dist} License: GPLv2 Group: System Environment/Libraries @@ -49,6 +49,9 @@ rm -rf $RPM_BUILD_ROOT %{_datadir}/python-dmidecode/ %changelog +* Tue Feb 16 2010 Nima Talebi - 3.10.11-1 +- Update to new release + * Tue Jan 12 2010 Nima Talebi - 3.10.10-1 - Update to new release diff --git a/debian/changelog b/debian/changelog index 2e3f427..a128278 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +python-dmidecode (3.10.11-1) unstable; urgency=low + + * New upstream release. + * Log messages no longer handled via `fprintf' statements, but handled + inside a data structure and dealt with accordingly. + + -- Nima Talebi Tue, 16 Feb 2010 08:30:44 +1100 + python-dmidecode (3.10.10-1) unstable; urgency=low * New upstream cleanup release. diff --git a/src/version.h b/src/version.h index bbc59e6..180cf92 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define VERSION "3.10.10" +#define VERSION "3.10.11" From c5ffd14c31cc733ccfa625727c204a799cb1a9fc Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Tue, 16 Feb 2010 08:54:52 +1100 Subject: [PATCH 070/146] Preparing Debian release --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index ba2ea7b..d0c3f11 100644 --- a/debian/control +++ b/debian/control @@ -6,7 +6,7 @@ Homepage: http://projects.autonomy.net.au/python-dmidecode Maintainer: Nima Talebi Build-Depends: debhelper (>> 7), python-support (>= 0.5.3), python, python-all-dev (>= 2.5.4-2), python-all-dbg, libxml2-dev, python-libxml2 -Standards-Version: 3.8.3 +Standards-Version: 3.8.4 Package: python-dmidecode XB-Python-Version: ${python:Versions} From d86d22c89cda5f8d2736dadfc398e8f6a29e1b82 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Fri, 26 Feb 2010 00:43:03 +1100 Subject: [PATCH 071/146] Fix licensing problem, all now on GPLv2+ --- .autoheader | 4 ++-- Makefile | 38 +++++++++++++++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/.autoheader b/.autoheader index bc6e134..fb8f9cc 100644 --- a/.autoheader +++ b/.autoheader @@ -1,6 +1,6 @@ -© 2007-2009 Nima Talebi -© 2009 David Sommerseth +© 2007-2010 Nima Talebi +© 2009-2010 David Sommerseth © 2002-2008 Jean Delvare © 2000-2002 Alan Cox diff --git a/Makefile b/Makefile index 1d82922..d468b70 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,42 @@ +#. ******* coding:utf-8 AUTOHEADER START v1.2 ******* +#. vim: fileencoding=utf-8 syntax=Makefile sw=4 ts=4 et #. -#. DMI Decode Python Extension Module +#. © 2007-2010 Nima Talebi +#. © 2009-2010 David Sommerseth +#. © 2002-2008 Jean Delvare +#. © 2000-2002 Alan Cox #. -#. (C) 2008 Nima Talebi +#. This file is part of python-dmidecode. #. -#. Licensed under the GNU Public License v2 +#. python-dmidecode 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-dmidecode 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-dmidecode. If not, see . +#. +#. 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::20100225 $ +#. ******* AUTOHEADER END v1.2 ******* VERSION := $(shell cd src;python -c "from setup_common import *; print get_version();") PACKAGE := python-dmidecode From 60a85298dffa1497c2d24334c92989bc57201406 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 2 Mar 2010 18:48:35 +0100 Subject: [PATCH 072/146] Updated examples/dmidump.py to be more up-to-date against a lot of new features Rewrote bigger parts to be more intelligent, checking for warnings on the way. Added more warnings if script is run as a non-root user, and made it work as non-root user if a dmidata.dump file exists (created when run as root). Added examples with the XML API as well. --- examples/dmidump.py | 203 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 164 insertions(+), 39 deletions(-) diff --git a/examples/dmidump.py b/examples/dmidump.py index ed9908f..977504f 100755 --- a/examples/dmidump.py +++ b/examples/dmidump.py @@ -1,54 +1,179 @@ #!/usr/bin/env python +# +# Examples which makes use of the different python-dmidecode features +# This script should be run as root, or else expect permission warnings +# +# Copyright 2008-2009 Nima Talebi +# Copyright 2010 David Sommerseth +# +# 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 dmidecode -import sys +import sys, os 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() +def print_warnings(): + "Simple function, dumping out warnings with a prefix if warnings are found and clearing warning buffer" + warn = dmidecode.get_warnings() + if warn: + print "### WARNING: %s" % warn + dmidecode.clear_warnings() + + +# Check if running as root .... provide a warning if not +root_user = (os.getuid() == 0 and True or False) +if not root_user: + print "####" + print "#### NOT RUNNING AS ROOT" + print "####" + print "#### The first run must always be done as root for this example to work." + print "#### When not run as root, quite some permission errors might appear" + print "####" + print "#### If this script is first run as root, it should be possible to run this script" + print "#### as an unprivileged user afterwards, with less warnings." + print "####" + print + print + + +#. Test all functions using /dev/mem... Using the legacy API +if root_user: + print "*** bios ***\n"; dmidecode.bios() + print_warnings() + print "*** system ***\n"; dmidecode.system() + print_warnings() + print "*** system ***\n"; dmidecode.system() + print_warnings() + print "*** baseboard ***\n"; dmidecode.baseboard() + print_warnings() + print "*** chassis ***\n"; dmidecode.chassis() + print_warnings() + print "*** processor ***\n"; dmidecode.processor() + print_warnings() + print "*** memory ***\n"; dmidecode.memory() + print_warnings() + print "*** cache ***\n"; dmidecode.cache() + print_warnings() + print "*** connector ***\n"; dmidecode.connector() + print_warnings() + print "*** slot ***\n"; dmidecode.slot() + print_warnings() + #. Now test get/set of memory device file... +print "*** get_dev()" print dmidecode.get_dev() -print dmidecode.set_dev("private/mem-XXX"); +print_warnings() +print "*** set_dev('dmidata.dump')" +print dmidecode.set_dev("dmidata.dump"); +print_warnings() +print "*** get_dev()" print dmidecode.get_dev() +print_warnings() #. 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()) +if root_user: + print "*** Dumping DMI data to dump file" + print dmidecode.dump() + print_warnings() +#. Test reading the dump... Using the preferred API +print "*** bios ***\n"; pprint(dmidecode.QuerySection('bios')) +print_warnings() +print "*** system ***\n"; pprint(dmidecode.QuerySection('system')) +print_warnings() +print "*** system ***\n"; pprint(dmidecode.QuerySection('system')) +print_warnings() +print "*** baseboard ***\n"; pprint(dmidecode.QuerySection('baseboard')) +print_warnings() +print "*** chassis ***\n"; pprint(dmidecode.QuerySection('chassis')) +print_warnings() +print "*** processor ***\n"; pprint(dmidecode.QuerySection('processor')) +print_warnings() +print "*** memory ***\n"; pprint(dmidecode.QuerySection('memory')) +print_warnings() +print "*** cache ***\n"; pprint(dmidecode.QuerySection('cache')) +print_warnings() +print "*** connector ***\n"; pprint(dmidecode.QuerySection('connector')) +print_warnings() +print "*** slot ***\n"; pprint(dmidecode.QuerySection('slot')) +print_warnings() + +print "*** Extracting memory information" 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')) +print "*** Querying for DMI type 3 and 7" +pprint(dmidecode.type(3)) # <-- Legacy API +pprint(dmidecode.QueryTypeId(7)) # <-- preferred API +print_warnings() + +print "*** Querying for the BIOS section" +pprint(dmidecode.QuerySection('bios')) +print_warnings() + +# +# Test XML stuff +# +print +print +print +print "---------------------------------------" +print "*** *** *** Testing XML API *** *** ***" +print "---------------------------------------" +print +print +dmixml = dmidecode.dmidecodeXML() + +# Fetch all DMI data into a libxml2.xmlDoc object +print "*** Getting all DMI data into a XML document variable" +dmixml.SetResultType(dmidecode.DMIXML_DOC) # Valid values: dmidecode.DMIXML_DOC, dmidecode.DMIXML_NODE +xmldoc = dmixml.QuerySection('all') + +# Dump the XML to dmidump.xml - formated in UTF-8 decoding +print "*** Dumping XML document to dmidump.xml" +xmldoc.saveFormatFileEnc('dmidump.xml','UTF-8',1) + +# Do some XPath queries on the XML document +print "*** Doing some XPath queries against the XML document" +dmixp = xmldoc.xpathNewContext() + +# What to look for - XPath expressions +keys = ['/dmidecode/SystemInfo/Manufacturer', + '/dmidecode/SystemInfo/ProductName', + '/dmidecode/SystemInfo/SerialNumber', + '/dmidecode/SystemInfo/SystemUUID'] + +# Extract data and print it +for k in keys: + data = dmixp.xpathEval(k) + for d in data: + print "%s: %s" % (k, d.get_content()) + +del dmixp +del xmldoc + +# Query for only a particular DMI TypeID - 0x04 - Processor +print "*** Quering for Type ID 0x04 - Processor - dumping XML document to stdout" +dmixml.QueryTypeId(0x04).saveFormatFileEnc('-','UTF-8',1) +print_warnings() From a96f0787707489723fc83eac8b697989ca576f86 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Thu, 4 Mar 2010 10:56:16 +1100 Subject: [PATCH 073/146] Small fix to sample file based on report on mailing list --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index a128278..2db409a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +python-dmidecode (3.10.11-2) unstable; urgency=low + + * Small fix to example file. + + -- Nima Talebi Thu, 04 Mar 2010 10:55:55 +1100 + python-dmidecode (3.10.11-1) unstable; urgency=low * New upstream release. From c8779db3414e1e03be3c42dc3fbc81c83bc85d41 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Wed, 3 Mar 2010 14:57:10 -0500 Subject: [PATCH 074/146] RPM spec: Install into /usr instead of /usr/local On OpenSuSE, the default 'setup.py install' installs to /usr/local Added --prefix=/usr to setup.py install command in the RPM spec so rpmbuild picks up the correct files. --- contrib/python-dmidecode.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/python-dmidecode.spec b/contrib/python-dmidecode.spec index da818e4..d1790e8 100644 --- a/contrib/python-dmidecode.spec +++ b/contrib/python-dmidecode.spec @@ -31,7 +31,7 @@ cd .. %install rm -rf $RPM_BUILD_ROOT -python src/setup.py install --root $RPM_BUILD_ROOT +python src/setup.py install --root $RPM_BUILD_ROOT --prefix=/usr %clean rm -rf $RPM_BUILD_ROOT From 7489917e75aa967d6e945360c92df829c436a635 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 4 Mar 2010 10:50:52 +0100 Subject: [PATCH 075/146] Use %{_prefix} instead of hard coding /usr in setup.py --prefix --- contrib/python-dmidecode.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/python-dmidecode.spec b/contrib/python-dmidecode.spec index d1790e8..1645bc1 100644 --- a/contrib/python-dmidecode.spec +++ b/contrib/python-dmidecode.spec @@ -31,7 +31,7 @@ cd .. %install rm -rf $RPM_BUILD_ROOT -python src/setup.py install --root $RPM_BUILD_ROOT --prefix=/usr +python src/setup.py install --root $RPM_BUILD_ROOT --prefix=%{_prefix} %clean rm -rf $RPM_BUILD_ROOT From ec8411a210f6fba017b7c7e3fe903ceb0621b0fd Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 4 Mar 2010 16:08:39 +0100 Subject: [PATCH 076/146] Clarify one comment, where API presence is tested. --- examples/dmidump.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/dmidump.py b/examples/dmidump.py index 977504f..869262a 100755 --- a/examples/dmidump.py +++ b/examples/dmidump.py @@ -55,7 +55,11 @@ def print_warnings(): print -#. Test all functions using /dev/mem... Using the legacy API +#. Test for presence of important functions using /dev/mem... Using the legacy API +#. This does not print any decoded info. If the call fails, either a warning will +#. be issued or an exception will be raised. This test is now only used to check +#. for presence of the legacy API, which "under the hood" uses +#. dmidecode.QuerySection(name), where name can be 'bios', 'system', etc. if root_user: print "*** bios ***\n"; dmidecode.bios() print_warnings() From a0b0fd9762f1778efbfd368df9e6a4daba104655 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 4 Mar 2010 16:24:53 +0100 Subject: [PATCH 077/146] Removed not needed duplication --- examples/dmidump.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/examples/dmidump.py b/examples/dmidump.py index 869262a..11b04ff 100755 --- a/examples/dmidump.py +++ b/examples/dmidump.py @@ -65,8 +65,6 @@ def print_warnings(): print_warnings() print "*** system ***\n"; dmidecode.system() print_warnings() - print "*** system ***\n"; dmidecode.system() - print_warnings() print "*** baseboard ***\n"; dmidecode.baseboard() print_warnings() print "*** chassis ***\n"; dmidecode.chassis() @@ -105,8 +103,6 @@ def print_warnings(): print_warnings() print "*** system ***\n"; pprint(dmidecode.QuerySection('system')) print_warnings() -print "*** system ***\n"; pprint(dmidecode.QuerySection('system')) -print_warnings() print "*** baseboard ***\n"; pprint(dmidecode.QuerySection('baseboard')) print_warnings() print "*** chassis ***\n"; pprint(dmidecode.QuerySection('chassis')) From 3aabb2ff8c7fdb9c68c38c2cdd13f64f7c74586d Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 20 Apr 2010 11:43:04 +0200 Subject: [PATCH 078/146] Add a little hint where decoding got aborted --- src/dmidecode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index 02dd9b0..b89c163 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -4890,8 +4890,8 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver */ if(h.length < 4) { log_append(logp, LOGFL_NORMAL, LOG_WARNING, - "Invalid entry length (%i). DMI table is broken! Stop.", - (unsigned int)h.length); + "Invalid entry length (%i) for type %i. DMI table is broken! Stop.", + (unsigned int)h.length, type); break; } From 63fa74b229dd25b1e6398f20b966725df855dcf3 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 20 Apr 2010 12:08:04 +0200 Subject: [PATCH 079/146] Allow format strings to be NULL in dmixml_Add*() functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This bug was reported by Jan Hutař [1] The implemented fix avoids assertions if the format strings to dmixml_AddAttribute(), dmixml_AddTextChild() and dmixml_AddTextContent() functions are NULL. In these cases, it will result in an empty value instead of returning NULL from these functions. [1] --- src/dmixml.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/dmixml.c b/src/dmixml.c index ba285e8..3b05ad4 100644 --- a/src/dmixml.c +++ b/src/dmixml.c @@ -92,13 +92,18 @@ xmlAttr *dmixml_AddAttribute(xmlNode *node, const char *atrname, const char *fmt xmlAttr *res = NULL; va_list ap; - if( (node == NULL) || (atrname == NULL) || (fmt == NULL) ) { + if( (node == NULL) || (atrname == NULL) ) { return NULL; } atrname_s = xmlCharStrdup(atrname); assert( atrname_s != NULL ); + if( fmt == NULL ) { + res = xmlNewProp(node, atrname_s, NULL); + goto exit; + } + va_start(ap, fmt); val_s = dmixml_buildstr(2048, fmt, ap); va_end(ap); @@ -106,8 +111,9 @@ xmlAttr *dmixml_AddAttribute(xmlNode *node, const char *atrname, const char *fmt res = xmlNewProp(node, atrname_s, (xmlStrcmp(val_s, (xmlChar *) "(null)") == 0 ? NULL : val_s)); - free(atrname_s); free(val_s); + exit: + free(atrname_s); assert( res != NULL ); return res; @@ -129,13 +135,18 @@ xmlNode *dmixml_AddTextChild(xmlNode *node, const char *tagname, const char *fmt xmlNode *res = NULL; va_list ap; - if( (node == NULL) || (tagname == NULL) || (fmt == NULL) ) { + if( (node == NULL) || (tagname == NULL) ) { return NULL; } tagname_s = xmlCharStrdup(tagname); assert( tagname_s != NULL ); + if( fmt == NULL ) { + res = xmlNewChild(node, NULL, tagname_s, NULL); + goto exit; + } + va_start(ap, fmt); val_s = dmixml_buildstr(2048, fmt, ap); va_end(ap); @@ -144,8 +155,9 @@ xmlNode *dmixml_AddTextChild(xmlNode *node, const char *tagname, const char *fmt res = xmlNewTextChild(node, NULL, tagname_s, (xmlStrcmp(val_s, (xmlChar *) "(null)") == 0 ? NULL : val_s)); - free(tagname_s); free(val_s); + exit: + free(tagname_s); assert( res != NULL ); return res; @@ -165,7 +177,9 @@ xmlNode *dmixml_AddTextContent(xmlNode *node, const char *fmt, ...) va_list ap; if( (node == NULL) || (fmt == NULL) ) { - return NULL; + // Return node and not NULL, as node may not be NULL but fmt can be, + // thus doing a similar string check (val_s != "(null)") as later on + return node; } va_start(ap, fmt); From ed56537e17ee41c3cec019fc6dda815652dc0d52 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Thu, 4 Mar 2010 10:56:16 +1100 Subject: [PATCH 080/146] Small fix to sample file based on report on mailing list --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index a128278..2db409a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +python-dmidecode (3.10.11-2) unstable; urgency=low + + * Small fix to example file. + + -- Nima Talebi Thu, 04 Mar 2010 10:55:55 +1100 + python-dmidecode (3.10.11-1) unstable; urgency=low * New upstream release. From 1e9d9abffa27a45d24cb2e978f302ff25c2c7f76 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Fri, 12 Mar 2010 14:33:56 +1100 Subject: [PATCH 081/146] v3.10.12 in light of recent bugfix release Also, switch to dpkg-source 3.0 (quilt) format. --- contrib/python-dmidecode.spec | 5 ++++- debian/changelog | 8 ++++++++ debian/source/format | 1 + src/version.h | 2 +- 4 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 debian/source/format diff --git a/contrib/python-dmidecode.spec b/contrib/python-dmidecode.spec index 1645bc1..e31dd0e 100644 --- a/contrib/python-dmidecode.spec +++ b/contrib/python-dmidecode.spec @@ -3,7 +3,7 @@ Summary: Python module to access DMI data Name: python-dmidecode -Version: 3.10.11 +Version: 3.10.12 Release: 1%{?dist} License: GPLv2 Group: System Environment/Libraries @@ -49,6 +49,9 @@ rm -rf $RPM_BUILD_ROOT %{_datadir}/python-dmidecode/ %changelog +* Fri Mar 12 2010 Nima Talebi - 3.10.12-1 +- Update to new release + * Tue Feb 16 2010 Nima Talebi - 3.10.11-1 - Update to new release diff --git a/debian/changelog b/debian/changelog index 2db409a..5d98283 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +python-dmidecode (3.10.12-1) unstable; urgency=low + + * Switch to dpkg-source 3.0 (quilt) format + * Upstream bugfix release. See the following URI for details: + https://bugzilla.redhat.com/show_bug.cgi?id=583867 + + -- Nima Talebi Fri, 12 Mar 2010 14:31:45 +1100 + python-dmidecode (3.10.11-2) unstable; urgency=low * Small fix to example file. diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000..163aaf8 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/src/version.h b/src/version.h index 180cf92..912de39 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define VERSION "3.10.11" +#define VERSION "3.10.12" From 8175496d3cd4db4d0451ad881038c237df5edb10 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Fri, 23 Apr 2010 22:26:37 +1000 Subject: [PATCH 082/146] Added missing dependency --- debian/changelog | 9 ++++++++- debian/control | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 5d98283..11e3ef9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,10 +1,17 @@ +python-dmidecode (3.10.12-2) unstable; urgency=low + + * Added a missing dependency (Closes: Bug#578891) - thanks to Sven Wick for + the bug report. + + -- Nima Talebi Fri, 23 Apr 2010 22:25:55 +1000 + python-dmidecode (3.10.12-1) unstable; urgency=low * Switch to dpkg-source 3.0 (quilt) format * Upstream bugfix release. See the following URI for details: https://bugzilla.redhat.com/show_bug.cgi?id=583867 - -- Nima Talebi Fri, 12 Mar 2010 14:31:45 +1100 + -- Nima Talebi Fri, 23 Apr 2010 22:24:50 +1000 python-dmidecode (3.10.11-2) unstable; urgency=low diff --git a/debian/control b/debian/control index d0c3f11..9a0297b 100644 --- a/debian/control +++ b/debian/control @@ -12,7 +12,7 @@ Package: python-dmidecode XB-Python-Version: ${python:Versions} Architecture: any Provides: ${python:Provides} -Depends: ${python:Depends}, ${shlibs:Depends}, ${misc:Depends} +Depends: ${python:Depends}, ${shlibs:Depends}, ${misc:Depends}, python-libxml2 Description: Python extension module for dmidecode DMI (the desktop management interface) provides a standardized description of a computer's hardware, including characteristics such as BIOS serial number From 7253bbeed7f6d00bd796019d79dc1fe0a805fa8e Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 26 May 2010 15:39:19 +0200 Subject: [PATCH 083/146] Fixed an issue causing SEGV on some hardware when dmi_processor_id() is called The dmi_processor_id() function did not check the char *version pointer if it was NULL before doing strcmp(). On some hardware, *version will be NULL. --- src/dmidecode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index b89c163..4a2e445 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -1019,7 +1019,6 @@ xmlNode *dmi_processor_id(xmlNode *node, u8 type, const u8 * p, const char *vers ** 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]); @@ -1075,7 +1074,7 @@ xmlNode *dmi_processor_id(xmlNode *node, u8 type, const u8 * p, const char *vers sig = 2; - } else if(type == 0x01 || type == 0x02) { + } else if(version && (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 From 4e5fa23d119a6cb02f1a7fb92e1a447b7a7ae97f Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Fri, 23 Apr 2010 22:26:37 +1000 Subject: [PATCH 084/146] Added missing dependency --- debian/changelog | 9 ++++++++- debian/control | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 5d98283..11e3ef9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,10 +1,17 @@ +python-dmidecode (3.10.12-2) unstable; urgency=low + + * Added a missing dependency (Closes: Bug#578891) - thanks to Sven Wick for + the bug report. + + -- Nima Talebi Fri, 23 Apr 2010 22:25:55 +1000 + python-dmidecode (3.10.12-1) unstable; urgency=low * Switch to dpkg-source 3.0 (quilt) format * Upstream bugfix release. See the following URI for details: https://bugzilla.redhat.com/show_bug.cgi?id=583867 - -- Nima Talebi Fri, 12 Mar 2010 14:31:45 +1100 + -- Nima Talebi Fri, 23 Apr 2010 22:24:50 +1000 python-dmidecode (3.10.11-2) unstable; urgency=low diff --git a/debian/control b/debian/control index d0c3f11..9a0297b 100644 --- a/debian/control +++ b/debian/control @@ -12,7 +12,7 @@ Package: python-dmidecode XB-Python-Version: ${python:Versions} Architecture: any Provides: ${python:Provides} -Depends: ${python:Depends}, ${shlibs:Depends}, ${misc:Depends} +Depends: ${python:Depends}, ${shlibs:Depends}, ${misc:Depends}, python-libxml2 Description: Python extension module for dmidecode DMI (the desktop management interface) provides a standardized description of a computer's hardware, including characteristics such as BIOS serial number From 69a7962bbb7a8c0e0366045b80f159a982a00fc2 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Thu, 3 Jun 2010 19:57:08 +1000 Subject: [PATCH 085/146] New upstream release - v3.10.13 --- contrib/python-dmidecode.spec | 5 ++++- debian/changelog | 6 ++++++ src/version.h | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/contrib/python-dmidecode.spec b/contrib/python-dmidecode.spec index e31dd0e..ccd93d7 100644 --- a/contrib/python-dmidecode.spec +++ b/contrib/python-dmidecode.spec @@ -3,7 +3,7 @@ Summary: Python module to access DMI data Name: python-dmidecode -Version: 3.10.12 +Version: 3.10.13 Release: 1%{?dist} License: GPLv2 Group: System Environment/Libraries @@ -49,6 +49,9 @@ rm -rf $RPM_BUILD_ROOT %{_datadir}/python-dmidecode/ %changelog +* Thu Jun 03 2010 Nima Talebi - 3.10.13-1 +- Update to new release + * Fri Mar 12 2010 Nima Talebi - 3.10.12-1 - Update to new release diff --git a/debian/changelog b/debian/changelog index 11e3ef9..4bd61c9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +python-dmidecode (3.10.13-1) unstable; urgency=low + + * New upstream release. + + -- Nima Talebi Thu, 03 Jun 2010 19:56:38 +1000 + python-dmidecode (3.10.12-2) unstable; urgency=low * Added a missing dependency (Closes: Bug#578891) - thanks to Sven Wick for diff --git a/src/version.h b/src/version.h index 912de39..742a13f 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define VERSION "3.10.12" +#define VERSION "3.10.13" From 0d48bd736d5c9602574907500b5068138b155bf7 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 27 Oct 2010 15:49:37 +0200 Subject: [PATCH 086/146] Add SIGILL catcher in mem_chunk() On some s390x systems under heavy memory load seems to trigger a SIGILL event when calling memcpy(). To avoid this issue, which basically leads to the complete script to core dump, a signal handler was implemented to add tackle such siutations more gracefully. The SIGILL event should now be logged as well, to be able to see that this happened. Signed-off-by: David Sommerseth --- src/util.c | 67 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 53 insertions(+), 14 deletions(-) diff --git a/src/util.c b/src/util.c index 2eebf30..8da554b 100644 --- a/src/util.c +++ b/src/util.c @@ -44,6 +44,7 @@ #include #include #include +#include #include "types.h" #include "util.h" @@ -87,6 +88,23 @@ int checksum(const u8 * buf, size_t len) return (sum == 0); } +/* Static global variables which should only + * be used by the sigill_handler() + */ +static int sigill_error = 0; +static Log_t *sigill_logobj = NULL; + +void sigill_handler(int ignore_this) { + sigill_error = 1; + if( sigill_logobj ) { + log_append(sigill_logobj, LOGFL_NODUPS, LOG_WARNING, + "SIGILL signal caught in mem_chunk()"); + } else { + fprintf(stderr, + "** WARNING ** SIGILL signal caught in mem_chunk()\n"); + } +} + /* * Copy a physical memory chunk into a memory buffer. * This function allocates memory. @@ -100,15 +118,20 @@ void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem) size_t mmoffset; void *mmp; #endif - - if((fd = open(devmem, O_RDONLY)) == -1) { - log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s: %s", devmem, strerror(errno)); - return NULL; + sigill_logobj = logp; + signal(SIGILL, sigill_handler); + if(sigill_error || (fd = open(devmem, O_RDONLY)) == -1) { + log_append(logp, LOGFL_NORMAL, LOG_WARNING, + "Failed to open memory buffer (%s): %s", + devmem, strerror(errno)); + p = NULL; + goto exit; } - if((p = malloc(len)) == NULL) { - log_append(logp, LOGFL_NORMAL, LOG_WARNING, "malloc: %s", strerror(errno)); - return NULL; + if(sigill_error || (p = malloc(len)) == NULL) { + log_append(logp, LOGFL_NORMAL, LOG_WARNING,"malloc: %s", strerror(errno)); + p = NULL; + goto exit; } #ifdef USE_MMAP #ifdef _SC_PAGESIZE @@ -122,33 +145,49 @@ void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem) * 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) { + if(sigill_error || (mmp == MAP_FAILED)) { log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s (mmap): %s", devmem, strerror(errno)); free(p); - return NULL; + p = NULL; + goto exit; } memcpy(p, (u8 *) mmp + mmoffset, len); + if (sigill_error) { + log_append(logp, LOGFL_NODUPS, LOG_WARNING, + "Failed to do memcpy() due to SIGILL signal"); + free(p); + p = NULL; + goto exit; + } - if(munmap(mmp, mmoffset + len) == -1) { + if(sigill_error || (munmap(mmp, mmoffset + len) == -1)) { log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s (munmap): %s", devmem, strerror(errno)); + free(p); + p = NULL; + goto exit; } #else /* USE_MMAP */ - if(lseek(fd, base, SEEK_SET) == -1) { + if(sigill_error || (lseek(fd, base, SEEK_SET) == -1)) { log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s (lseek): %s", devmem, strerror(errno)); free(p); - return NULL; + p = NULL; + goto exit; } - if(myread(logp, fd, p, len, devmem) == -1) { + if(sigill_error || (myread(logp, fd, p, len, devmem) == -1)) { free(p); - return NULL; + p = NULL; + goto exit; } #endif /* USE_MMAP */ if(close(fd) == -1) perror(devmem); + exit: + signal(SIGILL, SIG_DFL); + sigill_logobj = NULL; return p; } From 10a2d8bd43934966dd842fd8f401f0d679d0d66a Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 6 Jan 2011 13:44:25 +0100 Subject: [PATCH 087/146] Implemented dmixml_AddDMIstring() This function can be used instead of dmi_string() and dmixml_AddTextChild(). In those cases where dmi_string() returns NULL, this situation is handled more gracefully. In addition of also handling "not specified" situations better as well. Signed-off-by: David Sommerseth --- src/dmixml.c | 42 ++++++++++++++++++++++++++++++++++++++++++ src/dmixml.h | 1 + 2 files changed, 43 insertions(+) diff --git a/src/dmixml.c b/src/dmixml.c index 3b05ad4..5fe0dd5 100644 --- a/src/dmixml.c +++ b/src/dmixml.c @@ -41,6 +41,7 @@ #include #include +#include "dmidecode.h" #include "dmilog.h" #include "dmixml.h" @@ -163,6 +164,47 @@ xmlNode *dmixml_AddTextChild(xmlNode *node, const char *tagname, const char *fmt return res; } +/** + * A variant of dmixml_AddTextChild() which will do dmi_string() decoding instead of a plain string. + * If the dmi_string() function returns NULL, it will instead add a XML node attribute 'badindex' + * @author David Sommerseth + * @param xmlNode* Pointer to the current node which will get the text child + * @param const char* Name of the new tag + * @param const struct dmi_header* Pointer to the DMI table header + * @param u8 DMI table index of the information to be extracted and used in the XML node + * @return xmlNode* Pointer to the new tag. On errors the return value will be NULL. On fatal + * errors and assert() call will be done. + */ +xmlNode *dmixml_AddDMIstring(xmlNode *node, const char *tagname, const struct dmi_header *dm, u8 s) { + xmlChar *tagname_s = NULL; + xmlNode *res = NULL; + const char *dmistr; + + if( (node == NULL) || (tagname == NULL) ) { + return NULL; + } + + tagname_s = xmlCharStrdup(tagname); + assert( tagname_s != NULL ); + + if(s == 0) { + res = xmlNewChild(node, NULL, tagname_s, NULL); + dmixml_AddAttribute(res, "not_specified", "1"); + return res; + } + + dmistr = dmi_string(dm, s); + if( dmistr == NULL ) { + res = xmlNewChild(node, NULL, tagname_s, NULL); + dmixml_AddAttribute(res, "badindex", "1"); + } else { + xmlChar *val_s = xmlCharStrdup(dmistr); + res = xmlNewTextChild(node, NULL, tagname_s, val_s); + free(val_s); + } + 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 diff --git a/src/dmixml.h b/src/dmixml.h index 7bbbb76..cc2c303 100644 --- a/src/dmixml.h +++ b/src/dmixml.h @@ -34,6 +34,7 @@ xmlAttr *dmixml_AddAttribute(xmlNode *node, const char *atrname, const char *fmt, ...); xmlNode *dmixml_AddTextChild(xmlNode *node, const char *tagname, const char *fmt, ...); +xmlNode *dmixml_AddDMIstring(xmlNode *node, const char *tagname, const struct dmi_header *dm, u8 s); xmlNode *dmixml_AddTextContent(xmlNode *node, const char *fmt, ...); char *dmixml_GetAttrValue(xmlNode *node, const char *key); From 734d025ce6503851447f5a3dd08b107425f8b515 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 6 Jan 2011 13:47:42 +0100 Subject: [PATCH 088/146] Make use of dmixml_AddDMIstring() where possible This modifies the core DMI decoding to make use of the new dmixml_AddDMIstring() function instead of the older, more error prone approach of dmi_string() and dmixml_AddTextChild(). Signed-off-by: David Sommerseth --- src/dmidecode.c | 133 +++++++++++++++++++++++++----------------------- 1 file changed, 68 insertions(+), 65 deletions(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index 4a2e445..726b2de 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -81,8 +81,8 @@ #include "config.h" #include "types.h" #include "util.h" -#include "dmixml.h" #include "dmidecode.h" +#include "dmixml.h" #include "dmioem.h" #include "efi.h" #include "dmidump.h" @@ -918,6 +918,7 @@ void dmi_processor_family(xmlNode *node, const struct dmi_header *h) /* Special case for ambiguous value 0xBE */ if(code == 0xBE) { const char *manufacturer = dmi_string(h, data[0x07]); + // FIXME: manufacturer may be NULL /* Best bet based on manufacturer string */ if(strstr(manufacturer, "Intel") != NULL || @@ -2107,7 +2108,7 @@ void dmi_on_board_devices_type(xmlNode *node, u8 code) } } -void dmi_on_board_devices(xmlNode *node, const char *tagname, struct dmi_header *h) +void dmi_on_board_devices(xmlNode *node, const char *tagname, const struct dmi_header *h) { u8 *p = h->data + 4; u8 count = (h->length - 0x04) / 2; @@ -2123,7 +2124,7 @@ void dmi_on_board_devices(xmlNode *node, const char *tagname, struct dmi_header 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])); + dmixml_AddDMIstring(dev_n, "Description", h, p[2 * i + 1]); dev_n = NULL; } } @@ -2141,7 +2142,7 @@ void dmi_oem_strings(xmlNode *node, struct dmi_header *h) dmixml_AddAttribute(node, "count", "%i", count); for(i = 1; i <= count; i++) { - xmlNode *str_n = dmixml_AddTextChild(node, "Record", "%s", dmi_string(h, i)); + xmlNode *str_n = dmixml_AddDMIstring(node, "Record", h, i); assert( str_n != NULL ); dmixml_AddAttribute(str_n, "index", "%i", i); } @@ -2163,7 +2164,7 @@ void dmi_system_configuration_options(xmlNode *node, struct dmi_header *h) dmixml_AddAttribute(data_n, "count", "%i", count); for(i = 1; i <= count; i++) { - xmlNode *o_n = dmixml_AddTextChild(data_n, "Option", "%s", dmi_string(h, i)); + xmlNode *o_n = dmixml_AddDMIstring(data_n, "Option", h, i); assert( o_n != NULL ); dmixml_AddAttribute(o_n, "index", "%ld", i); @@ -2186,7 +2187,7 @@ void dmi_bios_languages(xmlNode *node, struct dmi_header *h) 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)); + xmlNode *l_n = dmixml_AddDMIstring(data_n, "Language", h, i); assert( l_n != NULL ); dmixml_AddAttribute(l_n, "index", "%i", i); } @@ -3658,7 +3659,7 @@ void dmi_additional_info(xmlNode *node, const struct dmi_header *h) 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])); + str_n = dmixml_AddDMIstring(data_n, "String", h, p[0x04]); switch (length - 0x05) { case 1: @@ -3705,9 +3706,9 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade 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])); + dmixml_AddDMIstring(sect_n, "Vendor", h, data[0x04]); + dmixml_AddDMIstring(sect_n, "Version", h, data[0x05]); + dmixml_AddDMIstring(sect_n, "ReleaseDate", h, data[0x08]); /* * On IA-64, the BIOS base address will read 0 because @@ -3771,10 +3772,10 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade break; } - 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])); + dmixml_AddDMIstring(sect_n, "Manufacturer", h, data[0x04]); + dmixml_AddDMIstring(sect_n, "ProductName", h, data[0x05]); + dmixml_AddDMIstring(sect_n, "Version", h, data[0x06]); + dmixml_AddDMIstring(sect_n, "SerialNumber", h, data[0x07]); if(h->length < 0x19) { break; @@ -3788,8 +3789,8 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade break; } - dmixml_AddTextChild(sect_n, "SKUnumber", "%s", dmi_string(h, data[0x19])); - dmixml_AddTextChild(sect_n, "Family", "%s", dmi_string(h, data[0x1A])); + dmixml_AddDMIstring(sect_n, "SKUnumber", h, data[0x19]); + dmixml_AddDMIstring(sect_n, "Family", h, data[0x1A]); break; case 2: /* 3.3.3 Base Board Information */ @@ -3797,20 +3798,20 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade break; } - 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])); + dmixml_AddDMIstring(sect_n, "Manufacturer", h, data[0x04]); + dmixml_AddDMIstring(sect_n, "ProductName", h, data[0x05]); + dmixml_AddDMIstring(sect_n, "Version", h, data[0x06]); + dmixml_AddDMIstring(sect_n, "SerialNumber", h, data[0x07]); if(h->length < 0x0F) { break; } - dmixml_AddTextChild(sect_n, "AssetTag", "%s", dmi_string(h, data[0x08])); + dmixml_AddDMIstring(sect_n, "AssetTag", h, data[0x08]); dmi_base_board_features(sect_n, data[0x09]); - dmixml_AddTextChild(sect_n, "ChassisLocation", "%s", dmi_string(h, data[0x0A])); + dmixml_AddDMIstring(sect_n, "ChassisLocation", h, data[0x0A]); dmixml_AddTextChild(sect_n, "ChassisHandle", "0x%04x", WORD(data + 0x0B)); dmi_base_board_type(sect_n, "Type", data[0x0D]); @@ -3827,12 +3828,12 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade break; } - dmixml_AddTextChild(sect_n, "Manufacturer", "%s", dmi_string(h, data[0x04])); + dmixml_AddDMIstring(sect_n, "Manufacturer", 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])); + dmixml_AddDMIstring(sect_n, "Version", h, data[0x06]); + dmixml_AddDMIstring(sect_n, "SerialNumber", h, data[0x07]); + dmixml_AddDMIstring(sect_n, "AssetTag", h, data[0x08]); if(h->length < 0x0D) { break; @@ -3873,17 +3874,18 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade break; } - dmixml_AddTextChild(sect_n, "SocketDesignation", "%s", dmi_string(h, data[0x04])); + dmixml_AddDMIstring(sect_n, "SocketDesignation", h, data[0x04]); dmi_processor_type(sect_n, data[0x05]); dmi_processor_family(sect_n, h); + // FIXME: Better NULL handling dmi_processor_id(sect_n, data[0x06], data + 8, dmi_string(h, data[0x10])); sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Manufacturer", NULL); assert( sub_n != NULL ); - dmixml_AddTextChild(sub_n, "Vendor", dmi_string(h, data[0x07])); + dmixml_AddDMIstring(sub_n, "Vendor", h, data[0x07]); - dmixml_AddTextChild(sub_n, "Version", dmi_string(h, data[0x10])); + dmixml_AddDMIstring(sub_n, "Version", h, data[0x10]); sub_n = NULL; dmi_processor_voltage(sect_n, data[0x11]); @@ -3949,9 +3951,9 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade break; } - 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])); + dmixml_AddDMIstring(sect_n, "SerialNumber", h, data[0x20]); + dmixml_AddDMIstring(sect_n, "AssetTag", h, data[0x21]); + dmixml_AddDMIstring(sect_n, "PartNumber", h, data[0x22]); if(h->length < 0x28) { break; @@ -4024,7 +4026,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade break; } - dmixml_AddTextChild(sect_n, "SocketDesignation", "%s", dmi_string(h, data[0x04])); + dmixml_AddDMIstring(sect_n, "SocketDesignation", 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)); @@ -4039,7 +4041,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade break; } - dmixml_AddTextChild(sect_n, "SocketDesignation", dmi_string(h, data[0x04])); + dmixml_AddDMIstring(sect_n, "SocketDesignation", 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)); @@ -4071,14 +4073,14 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade break; } - sub_n = dmixml_AddTextChild(sect_n, "DesignatorRef", dmi_string(h, data[0x04])); + sub_n = dmixml_AddDMIstring(sect_n, "DesignatorRef", 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])); + sub_n = dmixml_AddDMIstring(sect_n, "DesignatorRef", h, data[0x06]); assert( sub_n != NULL ); dmixml_AddAttribute(sub_n, "type", "external"); sub_n = NULL; @@ -4092,7 +4094,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade break; } - dmixml_AddTextChild(sect_n, "Designation", "%s", dmi_string(h, data[0x04])); + dmixml_AddDMIstring(sect_n, "Designation", h, data[0x04]); dmi_slot_bus_width(sect_n, data[0x06]); dmi_slot_type(sect_n, data[0x05]); @@ -4142,7 +4144,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade break; } - dmixml_AddTextChild(sect_n, "Name", "%s", dmi_string(h, data[0x04])); + dmixml_AddDMIstring(sect_n, "Name", h, data[0x04]); sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Groups", NULL); assert( sub_n != NULL ); @@ -4233,8 +4235,8 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade 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])); + dmixml_AddDMIstring(sect_n, "Locator", h, data[0x10]); + dmixml_AddDMIstring(sect_n, "BankLocator", h, data[0x11]); dmi_memory_device_type(sect_n, data[0x12]); dmi_memory_device_type_detail(sect_n, WORD(data + 0x13)); @@ -4249,10 +4251,10 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade 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])); + dmixml_AddDMIstring(sect_n, "Manufacturer", h, data[0x17]); + dmixml_AddDMIstring(sect_n, "SerialNumber", h, data[0x18]); + dmixml_AddDMIstring(sect_n, "AssetTag", h, data[0x19]); + dmixml_AddDMIstring(sect_n, "PartNumber", h, data[0x1A]); break; case 18: /* 3.3.19 32-bit Memory Error Information */ @@ -4342,18 +4344,18 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade break; } - dmixml_AddTextChild(sect_n, "Location", "%s", dmi_string(h, data[0x04])); - dmixml_AddTextChild(sect_n, "Manufacturer", "%s", dmi_string(h, data[0x05])); + dmixml_AddDMIstring(sect_n, "Location", h, data[0x04]); + dmixml_AddDMIstring(sect_n, "Manufacturer", h, data[0x05]); if(data[0x06] || h->length < 0x1A) { - dmixml_AddTextChild(sect_n, "ManufactureDate", "%s", dmi_string(h, data[0x06])); + dmixml_AddDMIstring(sect_n, "ManufactureDate", h, data[0x06]); } if(data[0x07] || h->length < 0x1A) { - dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x07])); + dmixml_AddDMIstring(sect_n, "SerialNumber", h, data[0x07]); } - dmixml_AddTextChild(sect_n, "Name", "%s", dmi_string(h, data[0x08])); + dmixml_AddDMIstring(sect_n, "Name", h, data[0x08]); if(data[0x09] != 0x02 || h->length < 0x1A) { dmi_battery_chemistry(sect_n, data[0x09]); @@ -4361,7 +4363,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade 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])); + dmixml_AddDMIstring(sect_n, "SBDSversion", h, data[0x0E]); dmi_battery_maximum_error(sect_n, data[0x0F]); @@ -4379,7 +4381,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade (WORD(data + 0x12) & 0x1F)); } if(data[0x09] == 0x02) { - dmixml_AddTextChild(sect_n, "SBDSchemistry", "%s", dmi_string(h, data[0x14])); + dmixml_AddDMIstring(sect_n, "SBDSchemistry", h, data[0x14]); } dmixml_AddTextChild(sect_n, "OEMinformation", "0x%08x", DWORD(data + 0x16)); @@ -4441,7 +4443,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade break; } - dmixml_AddTextChild(sect_n, "Description", "%s", dmi_string(h, data[0x04])); + dmixml_AddDMIstring(sect_n, "Description", h, data[0x04]); dmi_voltage_probe_location(sect_n, data[0x05] & 0x1f); dmi_probe_status(sect_n, data[0x05] >> 5); @@ -4494,7 +4496,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade break; } - dmixml_AddTextChild(sect_n, "Description", "%s", dmi_string(h, data[0x04])); + dmixml_AddDMIstring(sect_n, "Description", h, data[0x04]); dmi_temperature_probe_location(sect_n,data[0x05] & 0x1F); dmi_probe_status(sect_n, data[0x05] >> 5); @@ -4520,7 +4522,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade break; } - dmixml_AddTextChild(sect_n, "Description", dmi_string(h, data[0x04])); + dmixml_AddDMIstring(sect_n, "Description", h, data[0x04]); dmi_voltage_probe_location(sect_n, data[5] & 0x1F); dmi_probe_status(sect_n, data[0x05] >> 5); @@ -4545,7 +4547,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade break; } - dmixml_AddTextChild(sect_n, "ManufacturerName", "%s", dmi_string(h, data[0x04])); + dmixml_AddDMIstring(sect_n, "ManufacturerName", 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; @@ -4569,7 +4571,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade break; } - dmixml_AddTextChild(sect_n, "Description", "%s", dmi_string(h, data[0x04])); + dmixml_AddDMIstring(sect_n, "Description", 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]); @@ -4582,7 +4584,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade break; } - dmixml_AddTextChild(sect_n, "Description", dmi_string(h, data[0x04])); + dmixml_AddDMIstring(sect_n, "Description", h, data[0x04]); dmixml_AddTextChild(sect_n, "ManagementDeviceHandle", "0x%04x", WORD(data + 0x05)); dmixml_AddTextChild(sect_n, "ComponentHandle", "0x%04x", WORD(data + 0x07)); @@ -4721,13 +4723,13 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade 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])); + dmixml_AddDMIstring(sect_n, "Location", h, data[0x05]); + dmixml_AddDMIstring(sect_n, "Name", h, data[0x06]); + dmixml_AddDMIstring(sect_n, "Manufacturer", h, data[0x07]); + dmixml_AddDMIstring(sect_n, "SerialNumber", h, data[0x08]); + dmixml_AddDMIstring(sect_n, "AssetTag", h, data[0x09]); + dmixml_AddDMIstring(sect_n, "ModelPartNumber", h, data[0x0A]); + dmixml_AddDMIstring(sect_n, "Revision", h, data[0x0B]); dmi_power_supply_power(sect_n, WORD(data + 0x0C)); @@ -4789,7 +4791,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade break; } - dmixml_AddTextChild(sect_n, "ReferenceDesignation", "%s", dmi_string(h, data[0x04])); + dmixml_AddDMIstring(sect_n, "ReferenceDesignation", h, data[0x04]); sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "OnboardDevice", NULL); dmi_on_board_devices_type(sub_n, data[0x05] & 0x7F); @@ -4900,6 +4902,7 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver /* assign vendor for vendor-specific decodes later */ if(h.type == 0 && h.length >= 5) { + // FIXME: Better NULL handling dmi_set_vendor(dmi_string(&h, data[0x04])); } From d6987c53d3648d85e410ef81a343867e239eb960 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 6 Jan 2011 15:56:24 +0100 Subject: [PATCH 089/146] Harden dmi_string() calls with better NULL checks This patch fixes more potential issues where dmi_string() results was not necessarily checked for NULL, which potentially could lead to SEGV issues. Signed-off-by: David Sommerseth --- src/dmidecode.c | 23 ++++++++++++++++------- src/dmioem.c | 13 +++++++++++-- src/dmioem.h | 2 +- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index 726b2de..17f2130 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -918,7 +918,11 @@ void dmi_processor_family(xmlNode *node, const struct dmi_header *h) /* Special case for ambiguous value 0xBE */ if(code == 0xBE) { const char *manufacturer = dmi_string(h, data[0x07]); - // FIXME: manufacturer may be NULL + + if( manufacturer == NULL ) { + dmixml_AddTextContent(family_n, "Core 2 or K7 (Unkown manufacturer)"); + return; + } /* Best bet based on manufacturer string */ if(strstr(manufacturer, "Intel") != NULL || @@ -932,7 +936,7 @@ void dmi_processor_family(xmlNode *node, const struct dmi_header *h) dmixml_AddTextContent(family_n, "K7"); return; } - dmixml_AddTextContent(family_n, "Core 2 or K7"); + dmixml_AddTextContent(family_n, "Core 2 or K7 (Unkown manufacturer)"); return; } @@ -960,7 +964,7 @@ void dmi_processor_family(xmlNode *node, const struct dmi_header *h) dmixml_AddAttribute(family_n, "outofspec", "1"); } -xmlNode *dmi_processor_id(xmlNode *node, u8 type, const u8 * p, const char *version) +xmlNode *dmi_processor_id(xmlNode *node, const struct dmi_header *h) { /* Intel AP-485 revision 31, table 3-4 */ static struct _cpuflags { @@ -1002,11 +1006,18 @@ xmlNode *dmi_processor_id(xmlNode *node, u8 type, const u8 * p, const char *vers {"PBE", "PBE (Pending break enabled)"} /* 31 */ /* *INDENT-ON* */ }; + u8 type, *p = NULL; + char *version = NULL; xmlNode *flags_n = NULL; xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "CPUCore", NULL); assert( data_n != NULL ); + assert( h && h->data ); + type = h->data[0x06]; + p = h->data + 8; + version = dmi_string(h, h->data[0x10]); + /* ** Extra flags are now returned in the ECX register when one calls ** the CPUID instruction. Their meaning is explained in table 3-5, but @@ -3878,8 +3889,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmi_processor_type(sect_n, data[0x05]); dmi_processor_family(sect_n, h); - // FIXME: Better NULL handling - dmi_processor_id(sect_n, data[0x06], data + 8, dmi_string(h, data[0x10])); + dmi_processor_id(sect_n, h); sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Manufacturer", NULL); assert( sub_n != NULL ); @@ -4902,8 +4912,7 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver /* assign vendor for vendor-specific decodes later */ if(h.type == 0 && h.length >= 5) { - // FIXME: Better NULL handling - dmi_set_vendor(dmi_string(&h, data[0x04])); + dmi_set_vendor(&h); } /* look for the next handle */ diff --git a/src/dmioem.c b/src/dmioem.c index 361810a..67cd517 100644 --- a/src/dmioem.c +++ b/src/dmioem.c @@ -40,10 +40,19 @@ static enum DMI_VENDORS dmi_vendor = VENDOR_UNKNOWN; * value if we know how to decode at least one specific entry type for * that vendor. */ -void dmi_set_vendor(const char *s) +void dmi_set_vendor(const struct dmi_header *h) { - if(strcmp(s, "HP") == 0) + const char *vendor; + + if( !h || !h->data ) { + return; + } + vendor = dmi_string(h, h->data[0x04]); + if( !vendor ) { + return; + } else if(strcmp(vendor, "HP") == 0) { dmi_vendor = VENDOR_HP; + } } /* diff --git a/src/dmioem.h b/src/dmioem.h index b1b4af8..9ad25bf 100644 --- a/src/dmioem.h +++ b/src/dmioem.h @@ -22,5 +22,5 @@ struct dmi_header; -void dmi_set_vendor(const char *s); +void dmi_set_vendor(const struct dmi_header *h); int dmi_decode_oem(struct dmi_header *h); From 39869fb9346cd46097bd6d70a90f351938d30296 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 5 Apr 2013 18:25:23 +0200 Subject: [PATCH 090/146] Do not add explictly 'dmispec' attributes inside switch() in dmi_decode() The dmispec attribute is added outside the switch() call, and must not be duplicated. If this happens, an invalid XML file will be generated. (Un)fortunately, libxml2 is quite forgiving to this error. But xmllint will complain about it and other XML libraries (such as python-lxml) may reject such XML data. Signed-off-by: David Sommerseth --- src/dmidecode.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index 17f2130..215c3f4 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -4784,7 +4784,6 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade 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; @@ -4795,7 +4794,6 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade 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; From b82aff22223e8c47857b8eb09bf21f1b15887fc4 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 5 Apr 2013 18:30:46 +0200 Subject: [PATCH 091/146] New upstream release (v3.10.14) Signed-off-by: David Sommerseth --- contrib/python-dmidecode.spec | 5 ++++- src/version.h | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/contrib/python-dmidecode.spec b/contrib/python-dmidecode.spec index ccd93d7..ef8ca62 100644 --- a/contrib/python-dmidecode.spec +++ b/contrib/python-dmidecode.spec @@ -3,7 +3,7 @@ Summary: Python module to access DMI data Name: python-dmidecode -Version: 3.10.13 +Version: 3.10.14 Release: 1%{?dist} License: GPLv2 Group: System Environment/Libraries @@ -49,6 +49,9 @@ rm -rf $RPM_BUILD_ROOT %{_datadir}/python-dmidecode/ %changelog +* Fri Apr 05 2013 David Sommerseth - 3.10.14-1 +- Update to new release + * Thu Jun 03 2010 Nima Talebi - 3.10.13-1 - Update to new release diff --git a/src/version.h b/src/version.h index 742a13f..792e7e8 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define VERSION "3.10.13" +#define VERSION "3.10.14" From 69a1c9ca658c9708698cde6aee32af7bb2e16f9a Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 20 Jun 2013 12:58:12 +0200 Subject: [PATCH 092/146] Fixed a missing break statement in a switch for DMI section 3.3.7.2 This missing break could cause duplicated 'installed' attributes in or XML tags. This is only happening when dmi_memory_module_size() is called and only on some hardware. Signed-off-by: David Sommerseth --- src/dmidecode.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dmidecode.c b/src/dmidecode.c index 215c3f4..dae2fef 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -1516,6 +1516,7 @@ void dmi_memory_module_size(xmlNode *node, const char *tagname, u8 code) case 0x7F: dmixml_AddAttribute(data_n, "installed", "0"); check_conn = 0; + break; default: dmixml_AddAttribute(data_n, "installed", "1"); dmixml_AddAttribute(data_n, "unit", "MB"); From 8528590126026d7ed2e7910bafc97f4dc5bc71f4 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Wed, 3 Jul 2013 17:07:46 +0200 Subject: [PATCH 093/146] New upstream release (v3.10.15) Signed-off-by: David Sommerseth --- contrib/python-dmidecode.spec | 5 ++++- src/version.h | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/contrib/python-dmidecode.spec b/contrib/python-dmidecode.spec index ef8ca62..9589179 100644 --- a/contrib/python-dmidecode.spec +++ b/contrib/python-dmidecode.spec @@ -3,7 +3,7 @@ Summary: Python module to access DMI data Name: python-dmidecode -Version: 3.10.14 +Version: 3.10.15 Release: 1%{?dist} License: GPLv2 Group: System Environment/Libraries @@ -49,6 +49,9 @@ rm -rf $RPM_BUILD_ROOT %{_datadir}/python-dmidecode/ %changelog +* Wed Jul 3 2013 David Sommerseth - 3.10.15-1 +- Update to new release + * Fri Apr 05 2013 David Sommerseth - 3.10.14-1 - Update to new release diff --git a/src/version.h b/src/version.h index 792e7e8..c07b06f 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define VERSION "3.10.14" +#define VERSION "3.10.15" From 4ca9576b4090fcc48868e5e362d162e1544e8660 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Mon, 8 Jul 2013 19:36:35 +0200 Subject: [PATCH 094/146] Rebase against upstream dmidecode v2.11 This includes an update against the SMBIOS reference specification v2.7.0 Signed-off-by: David Sommerseth --- contrib/python-dmidecode.spec | 5 +- src/dmidecode.c | 964 ++++++++++++++++++++++------------ src/dmihelper.h | 90 ++-- src/dmixml.h | 2 + src/pymap.xml | 32 +- src/util.c | 15 + src/util.h | 1 + src/version.h | 2 +- 8 files changed, 728 insertions(+), 383 deletions(-) diff --git a/contrib/python-dmidecode.spec b/contrib/python-dmidecode.spec index 9589179..b016a72 100644 --- a/contrib/python-dmidecode.spec +++ b/contrib/python-dmidecode.spec @@ -3,7 +3,7 @@ Summary: Python module to access DMI data Name: python-dmidecode -Version: 3.10.15 +Version: 3.11.1 Release: 1%{?dist} License: GPLv2 Group: System Environment/Libraries @@ -49,6 +49,9 @@ rm -rf $RPM_BUILD_ROOT %{_datadir}/python-dmidecode/ %changelog +* Thu Jul 4 2013 David Sommerseth - 3.11.1-1 +- Updated against upstream v3.11.1, which realigns against dmidecode 2.11 + * Wed Jul 3 2013 David Sommerseth - 3.10.15-1 - Update to new release diff --git a/src/dmidecode.c b/src/dmidecode.c index dae2fef..36f390b 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -2,9 +2,9 @@ /*. ******* coding:utf-8 AUTOHEADER START v1.1 ******* *. vim: fileencoding=utf-8 syntax=c sw=2 ts=2 et *. - *. © 2007-2009 Nima Talebi - *. © 2009 David Sommerseth - *. © 2002-2008 Jean Delvare + *. © 2007-2013 Nima Talebi + *. © 2009-2013 David Sommerseth + *. © 2002-2010 Jean Delvare *. © 2000-2002 Alan Cox *. *. This file is part of Python DMI-Decode. @@ -44,17 +44,17 @@ * DMI Decode * * 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/. + * Management BIOS Reference Specification, Version 2.7.0" document, + * available from http://www.dmtf.org/standards/smbios. * * Note to contributors: * Please reference every value you add or modify, especially if the * information does not come from the above mentioned specification. * * Additional references: - * - Intel AP-485 revision 32 + * - Intel AP-485 revision 36 * "Intel Processor Identification and the CPUID Instruction" - * http://developer.intel.com/design/xeon/applnots/241618.htm + * http://www.intel.com/support/processors/sb/cs-009861.htm * - DMTF Common Information Model * CIM Schema version 2.19.1 * http://www.dmtf.org/standards/cim/ @@ -65,6 +65,9 @@ * "CPUID Specification" * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25481.pdf * - BIOS Integrity Services Application Programming Interface version 1.0 + * - DMTF DSP0239 version 1.1.0 + * "Management Component Transport Protocol (MCTP) IDs and Codes" + * http://www.dmtf.org/standards/pmci * http://www.intel.com/design/archives/wfm/downloads/bisspec.htm * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * @@ -89,6 +92,8 @@ #include "dmihelper.h" +#define SUPPORTED_SMBIOS_VER 0x0207 + /******************************************************************************* ** Type-independant Stuff */ @@ -168,12 +173,15 @@ xmlNode *dmi_smbios_structure_type(xmlNode *node, u8 code) {"Management Device Threshold Data","ManagementDevice", "type", "Threshold Data"}, {"Memory Channel", "MemoryChannel", NULL, NULL}, {"IPMI Device", "IPMIdevice", NULL, NULL}, - {"Power Supply", "PowerSupply", NULL, NULL} /* 39 */ + {"Power Supply", "PowerSupply", NULL, NULL}, /* 39 */ + {"Additional Information", "AdditionalInfo", NULL, NULL}, + {"Onboard Device", "OnboardDevice", NULL, NULL}, /* 41 */ + {"Management Controller Host Interface", "MgmntCtrltHostIntf", NULL, NULL}, /* 42 */ /* *INDENT-ON* */ }; xmlNode *type_n = NULL; - if(code <= 39) { + if(code <= 42) { type_n = xmlNewChild(node, NULL, (xmlChar *)types[code].tagname, NULL); assert( type_n != NULL ); @@ -254,8 +262,55 @@ void dmi_dump(xmlNode *node, struct dmi_header * h) dump_n = NULL; } + +/* shift is 0 if the value is in bytes, 1 if it is in kilobytes */ +static void dmi_add_memory_size(xmlNode *node, u64 code, int shift) +{ + unsigned long capacity; + u16 split[7]; + static const char *unit[8] = { + "bytes", "kB", "MB", "GB", "TB", "PB", "EB", "ZB" + }; + int i; + + /* + * We split the overall size in powers of thousand: EB, PB, TB, GB, + * MB, kB and B. In practice, it is expected that only one or two + * (consecutive) of these will be non-zero. + */ + split[0] = code.l & 0x3FFUL; + split[1] = (code.l >> 10) & 0x3FFUL; + split[2] = (code.l >> 20) & 0x3FFUL; + split[3] = ((code.h << 2) & 0x3FCUL) | (code.l >> 30); + split[4] = (code.h >> 8) & 0x3FFUL; + split[5] = (code.h >> 18) & 0x3FFUL; + split[6] = code.h >> 28; + + /* + * Now we find the highest unit with a non-zero value. If the following + * is also non-zero, we use that as our base. If the following is zero, + * we simply display the highest unit. + */ + for (i = 6; i > 0; i--) { + if (split[i]) + break; + } + if (i > 0 && split[i - 1]) { + i--; + capacity = split[i] + (split[i + 1] << 10); + } else { + capacity = split[i]; + } + + dmixml_AddAttribute(node, "unit", unit[i + shift]); + dmixml_AddTextContent(node, "%lu", capacity); +} + + + + /******************************************************************************* -** 3.3.1 BIOS Information (Type 0) +** 7.1 BIOS Information (Type 0) */ void dmi_bios_runtime_size(xmlNode *node, u32 code) @@ -273,7 +328,7 @@ void dmi_bios_runtime_size(xmlNode *node, u32 code) } } -/* 3.3.1.1 */ +/* 7.1.1 */ void dmi_bios_characteristics(xmlNode *node, u64 code) { static const char *characteristics[] = { @@ -296,9 +351,9 @@ void dmi_bios_characteristics(xmlNode *node, u64 code) "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\"/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\"/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)", @@ -307,7 +362,7 @@ void dmi_bios_characteristics(xmlNode *node, u64 code) "CGA/mono video services are supported (int 10h)", "NEC PC-98" /* 31 */ }; - dmixml_AddAttribute(node, "dmispec", "3.3.1.1"); + dmixml_AddAttribute(node, "dmispec", "7.1.1"); dmixml_AddAttribute(node, "flags", "0x%04x", code); if(code.l&(1<<3)) { @@ -325,7 +380,7 @@ void dmi_bios_characteristics(xmlNode *node, u64 code) } } -/* 3.3.1.2.1 */ +/* 7.1.2.1 */ void dmi_bios_characteristics_x1(xmlNode *node, u8 code) { int i = 0; @@ -340,7 +395,7 @@ void dmi_bios_characteristics_x1(xmlNode *node, u8 code) "Smart battery" /* 7 */ }; - dmixml_AddAttribute(node, "dmispec", "3.3.1.2.1"); + dmixml_AddAttribute(node, "dmispec", "7.1.2.1"); dmixml_AddAttribute(node, "flags", "0x%04x", code); for(i = 0; i <= 7; i++) { @@ -349,27 +404,29 @@ void dmi_bios_characteristics_x1(xmlNode *node, u8 code) } } -/* 3.3.1.2.2 */ +/* 7.1.2.2 */ 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 */ + "Targeted content distribution", /* 2 */ + "UEFI is supported", + "System is a virtual machine" /* 4 */ }; - dmixml_AddAttribute(node, "dmispec", "3.3.1.2.2"); + dmixml_AddAttribute(node, "dmispec", "7.1.2.2"); dmixml_AddAttribute(node, "flags", "0x%04x", code); - for(i = 0; i <= 2; i++) { + for(i = 0; i <= 4; 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) +** 7.2 System Information (Type 1) */ void dmi_system_uuid(xmlNode *node, const u8 * p, u16 ver) @@ -386,9 +443,9 @@ void dmi_system_uuid(xmlNode *node, const u8 * p, u16 ver) } uuid_n = xmlNewChild(node, NULL, (xmlChar *) "SystemUUID", NULL); - dmixml_AddAttribute(uuid_n, "dmispec", "3.3.2"); + dmixml_AddAttribute(uuid_n, "dmispec", "7.2"); - if(only0xFF ) { + if(only0xFF) { dmixml_AddAttribute(uuid_n, "unavailable", "1"); dmixml_AddTextContent(uuid_n, "Not Present"); return; @@ -401,7 +458,7 @@ void dmi_system_uuid(xmlNode *node, const u8 * p, u16 ver) } /* - * As off version 2.6 of the SMBIOS specification, the first 3 + * As of 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 @@ -421,7 +478,7 @@ void dmi_system_uuid(xmlNode *node, const u8 * p, u16 ver) } } -/* 3.3.2.1 */ +/* 7.2.2 */ void dmi_system_wake_up_type(xmlNode *node, u8 code) { static const char *type[] = { @@ -437,7 +494,7 @@ void dmi_system_wake_up_type(xmlNode *node, u8 code) }; 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, "dmispec", "7.2.2"); dmixml_AddAttribute(swut_n, "flags", "0x%04x", code); if(code <= 0x08) { @@ -448,10 +505,10 @@ void dmi_system_wake_up_type(xmlNode *node, u8 code) } /******************************************************************************* -** 3.3.3 Base Board Information (Type 2) +** 7.3 Base Board Information (Type 2) */ -/* 3.3.3.1 */ +/* 7.3.1 */ void dmi_base_board_features(xmlNode *node, u8 code) { static const char *features[] = { @@ -464,7 +521,7 @@ void dmi_base_board_features(xmlNode *node, u8 code) 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, "dmispec", "7.3.1"); dmixml_AddAttribute(feat_n, "flags", "0x%04x", code); if((code & 0x1F) != 0) { @@ -482,7 +539,7 @@ void dmi_base_board_features(xmlNode *node, u8 code) void dmi_base_board_type(xmlNode *node, const char *tagname, u8 code) { - /* 3.3.3.2 */ + /* 7.3.2 */ static const char *type[] = { "Unknown", /* 0x01 */ "Other", @@ -500,7 +557,7 @@ void dmi_base_board_type(xmlNode *node, const char *tagname, u8 code) }; 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, "dmispec", "7.3.2"); dmixml_AddAttribute(type_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x0D) { @@ -528,10 +585,10 @@ void dmi_base_board_handles(xmlNode *node, u8 count, const u8 * p) } /******************************************************************************* -** 3.3.4 Chassis Information (Type 3) +** 7.4 Chassis Information (Type 3) */ -/* 3.3.4.1 */ +/* 7.4.1 */ void dmi_chassis_type(xmlNode *node, u8 code) { static const char *type[] = { @@ -567,7 +624,7 @@ void dmi_chassis_type(xmlNode *node, u8 code) }; 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, "dmispec", "7.4.1"); dmixml_AddAttribute(type_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x1B) { @@ -586,25 +643,25 @@ void dmi_chassis_lock(xmlNode *node, u8 code) }; 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, "dmispec", "7.4.1"); dmixml_AddAttribute(lock_n, "flags", "0x%04x", code); dmixml_AddTextContent(lock_n, "%s", lock[code]); } -/* 3.3.4.2 */ +/* 7.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 */ + "Safe", "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, "dmispec", "7.4.2"); dmixml_AddAttribute(state_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x06) { @@ -614,7 +671,7 @@ void dmi_chassis_state(xmlNode *node, const char *tagname, u8 code) } } -/* 3.3.4.3 */ +/* 7.4.3 */ void dmi_chassis_security_status(xmlNode *node, u8 code) { static const char *status[] = { @@ -626,7 +683,7 @@ void dmi_chassis_security_status(xmlNode *node, u8 code) }; 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, "dmispec", "7.4.3"); dmixml_AddAttribute(secstat_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x05) { @@ -691,12 +748,12 @@ void dmi_chassis_elements(xmlNode *node, u8 count, u8 len, const u8 * p) } /******************************************************************************* -** 3.3.5 Processor Information (Type 4) +** 7.5 Processor Information (Type 4) */ void dmi_processor_type(xmlNode *node, u8 code) { - /* 3.3.5.1 */ + /* 7.5.1 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", @@ -716,13 +773,13 @@ void dmi_processor_type(xmlNode *node, u8 code) } } -void dmi_processor_family(xmlNode *node, const struct dmi_header *h) +void dmi_processor_family(xmlNode *node, const struct dmi_header *h, u16 ver) { const u8 *data = h->data; unsigned int i, low, high; u16 code; - /* 3.3.5.2 */ + /* 7.5.2 */ static struct { int value; const char *name; @@ -747,8 +804,8 @@ void dmi_processor_family(xmlNode *node, const struct dmi_header *h) { 0x11, "Pentium III" }, { 0x12, "M1" }, { 0x13, "M2" }, - { 0x14, "Celeron M" }, /* From CIM_Processor.Family */ - { 0x15, "Pentium 4 HT" }, /* From CIM_Processor.Family */ + { 0x14, "Celeron M" }, + { 0x15, "Pentium 4 HT" }, { 0x18, "Duron" }, { 0x19, "K5" }, @@ -766,10 +823,10 @@ void dmi_processor_family(xmlNode *node, const struct dmi_header *h) { 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 */ + { 0x28, "Core Duo" }, + { 0x29, "Core Duo Mobile" }, + { 0x2A, "Core Solo Mobile" }, + { 0x2B, "Atom" }, { 0x30, "Alpha" }, { 0x31, "Alpha 21064" }, @@ -779,6 +836,12 @@ void dmi_processor_family(xmlNode *node, const struct dmi_header *h) { 0x35, "Alpha 21164a" }, { 0x36, "Alpha 21264" }, { 0x37, "Alpha 21364" }, + { 0x38, "Turion II Ultra Dual-Core Mobile M" }, + { 0x39, "Turion II Dual-Core Mobile M" }, + { 0x3A, "Athlon II Dual-Core M" }, + { 0x3B, "Opteron 6100" }, + { 0x3C, "Opteron 4100" }, + { 0x40, "MIPS" }, { 0x41, "MIPS R4000" }, @@ -820,12 +883,12 @@ void dmi_processor_family(xmlNode *node, const struct dmi_header *h) { 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 */ + { 0x8A, "Quad-Core Opteron" }, + { 0x8B, "Third-Generation Opteron" }, + { 0x8C, "Phenom FX" }, + { 0x8D, "Phenom X4" }, + { 0x8E, "Phenom X2" }, + { 0x8F, "Athlon X2" }, { 0x90, "PA-RISC" }, { 0x91, "PA-RISC 8500" }, { 0x92, "PA-RISC 8000" }, @@ -835,17 +898,21 @@ void dmi_processor_family(xmlNode *node, const struct dmi_header *h) { 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 */ - + { 0xA1, "Quad-Core Xeon 3200" }, + { 0xA2, "Dual-Core Xeon 3000" }, + { 0xA3, "Quad-Core Xeon 5300" }, + { 0xA4, "Dual-Core Xeon 5100" }, + { 0xA5, "Dual-Core Xeon 5000" }, + { 0xA6, "Dual-Core Xeon LV" }, + { 0xA7, "Dual-Core Xeon ULV" }, + { 0xA8, "Dual-Core Xeon 7100" }, + { 0xA9, "Quad-Core Xeon 5400" }, + { 0xAA, "Quad-Core Xeon" }, + { 0xAB, "Dual-Core Xeon 5200" }, + { 0xAC, "Dual-Core Xeon 7200" }, + { 0xAD, "Quad-Core Xeon 7300" }, + { 0xAE, "Quad-Core Xeon 7400" }, + { 0xAF, "Multi-Core Xeon 7400" }, { 0xB0, "Pentium III Xeon" }, { 0xB1, "Pentium III Speedstep" }, { 0xB2, "Pentium 4" }, @@ -862,24 +929,50 @@ void dmi_processor_family(xmlNode *node, const struct dmi_header *h) { 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 */ - + { 0xC0, "Core 2 Solo" }, + { 0xC1, "Core 2 Extreme" }, + { 0xC2, "Core 2 Quad" }, + { 0xC3, "Core 2 Extreme Mobile" }, + { 0xC4, "Core 2 Duo Mobile" }, + { 0xC5, "Core 2 Solo Mobile" }, + { 0xC6, "Core i7" }, + { 0xC7, "Dual-Core Celeron" }, { 0xC8, "IBM390" }, { 0xC9, "G4" }, { 0xCA, "G5" }, { 0xCB, "ESA/390 G6" }, { 0xCC, "z/Architectur" }, + { 0xCD, "Core i5" }, + { 0xCE, "Core i3" }, { 0xD2, "C7-M" }, { 0xD3, "C7-D" }, { 0xD4, "C7" }, { 0xD5, "Eden" }, + { 0xD6, "Multi-Core Xeon" }, + { 0xD7, "Dual-Core Xeon 3xxx" }, + { 0xD8, "Quad-Core Xeon 3xxx" }, + { 0xD9, "Nano" }, + { 0xDA, "Dual-Core Xeon 5xxx" }, + { 0xDB, "Quad-Core Xeon 5xxx" }, + + { 0xDD, "Dual-Core Xeon 7xxx" }, + { 0xDE, "Quad-Core Xeon 7xxx" }, + { 0xDF, "Multi-Core Xeon 7xxx" }, + { 0xE0, "Multi-Core Xeon 3400" }, + + { 0xE6, "Embedded Opteron Quad-Core" }, + { 0xE7, "Phenom Triple-Core" }, + { 0xE8, "Turion Ultra Dual-Core Mobile" }, + { 0xE9, "Turion Dual-Core Mobile" }, + { 0xEA, "Athlon Dual-Core" }, + { 0xEB, "Sempron SI" }, + { 0xEC, "Phenom II" }, + { 0xED, "Athlon II" }, + { 0xEE, "Six-Core Opteron" }, + { 0xEF, "Sempron M" }, + { 0xFA, "i860" }, { 0xFB, "i960" }, @@ -909,7 +1002,18 @@ void dmi_processor_family(xmlNode *node, const struct dmi_header *h) xmlNode *family_n = xmlNewChild(node, NULL, (xmlChar *) "Family", NULL); assert( family_n != NULL ); - dmixml_AddAttribute(family_n, "dmispec", "3.3.3.5"); + dmixml_AddAttribute(family_n, "dmispec", "7.5.2"); + + /* Special case for ambiguous value 0x30 (SMBIOS 2.0 only) */ + if (ver == 0x0200 && data[0x06] == 0x30 && h->length >= 0x08) { + const char *manufacturer = dmi_string(h, data[0x07]); + + if (strstr(manufacturer, "Intel") != NULL + || strncasecmp(manufacturer, "Intel", 5) == 0) { + dmixml_AddTextContent(family_n, "Pentium Pro"); + return; + } + } code = (data[0x06] == 0xFE && h->length >= 0x2A) ? WORD(data + 0x28) : data[0x06]; @@ -966,7 +1070,7 @@ void dmi_processor_family(xmlNode *node, const struct dmi_header *h) xmlNode *dmi_processor_id(xmlNode *node, const struct dmi_header *h) { - /* Intel AP-485 revision 31, table 3-4 */ + /* Intel AP-485 revision 36, table 2-4 */ static struct _cpuflags { const char *flag; const char *descr; @@ -996,13 +1100,13 @@ xmlNode *dmi_processor_id(xmlNode *node, const struct dmi_header *h) {"DS", "DS (Debug store)"}, {"ACPI", "ACPI (ACPI supported)"}, {"MMX", "MMX (MMX technology supported)"}, - {"FXSR", "FXSR (Fast floating-point save and restore)"}, + {"FXSR", "FXSR (FXSAVE and FXSTOR instructions supported)"}, {"SSE", "SSE (Streaming SIMD extensions)"}, {"SSE2", "SSE2 (Streaming SIMD extensions 2)"}, {"SS", "SS (Self-snoop)"}, - {"HTT", "HTT (Hyper-threading technology)"}, + {"HTT", "HTT (Multi-threading)"}, {"TM", "TM (Thermal monitor supported)"}, - {"IA64", "IA64 (IA64 capabilities)"}, + {NULL, NULL}, {"PBE", "PBE (Pending break enabled)"} /* 31 */ /* *INDENT-ON* */ }; @@ -1016,7 +1120,7 @@ xmlNode *dmi_processor_id(xmlNode *node, const struct dmi_header *h) assert( h && h->data ); type = h->data[0x06]; p = h->data + 8; - version = dmi_string(h, h->data[0x10]); + version = (char *) dmi_string(h, h->data[0x10]); /* ** Extra flags are now returned in the ECX register when one calls @@ -1066,22 +1170,24 @@ xmlNode *dmi_processor_id(xmlNode *node, const struct dmi_header *h) dx & 0xF); return data_n; } - } else if((type >= 0x0B && type <= 0x15) /* Intel, Cyrix */ + } 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 */ + ||(type >= 0xA1 && type <= 0xB3) /* Intel */ + ||type == 0xB5 /* Intel */ + ||(type >= 0xB9 && type <= 0xC7) /* Intel */ + ||(type >= 0xCD && type <= 0xCE) /* Intel */ + ||(type >= 0xD2 && type <= 0xDB) /* VIA, Intel */ + ||(type >= 0xDD && type <= 0xE0) /* Intel */ ) { 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 */ + ||(type >= 0x38 && type <= 0x3C) /* AMD */ + ||(type >= 0x83 && type <= 0x8F) /* AMD */ + ||(type >= 0xB6 && type <= 0xB7) /* AMD */ + ||(type >= 0xE6 && type <= 0xEF) /* AMD */ ) { sig = 2; @@ -1135,7 +1241,7 @@ xmlNode *dmi_processor_id(xmlNode *node, const struct dmi_header *h) edx = DWORD(p + 4); flags_n = xmlNewChild(data_n, NULL, (xmlChar *) "cpu_flags", NULL); - if((edx & 0xFFEFFBFF) != 0) { + if((edx & 0xBFEFFBFF) != 0) { int i; for(i = 0; i <= 31; i++) { @@ -1150,7 +1256,7 @@ xmlNode *dmi_processor_id(xmlNode *node, const struct dmi_header *h) return data_n; } -/* 3.3.5.4 */ +/* 7.5.4 */ void dmi_processor_voltage(xmlNode *node, u8 code) { static const char *voltage[] = { @@ -1161,7 +1267,7 @@ void dmi_processor_voltage(xmlNode *node, u8 code) 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, "dmispec", "7.5.4"); dmixml_AddAttribute(vltg_n, "flags", "0x%04x", code); if(code & 0x80) { @@ -1216,7 +1322,7 @@ void dmi_processor_status(xmlNode *node, u8 code) void dmi_processor_upgrade(xmlNode *node, u8 code) { - /* 3.3.5.5 */ + /* 7.5.5 */ static const char *upgrade[] = { "Other", /* 0x01 */ "Unknown", @@ -1241,14 +1347,22 @@ void dmi_processor_upgrade(xmlNode *node, u8 code) "Socket LGA775", /* 0x15 */ "Socket S1", "Socket AM2", - "Socket F (1207)" /* 0x18 */ + "Socket F (1207)", /* 0x18 */ + "Socket LGA1366", + "Socket G34", + "Socket AM3", + "Socket C32", + "Socket LGA1156", + "Socket LGA1567", + "Socket PGA988A", + "Socket BGA1288" /* 0x20 */ }; 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, "dmispec", "7.5.5"); dmixml_AddAttribute(upgr_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x15) { + if(code >= 0x01 && code <= 0x20) { dmixml_AddTextContent(upgr_n, "%s", upgrade[code - 0x01]); } else { dmixml_AddAttribute(upgr_n, "outofspec", "1"); @@ -1276,23 +1390,28 @@ void dmi_processor_cache(xmlNode *cache_n, u16 code, u16 ver) } } -/* 3.3.5.9 */ +/* 7.5.9 */ void dmi_processor_characteristics(xmlNode *node, u16 code) { static const char *characteristics[] = { "Unknown", /* 1 */ - "64-bit capable" /* 2 */ + "64-bit capable", /* 2 */ + "Multi-Core", + "Hardware Thread", + "Execute Protection", + "Enhanced Virtualization", + "Power/Performance Control" /* 7 */ }; 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, "dmispec", "7.5.9"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if((code & 0x0004) != 0) { + if((code & 0x00FC) != 0) { int i; - for(i = 1; i <= 2; i++) { + for(i = 1; i <= 7; i++) { if(code & (1 << i)) { dmixml_AddTextChild(data_n, "Flag", "%s", characteristics[i - 1]); } @@ -1301,12 +1420,12 @@ void dmi_processor_characteristics(xmlNode *node, u16 code) } /******************************************************************************* -** 3.3.6 Memory Controller Information (Type 5) +** 7.6 Memory Controller Information (Type 5) */ void dmi_memory_controller_ed_method(xmlNode *node, u8 code) { - /* 3.3.6.1 */ + /* 7.6.1 */ static const char *method[] = { "Other", /* 0x01 */ "Unknown", @@ -1319,7 +1438,7 @@ void dmi_memory_controller_ed_method(xmlNode *node, u8 code) }; 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, "dmispec", "7.6.1"); dmixml_AddAttribute(ercm_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x08) { @@ -1329,7 +1448,7 @@ void dmi_memory_controller_ed_method(xmlNode *node, u8 code) } } -/* 3.3.6.2 */ +/* 7.6.2 */ void dmi_memory_controller_ec_capabilities(xmlNode *node, const char *tagname, u8 code) { static const char *capabilities[] = { @@ -1343,7 +1462,7 @@ void dmi_memory_controller_ec_capabilities(xmlNode *node, const char *tagname, u 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, "dmispec", "7.6.2"); dmixml_AddAttribute(cap_n, "flags", "0x%04x", code); if((code & 0x3F) != 0) { @@ -1360,7 +1479,7 @@ void dmi_memory_controller_ec_capabilities(xmlNode *node, const char *tagname, u void dmi_memory_controller_interleave(xmlNode *node, const char *tagname, u8 code) { - /* 3.3.6.3 */ + /* 7.6.3 */ static const char *interleave[] = { "Other", /* 0x01 */ "Unknown", @@ -1372,7 +1491,7 @@ void dmi_memory_controller_interleave(xmlNode *node, const char *tagname, u8 cod }; 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, "dmispec", "7.6.3"); dmixml_AddAttribute(mci_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x07) { @@ -1382,7 +1501,7 @@ void dmi_memory_controller_interleave(xmlNode *node, const char *tagname, u8 cod } } -/* 3.3.6.4 */ +/* 7.6.4 */ void dmi_memory_controller_speeds(xmlNode *node, u16 code) { static struct { @@ -1397,7 +1516,7 @@ void dmi_memory_controller_speeds(xmlNode *node, u16 code) }; 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, "dmispec", "7.6.4"); dmixml_AddAttribute(mcs_n, "flags", "0x%04x", code); if((code & 0x001F) == 0) { @@ -1429,10 +1548,10 @@ void dmi_memory_controller_slots(xmlNode *node, u8 count, const u8 * p) } /******************************************************************************* -** 3.3.7 Memory Module Information (Type 6) +** 7.7 Memory Module Information (Type 6) */ -/* 3.3.7.1 */ +/* 7.7.1 */ void dmi_memory_module_types(xmlNode *node, const char *tagname, u16 code) { static const char *types[] = { @@ -1450,7 +1569,7 @@ void dmi_memory_module_types(xmlNode *node, const char *tagname, u16 code) }; 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, "dmispec", "7.7.1"); dmixml_AddAttribute(mmt_n, "flags", "0x%04x", code); if((code & 0x07FF) != 0) { @@ -1496,14 +1615,14 @@ void dmi_memory_module_speed(xmlNode *node, const char *tagname, u8 code) } } -/* 3.3.7.2 */ +/* 7.7.2 */ 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, "dmispec", "7.7.2"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); switch (code & 0x7F) { @@ -1549,7 +1668,7 @@ void dmi_memory_module_error(xmlNode *node, u8 code) } /******************************************************************************* -** 3.3.8 Cache Information (Type 7) +** 7.8 Cache Information (Type 7) */ static const char *dmi_cache_mode(u8 code) { @@ -1574,7 +1693,7 @@ void dmi_cache_location(xmlNode *node, u8 code) 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, "dmispec", "7.8"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(location[code] != NULL) { @@ -1588,7 +1707,7 @@ 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, "dmispec", "7.8"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code & 0x8000) { @@ -1600,7 +1719,7 @@ void dmi_cache_size(xmlNode *node, const char *tagname, u16 code) } } -/* 3.3.8.2 */ +/* 7.8.2 */ void dmi_cache_types(xmlNode *node, const char *tagname, u16 code) { static const char *types[] = { @@ -1615,7 +1734,7 @@ void dmi_cache_types(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.2"); + dmixml_AddAttribute(data_n, "dmispec", "7.8.2"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); @@ -1632,7 +1751,7 @@ void dmi_cache_types(xmlNode *node, const char *tagname, u16 code) void dmi_cache_ec_type(xmlNode *node, u8 code) { - /* 3.3.8.3 */ + /* 7.8.3 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", @@ -1643,7 +1762,7 @@ void dmi_cache_ec_type(xmlNode *node, u8 code) }; 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, "dmispec", "7.8.3"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x06) { @@ -1655,7 +1774,7 @@ void dmi_cache_ec_type(xmlNode *node, u8 code) void dmi_cache_type(xmlNode *node, u8 code) { - /* 3.3.8.4 */ + /* 7.8.4 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", @@ -1665,7 +1784,7 @@ void dmi_cache_type(xmlNode *node, u8 code) }; 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, "dmispec", "7.8.4"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x05) { @@ -1677,7 +1796,7 @@ void dmi_cache_type(xmlNode *node, u8 code) void dmi_cache_associativity(xmlNode *node, u8 code) { - /* 3.3.8.5 */ + /* 7.8.5 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", @@ -1686,14 +1805,19 @@ void dmi_cache_associativity(xmlNode *node, u8 code) "4-way Set-associative", "Fully Associative", "8-way Set-associative", - "16-way Set-associative" /* 0x08 */ + "16-way Set-associative", /* 0x08 */ + "12-way Set-associative", + "24-way Set-associative", + "32-way Set-associative", + "48-way Set-associative", + "64-way Set-associative" /* 0x0D */ }; 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, "dmispec", "7.8.5"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x08) { + if(code >= 0x01 && code <= 0x0D) { dmixml_AddTextContent(data_n, type[code - 0x01]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); @@ -1701,12 +1825,12 @@ void dmi_cache_associativity(xmlNode *node, u8 code) } /******************************************************************************* -** 3.3.9 Port Connector Information (Type 8) +** 7.9 Port Connector Information (Type 8) */ void dmi_port_connector_type(xmlNode *node, const char *tpref, u8 code) { - /* 3.3.9.2 */ + /* 7.9.2 */ static const char *type[] = { "None", /* 0x00 */ "Centronics", @@ -1754,7 +1878,7 @@ void dmi_port_connector_type(xmlNode *node, const char *tpref, u8 code) 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, "dmispec", "7.9.2"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); dmixml_AddAttribute(data_n, "type", "%s", tpref); @@ -1771,7 +1895,7 @@ void dmi_port_connector_type(xmlNode *node, const char *tpref, u8 code) void dmi_port_type(xmlNode *node, u8 code) { - /* 3.3.9.3 */ + /* 7.9.3 */ static const char *type[] = { "None", /* 0x00 */ "Parallel Port XT/AT Compatible", @@ -1815,7 +1939,7 @@ void dmi_port_type(xmlNode *node, u8 code) 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, "dmispec", "7.9.3"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code <= 0x21) { @@ -1830,12 +1954,12 @@ void dmi_port_type(xmlNode *node, u8 code) } /******************************************************************************* -** 3.3.10 System Slots (Type 9) +** 7.10 System Slots (Type 9) */ void dmi_slot_type(xmlNode *node, u8 code) { - /* 3.3.10.1 */ + /* 7.10.1 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", @@ -1868,16 +1992,22 @@ void dmi_slot_type(xmlNode *node, u8 code) "PCI Express x2", "PCI Express x4", "PCI Express x8", - "PCI Express x16" /* 0xAA */ + "PCI Express x16", /* 0xAA */ + "PCI Express 2", + "PCI Express 2 x1", + "PCI Express 2 x2", + "PCI Express 2 x4", + "PCI Express 2 x8", + "PCI Express 2 x16", /* 0xB0 */ }; 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, "dmispec", "7.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) { + } else if(code >= 0xA0 && code <= 0xB0) { dmixml_AddTextContent(data_n, "%s", type_0xA0[code - 0xA0]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); @@ -1886,7 +2016,7 @@ void dmi_slot_type(xmlNode *node, u8 code) void dmi_slot_bus_width(xmlNode *node, u8 code) { - /* 3.3.10.2 */ + /* 7.10.2 */ static const char *width[] = { "", /* 0x01, "Other" */ "", /* "Unknown" */ @@ -1905,7 +2035,7 @@ void dmi_slot_bus_width(xmlNode *node, u8 code) }; 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, "dmispec", "7.10.2"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if( (code >= 0x01) && (code <= 0x0E) ) { @@ -1917,7 +2047,7 @@ void dmi_slot_bus_width(xmlNode *node, u8 code) void dmi_slot_current_usage(xmlNode *node, u8 code) { - /* 3.3.10.3 */ + /* 7.10.3 */ static const char *usage[] = { "Other", /* 0x01 */ "Unknown", @@ -1927,7 +2057,7 @@ void dmi_slot_current_usage(xmlNode *node, u8 code) 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, "dmispec", "7.10.3"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); @@ -1938,7 +2068,7 @@ void dmi_slot_current_usage(xmlNode *node, u8 code) } } -/* 3.3.1O.4 */ +/* 7.1O.4 */ void dmi_slot_length(xmlNode *node, u8 code) { static const char *length[] = { @@ -1950,7 +2080,7 @@ void dmi_slot_length(xmlNode *node, u8 code) 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, "dmispec", "7.10.4"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x04) { @@ -1960,7 +2090,7 @@ void dmi_slot_length(xmlNode *node, u8 code) } } -/* 3.3.10.5 */ +/* 7.10.5 */ void inline set_slottype(xmlNode *node, u8 type) { switch (type) { case 0x04: /* MCA */ @@ -1983,8 +2113,21 @@ void inline set_slottype(xmlNode *node, u8 type) { dmixml_AddAttribute(node, "slottype", "PCI-X"); break; case 0xA5: /* PCI Express */ + case 0xA6: /* PCI Express */ + case 0xA7: /* PCI Express */ + case 0xA8: /* PCI Express */ + case 0xA9: /* PCI Express */ + case 0xAA: /* PCI Express */ dmixml_AddAttribute(node, "slottype", "PCI Express"); break; + case 0xAB: /* PCI Express 2*/ + case 0xAC: /* PCI Express 2*/ + case 0xAD: /* PCI Express 2*/ + case 0xAE: /* PCI Express 2*/ + case 0xAF: /* PCI Express 2*/ + case 0xB0: /* PCI Express 2*/ + dmixml_AddAttribute(node, "slottype", "PCI Express 2"); + break; case 0x07: /* PCMCIA */ dmixml_AddAttribute(node, "slottype", "PCMCIA"); break; @@ -1996,7 +2139,7 @@ void inline set_slottype(xmlNode *node, u8 type) { 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, "dmispec", "7.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); @@ -2015,6 +2158,17 @@ void dmi_slot_id(xmlNode *node, u8 code1, u8 code2, u8 type) case 0x12: /* PCI-X */ case 0x13: /* AGP */ case 0xA5: /* PCI Express */ + case 0xA6: /* PCI Express */ + case 0xA7: /* PCI Express */ + case 0xA8: /* PCI Express */ + case 0xA9: /* PCI Express */ + case 0xAA: /* PCI Express */ + case 0xAB: /* PCI Express 2 */ + case 0xAC: /* PCI Express 2 */ + case 0xAD: /* PCI Express 2 */ + case 0xAE: /* PCI Express 2 */ + case 0xAF: /* PCI Express 2 */ + case 0xB0: /* PCI Express 2 */ dmixml_AddAttribute(slotid_n, "id", "%i", code1); break; case 0x07: /* PCMCIA */ @@ -2029,7 +2183,7 @@ void dmi_slot_id(xmlNode *node, u8 code1, u8 code2, u8 type) void dmi_slot_characteristics(xmlNode *node, u8 code1, u8 code2) { - /* 3.3.10.6 */ + /* 7.10.6 */ static const char *characteristics1[] = { "5.0 V is provided", /* 1 */ "3.3 V is provided", @@ -2040,7 +2194,7 @@ void dmi_slot_characteristics(xmlNode *node, u8 code1, u8 code2) "Modem ring resume is supported" /* 7 */ }; - /* 3.3.10.7 */ + /* 7.10.7 */ static const char *characteristics2[] = { "PME signal is supported", /* 0 */ "Hot-plug devices are supported", @@ -2048,7 +2202,7 @@ void dmi_slot_characteristics(xmlNode *node, u8 code1, u8 code2) }; 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, "dmispec", "7.10.6, 7.10.7"); dmixml_AddAttribute(data_n, "flags1", "0x%04x", code1); dmixml_AddAttribute(data_n, "flags2", "0x%04x", code2); @@ -2080,10 +2234,10 @@ void dmi_slot_characteristics(xmlNode *node, u8 code1, u8 code2) void dmi_slot_segment_bus_func(xmlNode *node, u16 code1, u8 code2, u8 code3) { - /* 3.3.10.8 */ + /* 7.10.8 */ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "BusAddress", NULL); assert( data_n != NULL ); - dmixml_AddAttribute(data_n, "dmispec", "3.3.10.8"); + dmixml_AddAttribute(data_n, "dmispec", "7.10.8"); if(!(code1 == 0xFFFF && code2 == 0xFF && code3 == 0xFF)) { dmixml_AddTextContent(data_n, "%04x:%02x:%02x.%x", code1, code2, code3 >> 3, code3 & 0x7); @@ -2091,12 +2245,12 @@ void dmi_slot_segment_bus_func(xmlNode *node, u16 code1, u8 code2, u8 code3) } /******************************************************************************* -** 3.3.11 On Board Devices Information (Type 10) +** 7.11 On Board Devices Information (Type 10) */ void dmi_on_board_devices_type(xmlNode *node, u8 code) { - /* 3.3.11.1 */ + /* 7.11.1 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", @@ -2110,7 +2264,7 @@ void dmi_on_board_devices_type(xmlNode *node, u8 code) "SAS Controller" /* 0x0A */ }; - dmixml_AddAttribute(node, "dmispec", "3.3.11.1"); + dmixml_AddAttribute(node, "dmispec", "7.11.1, 7.42.2"); dmixml_AddAttribute(node, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x0A) { @@ -2128,7 +2282,7 @@ void dmi_on_board_devices(xmlNode *node, const char *tagname, const struct dmi_h xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); assert( data_n != NULL ); - dmixml_AddAttribute(data_n, "dmispec", "3.3.11"); + dmixml_AddAttribute(data_n, "dmispec", "7.11"); for(i = 0; i < count; i++) { xmlNode *dev_n = xmlNewChild(data_n, NULL, (xmlChar *) "Device", NULL); @@ -2142,7 +2296,7 @@ void dmi_on_board_devices(xmlNode *node, const char *tagname, const struct dmi_h } /******************************************************************************* - * 3.3.12 OEM Strings (Type 11) + * 7.12 OEM Strings (Type 11) */ void dmi_oem_strings(xmlNode *node, struct dmi_header *h) @@ -2161,7 +2315,7 @@ void dmi_oem_strings(xmlNode *node, struct dmi_header *h) } /******************************************************************************* -** 3.3.13 System Configuration Options (Type 12) +** 7.13 System Configuration Options (Type 12) */ void dmi_system_configuration_options(xmlNode *node, struct dmi_header *h) @@ -2172,7 +2326,7 @@ void dmi_system_configuration_options(xmlNode *node, struct dmi_header *h) 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, "dmispec", "7.13"); dmixml_AddAttribute(data_n, "count", "%i", count); for(i = 1; i <= count; i++) { @@ -2184,10 +2338,10 @@ void dmi_system_configuration_options(xmlNode *node, struct dmi_header *h) } /******************************************************************************* -** 3.3.14 BIOS Language Information (Type 13) +** 7.14 BIOS Language Information (Type 13) */ -void dmi_bios_languages(xmlNode *node, struct dmi_header *h) +void dmi_bios_languages(xmlNode *node, struct dmi_header *h, u8 brevity_code) { u8 *p = h->data + 4; u8 count = p[0x00]; @@ -2195,9 +2349,15 @@ void dmi_bios_languages(xmlNode *node, struct dmi_header *h) 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, "dmispec", "7.14"); dmixml_AddAttribute(data_n, "count", "%i", count); + if (brevity_code & 0x01) { + dmixml_AddAttribute(data_n, "format", "Abbreviated"); + } else { + dmixml_AddAttribute(data_n, "format", "Long"); + } + for(i = 1; i <= count; i++) { xmlNode *l_n = dmixml_AddDMIstring(data_n, "Language", h, i); assert( l_n != NULL ); @@ -2206,12 +2366,12 @@ void dmi_bios_languages(xmlNode *node, struct dmi_header *h) } /******************************************************************************* -** 3.3.15 Group Associations (Type 14) +** 7.15 Group Associations (Type 14) */ void dmi_group_associations_items(xmlNode *node, u8 count, const u8 * p) { - dmixml_AddAttribute(node, "dmispec", "3.3.15"); + dmixml_AddAttribute(node, "dmispec", "7.15"); dmixml_AddAttribute(node, "items", "%i", count); int i; @@ -2225,7 +2385,7 @@ void dmi_group_associations_items(xmlNode *node, u8 count, const u8 * p) } /******************************************************************************* -** 3.3.16 System Event Log (Type 15) +** 7.16 System Event Log (Type 15) */ void dmi_event_log_method(xmlNode *node, u8 code) @@ -2240,7 +2400,7 @@ void dmi_event_log_method(xmlNode *node, u8 code) 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, "dmispec", "7.16"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code <= 0x04) { @@ -2266,10 +2426,9 @@ void dmi_event_log_status(xmlNode *node, u8 code) 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, "dmispec", "7.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]); } @@ -2278,10 +2437,10 @@ 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, "dmispec", "7.16.3"); dmixml_AddAttribute(data_n, "method", "0x%04x", method); - /* 3.3.16.3 */ + /* 7.16.3 */ switch (method) { case 0x00: case 0x01: @@ -2309,7 +2468,7 @@ void dmi_event_log_header_type(xmlNode *node, u8 code) 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, "dmispec", "7.16"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code <= 0x01) { @@ -2323,7 +2482,7 @@ void dmi_event_log_header_type(xmlNode *node, u8 code) void dmi_event_log_descriptor_type(xmlNode *node, u8 code) { - /* 3.3.16.6.1 */ + /* 7.16.6.1 */ static const char *type[] = { NULL, /* 0x00 */ "Single-bit ECC memory error", @@ -2353,7 +2512,7 @@ void dmi_event_log_descriptor_type(xmlNode *node, u8 code) 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, "dmispec", "7.16.6.1"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code <= 0x17 && type[code] != NULL) { @@ -2369,7 +2528,7 @@ void dmi_event_log_descriptor_type(xmlNode *node, u8 code) void dmi_event_log_descriptor_format(xmlNode *node, u8 code) { - /* 3.3.16.6.2 */ + /* 7.16.6.2 */ static const char *format[] = { "None", /* 0x00 */ "Handle", @@ -2382,7 +2541,7 @@ void dmi_event_log_descriptor_format(xmlNode *node, u8 code) 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, "dmispec", "7.16.6.2"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code <= 0x06) { @@ -2396,10 +2555,10 @@ void dmi_event_log_descriptor_format(xmlNode *node, u8 code) void dmi_event_log_descriptors(xmlNode *node, u8 count, const u8 len, const u8 * p) { - /* 3.3.16.1 */ + /* 7.16.1 */ int i; - dmixml_AddAttribute(node, "dmispec", "3.3.16.1"); + dmixml_AddAttribute(node, "dmispec", "7.16.1"); for(i = 0; i < count; i++) { if(len >= 0x02) { @@ -2413,12 +2572,12 @@ void dmi_event_log_descriptors(xmlNode *node, u8 count, const u8 len, const u8 * } /******************************************************************************* -** 3.3.17 Physical Memory Array (Type 16) +** 7.17 Physical Memory Array (Type 16) */ void dmi_memory_array_location(xmlNode *node, u8 code) { - /* 3.3.17.1 */ + /* 7.17.1 */ static const char *location[] = { "Other", /* 0x01 */ "Unknown", @@ -2441,7 +2600,7 @@ void dmi_memory_array_location(xmlNode *node, u8 code) 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, "dmispec", "7.17.1"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x0A) { @@ -2455,7 +2614,7 @@ void dmi_memory_array_location(xmlNode *node, u8 code) void dmi_memory_array_use(xmlNode *node, u8 code) { - /* 3.3.17.2 */ + /* 7.17.2 */ static const char *use[] = { "Other", /* 0x01 */ "Unknown", @@ -2467,7 +2626,7 @@ void dmi_memory_array_use(xmlNode *node, u8 code) }; 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, "dmispec", "7.17.2"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x07) { @@ -2479,7 +2638,7 @@ void dmi_memory_array_use(xmlNode *node, u8 code) void dmi_memory_array_ec_type(xmlNode *node, u8 code) { - /* 3.3.17.3 */ + /* 7.17.3 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", @@ -2492,7 +2651,7 @@ void dmi_memory_array_ec_type(xmlNode *node, u8 code) 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, "dmispec", "7.17.3"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x07) { @@ -2502,25 +2661,23 @@ void dmi_memory_array_ec_type(xmlNode *node, u8 code) } } -void dmi_memory_array_capacity(xmlNode *node, u32 code) +void dmi_memory_array_capacity(xmlNode *node, struct dmi_header *h, const u8 *data) { 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); + if(DWORD(data + 0x07) == 0x8000000) { + if( h->length < 0x17 ) { + dmixml_AddAttribute(data_n, "unknown", "1"); } else { - dmixml_AddAttribute(data_n, "unit", "KB"); - dmixml_AddTextContent(data_n, "%i", code); + dmi_add_memory_size(data_n, QWORD(data + 0x0F), 0); } + } else { + u64 capacity; + + capacity.h = 0; + capacity.l = DWORD(data + 0x07); + dmi_add_memory_size(data_n, capacity, 1); } } @@ -2539,7 +2696,7 @@ void dmi_memory_array_error_handle(xmlNode *node, u16 code) } /******************************************************************************* -** 3.3.18 Memory Device (Type 17) +** 7.18 Memory Device (Type 17) */ void dmi_memory_device_width(xmlNode *node, const char *tagname, u16 code) @@ -2575,9 +2732,33 @@ void dmi_memory_device_size(xmlNode *node, u16 code) } } + +static void dmi_memory_device_extended_size(xmlNode *node, u32 code) +{ + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Size", NULL); + assert( data_n != NULL ); + + code &= 0x7FFFFFFFUL; + dmixml_AddAttribute(data_n, "flags", "0x%08x", code); + dmixml_AddAttribute(data_n, "mode", "extended"); + + /* Use the most suitable unit depending on size */ + if (code & 0x3FFUL) { + dmixml_AddAttribute(data_n, "unit", "MB"); + dmixml_AddTextContent(data_n, "%lu", (unsigned long) code); + } else if (code & 0xFFFFFUL) { + dmixml_AddAttribute(data_n, "unit", "GB"); + dmixml_AddTextContent(data_n, "%lu", (unsigned long) code >> 10); + } else { + dmixml_AddAttribute(data_n, "unit", "TB"); + dmixml_AddTextContent(data_n, "%lu", (unsigned long) code >> 20); + } +} + + void dmi_memory_device_form_factor(xmlNode *node, u8 code) { - /* 3.3.18.1 */ + /* 7.18.1 */ static const char *form_factor[] = { "Other", /* 0x01 */ "Unknown", @@ -2597,7 +2778,7 @@ void dmi_memory_device_form_factor(xmlNode *node, u8 code) }; 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, "dmispec", "7.18.1"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x0F) { @@ -2622,7 +2803,7 @@ void dmi_memory_device_set(xmlNode *node, u8 code) void dmi_memory_device_type(xmlNode *node, u8 code) { - /* 3.3.18.2 */ + /* 7.18.2 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", @@ -2643,14 +2824,19 @@ void dmi_memory_device_type(xmlNode *node, u8 code) "RDRAM", "DDR", "DDR2", - "DDR2 FB-DIMM" /* 0x14 */ + "DDR2 FB-DIMM", /* 0x14 */ + "Reserved", + "Reserved", + "Reserved", + "DDR3" + "FBD2" /* 0x19 */ }; 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, "dmispec", "7.18.2"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x14) { + if(code >= 0x01 && code <= 0x19) { dmixml_AddTextContent(data_n, "%s", type[code - 0x01]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); @@ -2659,7 +2845,7 @@ void dmi_memory_device_type(xmlNode *node, u8 code) void dmi_memory_device_type_detail(xmlNode *node, u16 code) { - /* 3.3.18.3 */ + /* 7.18.3 */ static const char *detail[] = { "Other", /* 1 */ "Unknown", @@ -2672,16 +2858,18 @@ void dmi_memory_device_type_detail(xmlNode *node, u16 code) "EDO", "Window DRAM", "Cache DRAM", - "Non-Volatile" /* 12 */ + "Non-Volatile", /* 12 */ + "Registered (Buffered)", + "Unbuffered (Unregistered)" /* 14 */ }; 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, "dmispec", "7.18.3"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if((code & 0x1FFE) != 0) { int i; - for(i = 1; i <= 12; i++) { + for(i = 1; i <= 14; i++) { if(code & (1 << i)) { xmlNode *td_n = dmixml_AddTextChild(data_n, "flag", "%s", detail[i - 1]); assert( td_n != NULL ); @@ -2691,28 +2879,27 @@ void dmi_memory_device_type_detail(xmlNode *node, u16 code) } } -void dmi_memory_device_speed(xmlNode *node, u16 code) +void dmi_memory_device_speed(xmlNode *node, const char *tag, u16 code) { - xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Speed", NULL); + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tag, NULL); assert( data_n != NULL ); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code == 0) { dmixml_AddAttribute(data_n, "unknown", "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) +* 7.19 32-bit Memory Error Information (Type 18) */ void dmi_memory_error_type(xmlNode *node, u8 code) { - /* 3.3.19.1 */ + /* 7.19.1 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", @@ -2731,7 +2918,7 @@ void dmi_memory_error_type(xmlNode *node, u8 code) }; 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, "dmispec", "7.19.1"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x0E) { @@ -2743,7 +2930,7 @@ void dmi_memory_error_type(xmlNode *node, u8 code) void dmi_memory_error_granularity(xmlNode *node, u8 code) { - /* 3.3.19.2 */ + /* 7.19.2 */ static const char *granularity[] = { "Other", /* 0x01 */ "Unknown", @@ -2752,7 +2939,7 @@ void dmi_memory_error_granularity(xmlNode *node, u8 code) }; 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, "dmispec", "7.19.2"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x04) { @@ -2764,7 +2951,7 @@ void dmi_memory_error_granularity(xmlNode *node, u8 code) void dmi_memory_error_operation(xmlNode *node, u8 code) { - /* 3.3.19.3 */ + /* 7.19.3 */ static const char *operation[] = { "Other", /* 0x01 */ "Unknown", @@ -2774,7 +2961,7 @@ void dmi_memory_error_operation(xmlNode *node, u8 code) }; 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, "dmispec", "7.19.3"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x05) { @@ -2809,32 +2996,45 @@ void dmi_32bit_memory_error_address(xmlNode *node, char *tagname, u32 code) } /******************************************************************************* -** 3.3.20 Memory Array Mapped Address (Type 19) +** 7.20 Memory Array Mapped Address (Type 19) */ 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, "dmispec", "7.20"); 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); + u64 size; + + size.h = 0; + size.l = code; + dmi_add_memory_size(data_n, size, 1); + } +} + +void dmi_mapped_address_extended_size(xmlNode *node, u64 start, u64 end) +{ + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "RangeSize", NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "7.20"); + dmixml_AddAttribute(data_n, "mode", "extended"); + dmixml_AddAttribute(data_n, "start_address", "0x%08x%08x", start.h, start.l); + dmixml_AddAttribute(data_n, "end_address", "0x%08x%08x", end.h, end.l); + + if(start.h == end.h && start.l == end.l) { + dmixml_AddAttribute(data_n, "invalid", "1"); + } else { + dmi_add_memory_size(data_n, u64_range(start, end), 0); } } /******************************************************************************* -** 3.3.21 Memory Device Mapped Address (Type 20) +** 7.21 Memory Device Mapped Address (Type 20) */ void dmi_mapped_address_row_position(xmlNode *node, u8 code) @@ -2876,12 +3076,12 @@ void dmi_mapped_address_interleaved_data_depth(xmlNode *node, u8 code) } /******************************************************************************* -** 3.3.22 Built-in Pointing Device (Type 21) +** 7.22 Built-in Pointing Device (Type 21) */ void dmi_pointing_device_type(xmlNode *node, u8 code) { - /* 3.3.22.1 */ + /* 7.22.1 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", @@ -2895,7 +3095,7 @@ void dmi_pointing_device_type(xmlNode *node, u8 code) }; 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, "dmispec", "7.22.1"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x09) { @@ -2907,7 +3107,7 @@ void dmi_pointing_device_type(xmlNode *node, u8 code) void dmi_pointing_device_interface(xmlNode *node, u8 code) { - /* 3.3.22.2 */ + /* 7.22.2 */ static const char *interface[] = { "Other", /* 0x01 */ "Unknown", @@ -2925,7 +3125,7 @@ void dmi_pointing_device_interface(xmlNode *node, u8 code) }; 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, "dmispec", "7.22.2"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x08) { @@ -2938,12 +3138,12 @@ void dmi_pointing_device_interface(xmlNode *node, u8 code) } /******************************************************************************* -** 3.3.23 Portable Battery (Type 22) +** 7.23 Portable Battery (Type 22) */ void dmi_battery_chemistry(xmlNode *node, u8 code) { - /* 3.3.23.1 */ + /* 7.23.1 */ static const char *chemistry[] = { "Other", /* 0x01 */ "Unknown", @@ -2956,7 +3156,7 @@ void dmi_battery_chemistry(xmlNode *node, u8 code) }; 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, "dmispec", "7.22.2"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x08) { @@ -3005,7 +3205,7 @@ void dmi_battery_maximum_error(xmlNode *node, u8 code) } /******************************************************************************* -** 3.3.24 System Reset (Type 23) +** 7.24 System Reset (Type 23) */ void dmi_system_reset_boot_option(xmlNode *node, const char *tagname, u8 code) @@ -3054,7 +3254,7 @@ void dmi_system_reset_timer(xmlNode *node, const char *tagname, u16 code) } /******************************************************************************* - * 3.3.25 Hardware Security (Type 24) + * 7.25 Hardware Security (Type 24) */ void dmi_hardware_security_status(xmlNode *node, const char *tagname, u8 code) @@ -3072,7 +3272,7 @@ void dmi_hardware_security_status(xmlNode *node, const char *tagname, u8 code) } /******************************************************************************* -** 3.3.26 System Power Controls (Type 25) +** 7.26 System Power Controls (Type 25) */ #define DMI_POWER_CTRL_TIME_STR(dest, variant, data) \ @@ -3081,11 +3281,11 @@ void dmi_hardware_security_status(xmlNode *node, const char *tagname, u8 code) void dmi_power_controls_power_on(xmlNode *node, const char *tagname, const u8 * p) { - /* 3.3.26.1 */ + /* 7.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, "dmispec", "7.26.1"); dmixml_AddAttribute(data_n, "flags", "0x%08x", p); DMI_POWER_CTRL_TIME_STR(timestr[0], dmi_bcd_range(p[0], 0x01, 0x12), p[0]) @@ -3100,12 +3300,12 @@ void dmi_power_controls_power_on(xmlNode *node, const char *tagname, const u8 * } /******************************************************************************* -* 3.3.27 Voltage Probe (Type 26) +* 7.27 Voltage Probe (Type 26) */ void dmi_voltage_probe_location(xmlNode *node, u8 code) { - /* 3.3.27.1 */ + /* 7.27.1 */ static const char *location[] = { "Other", /* 0x01 */ "Unknown", @@ -3121,7 +3321,7 @@ void dmi_voltage_probe_location(xmlNode *node, u8 code) }; 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, "dmispec", "7.27.1"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x0B) { @@ -3133,7 +3333,7 @@ void dmi_voltage_probe_location(xmlNode *node, u8 code) void dmi_probe_status(xmlNode *node, u8 code) { - /* 3.3.27.1 */ + /* 7.27.1 */ static const char *status[] = { "Other", /* 0x01 */ "Unknown", @@ -3144,7 +3344,7 @@ void dmi_probe_status(xmlNode *node, u8 code) }; 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, "dmispec", "7.27.1"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x06) { @@ -3197,12 +3397,12 @@ void dmi_probe_accuracy(xmlNode *node, u16 code) } /******************************************************************************* -** 3.3.28 Cooling Device (Type 27) +** 7.28 Cooling Device (Type 27) */ void dmi_cooling_device_type(xmlNode *node, u8 code) { - /* 3.3.28.1 */ + /* 7.28.1 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", @@ -3220,7 +3420,7 @@ void dmi_cooling_device_type(xmlNode *node, u8 code) }; 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, "dmispec", "7.28.1", code); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x09) { @@ -3247,12 +3447,12 @@ void dmi_cooling_device_speed(xmlNode *node, u16 code) } /******************************************************************************* -** 3.3.29 Temperature Probe (Type 28) +** 7.29 Temperature Probe (Type 28) */ void dmi_temperature_probe_location(xmlNode *node, u8 code) { - /* 3.3.29.1 */ + /* 7.29.1 */ static const char *location[] = { "Other", /* 0x01 */ "Unknown", @@ -3272,7 +3472,7 @@ void dmi_temperature_probe_location(xmlNode *node, u8 code) }; 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, "dmispec", "7.29.1", code); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x0F) { @@ -3311,7 +3511,7 @@ void dmi_temperature_probe_resolution(xmlNode *node, u16 code) } /******************************************************************************* -** 3.3.30 Electrical Current Probe (Type 29) +** 7.30 Electrical Current Probe (Type 29) */ void dmi_current_probe_value(xmlNode *node, const char *tagname, u16 code) @@ -3343,7 +3543,7 @@ void dmi_current_probe_resolution(xmlNode *node, u16 code) } /******************************************************************************* -** 3.3.33 System Boot Information (Type 32) +** 7.33 System Boot Information (Type 32) */ void dmi_system_boot_status(xmlNode *node, u8 code) @@ -3375,7 +3575,7 @@ void dmi_system_boot_status(xmlNode *node, u8 code) } /******************************************************************************* -** 3.3.34 64-bit Memory Error Information (Type 33) +** 7.34 64-bit Memory Error Information (Type 33) */ void dmi_64bit_memory_error_address(xmlNode *node, const char *tagname, u64 code) @@ -3391,12 +3591,12 @@ void dmi_64bit_memory_error_address(xmlNode *node, const char *tagname, u64 code } /******************************************************************************* -** 3.3.35 Management Device (Type 34) +** 7.35 Management Device (Type 34) */ void dmi_management_device_type(xmlNode *node, u8 code) { - /* 3.3.35.1 */ + /* 7.35.1 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", @@ -3414,7 +3614,7 @@ void dmi_management_device_type(xmlNode *node, u8 code) }; 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, "dmispec", "7.35.1", code); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x0D) { @@ -3426,7 +3626,7 @@ void dmi_management_device_type(xmlNode *node, u8 code) void dmi_management_device_address_type(xmlNode *node, u8 code) { - /* 3.3.35.2 */ + /* 7.35.2 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", @@ -3436,7 +3636,7 @@ void dmi_management_device_address_type(xmlNode *node, u8 code) }; 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, "dmispec", "7.35.2", code); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x05) { @@ -3447,12 +3647,12 @@ void dmi_management_device_address_type(xmlNode *node, u8 code) } /******************************************************************************* -** 3.3.38 Memory Channel (Type 37) +** 7.38 Memory Channel (Type 37) */ void dmi_memory_channel_type(xmlNode *node, u8 code) { - /* 3.3.38.1 */ + /* 7.38.1 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", @@ -3461,7 +3661,7 @@ void dmi_memory_channel_type(xmlNode *node, u8 code) }; 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, "dmispec", "7.38.1", code); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x04) { @@ -3485,12 +3685,12 @@ void dmi_memory_channel_devices(xmlNode *node, u8 count, const u8 * p) } /******************************************************************************* -** 3.3.39 IPMI Device Information (Type 38) +** 7.39 IPMI Device Information (Type 38) */ void dmi_ipmi_interface_type(xmlNode *node, u8 code) { - /* 3.3.39.1 and IPMI 2.0, appendix C1, table C1-2 */ + /* 7.39.1 and IPMI 2.0, appendix C1, table C1-2 */ static const char *type[] = { "Unknown", /* 0x00 */ "KCS (Keyboard Control Style)", @@ -3500,7 +3700,7 @@ void dmi_ipmi_interface_type(xmlNode *node, u8 code) }; 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, "dmispec", "7.39.1", code); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code <= 0x04) { @@ -3547,7 +3747,7 @@ void dmi_ipmi_register_spacing(xmlNode *node, u8 code) } /******************************************************************************* -** 3.3.40 System Power Supply (Type 39) +** 7.40 System Power Supply (Type 39) */ void dmi_power_supply_power(xmlNode *node, u16 code) @@ -3566,7 +3766,7 @@ void dmi_power_supply_power(xmlNode *node, u16 code) void dmi_power_supply_type(xmlNode *node, u8 code) { - /* 3.3.40.1 */ + /* 7.40.1 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", @@ -3579,7 +3779,7 @@ void dmi_power_supply_type(xmlNode *node, u8 code) }; 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, "dmispec", "7.40.1"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x08) { @@ -3591,7 +3791,7 @@ void dmi_power_supply_type(xmlNode *node, u8 code) void dmi_power_supply_status(xmlNode *node, u8 code) { - /* 3.3.40.1 */ + /* 7.40.1 */ static const char *status[] = { "Other", /* 0x01 */ "Unknown", @@ -3601,7 +3801,7 @@ void dmi_power_supply_status(xmlNode *node, u8 code) }; 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, "dmispec", "7.40.1"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); dmixml_AddAttribute(data_n, "present", "1"); @@ -3614,7 +3814,7 @@ void dmi_power_supply_status(xmlNode *node, u8 code) void dmi_power_supply_range_switching(xmlNode *node, u8 code) { - /* 3.3.40.1 */ + /* 7.40.1 */ static const char *switching[] = { "Other", /* 0x01 */ "Unknown", @@ -3625,7 +3825,7 @@ void dmi_power_supply_range_switching(xmlNode *node, u8 code) }; 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, "dmispec", "7.40.1"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code >= 0x01 && code <= 0x06) { @@ -3636,7 +3836,7 @@ void dmi_power_supply_range_switching(xmlNode *node, u8 code) } /* -** 3.3.41 Additional Information (Type 40) +** 7.41 Additional Information (Type 40) ** ** Proper support of this entry type would require redesigning a large part of ** the code, so I am waiting to see actual implementations of it to decide @@ -3694,6 +3894,39 @@ void dmi_additional_info(xmlNode *node, const struct dmi_header *h) } } +/* + * 7.43 Management Controller Host Interface (Type 42) + */ + +xmlNode * dmi_management_controller_host_type(xmlNode *node, u8 code) +{ + /* DMTF DSP0239 (MCTP) version 1.1.0 */ + static const char *type[] = { + "KCS: Keyboard Controller Style", /* 0x02 */ + "8250 UART Register Compatible", + "16450 UART Register Compatible", + "16550/16550A UART Register Compatible", + "16650/16650A UART Register Compatible", + "16750/16750A UART Register Compatible", + "16850/16850A UART Register Compatible" /* 0x08 */ + }; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "ManagementControllerHost", NULL); + + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "7.43"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); + + if (code >= 0x02 && code <= 0x08) { + dmixml_AddTextChild(data_n, "Type", "%s", type[code - 0x01]); + } else if (code == 0xF0) { + dmixml_AddTextChild(data_n, "Type", "OEM"); + } else { + dmixml_AddAttribute(data_n, "outofspec", "1"); + } + return data_n; +} + + /******************************************************************************* ** Main */ @@ -3713,7 +3946,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmixml_AddTextChild(sect_n, "DMIdescription", "%s", dmiMajor->desc); switch (h->type) { - case 0: /* 3.3.1 BIOS Information */ + case 0: /* 7.1 BIOS Information */ if(h->length < 0x12) { break; } @@ -3779,7 +4012,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade } break; - case 1: /* 3.3.2 System Information */ + case 1: /* 7.2 System Information */ if(h->length < 0x08) { break; } @@ -3805,7 +4038,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmixml_AddDMIstring(sect_n, "Family", h, data[0x1A]); break; - case 2: /* 3.3.3 Base Board Information */ + case 2: /* 7.3 Base Board Information */ if(h->length < 0x08) { break; } @@ -3835,7 +4068,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmi_base_board_handles(sect_n, data[0x0E], data + 0x0F); break; - case 3: /* 3.3.4 Chassis Information */ + case 3: /* 7.4 Chassis Information */ if(h->length < 0x09) { break; } @@ -3879,16 +4112,21 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade } dmi_chassis_elements(sect_n, data[0x13], data[0x14], data + 0x15); + if (h->length < 0x16 + data[0x13] * data[0x14]) { + break; + } + dmixml_AddDMIstring(sect_n, "SKUnumber", h, data[0x15 + data[0x13] * data[0x14]]); + break; - case 4: /* 3.3.5 Processor Information */ + case 4: /* 7.5 Processor Information */ if(h->length < 0x1A) { break; } dmixml_AddDMIstring(sect_n, "SocketDesignation", h, data[0x04]); dmi_processor_type(sect_n, data[0x05]); - dmi_processor_family(sect_n, h); + dmi_processor_family(sect_n, h, ver); dmi_processor_id(sect_n, h); @@ -3989,7 +4227,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade sub_n = NULL; break; - case 5: /* 3.3.6 Memory Controller Information */ + case 5: /* 7.6 Memory Controller Information */ if(h->length < 0x0F) { break; } @@ -4032,7 +4270,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade data[0x0F + data[0x0E] * sizeof(u16)]); break; - case 6: /* 3.3.7 Memory Module Information */ + case 6: /* 7.7 Memory Module Information */ if(h->length < 0x0C) { break; } @@ -4047,7 +4285,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmi_memory_module_error(sect_n, data[0x0B]); break; - case 7: /* 3.3.8 Cache Information */ + case 7: /* 7.8 Cache Information */ if(h->length < 0x0F) { break; } @@ -4079,7 +4317,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmi_cache_associativity(sect_n, data[0x12]); break; - case 8: /* 3.3.9 Port Connector Information */ + case 8: /* 7.9 Port Connector Information */ if(h->length < 0x09) { break; } @@ -4100,7 +4338,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmi_port_type(sect_n, data[0x08]); break; - case 9: /* 3.3.10 System Slots */ + case 9: /* 7.10 System Slots */ if(h->length < 0x0C) { break; } @@ -4120,11 +4358,11 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade } break; - case 10: /* 3.3.11 On Board Devices Information */ + case 10: /* 7.11 On Board Devices Information */ dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); break; - case 11: /* 3.3.12 OEM Strings */ + case 11: /* 7.12 OEM Strings */ if(h->length < 0x05) { break; } @@ -4132,7 +4370,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmi_oem_strings(sect_n, h); break; - case 12: /* 3.3.13 System Configuration Options */ + case 12: /* 7.13 System Configuration Options */ if(h->length < 0x05) { break; } @@ -4140,17 +4378,17 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmi_system_configuration_options(sect_n, h); break; - case 13: /* 3.3.14 BIOS Language Information */ + case 13: /* 7.14 BIOS Language Information */ if(h->length < 0x16) { break; } dmixml_AddAttribute(sect_n, "installable_languages", "%i", data[0x04]); - dmi_bios_languages(sect_n, h); + dmi_bios_languages(sect_n, h, data[0x05]); break; - case 14: /* 3.3.15 Group Associations */ + case 14: /* 7.15 Group Associations */ if(h->length < 0x05) { break; } @@ -4163,7 +4401,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade sub_n = NULL; break; - case 15: /* 3.3.16 System Event Log */ + case 15: /* 7.16 System Event Log */ // SysEventLog - sect_n if(h->length < 0x14) { break; @@ -4220,7 +4458,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade sub_n = NULL; break; - case 16: /* 3.3.17 Physical Memory Array */ + case 16: /* 7.17 Physical Memory Array */ if(h->length < 0x0F) { break; } @@ -4229,11 +4467,11 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade 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_capacity(sect_n, h, data); dmi_memory_array_error_handle(sect_n, WORD(data + 0x0B)); break; - case 17: /* 3.3.18 Memory Device */ + case 17: /* 7.18 Memory Device */ if(h->length < 0x15) { break; } @@ -4243,7 +4481,11 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade 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)); + if (h->length >= 0x20 && WORD(data + 0x0C) == 0x7FFF) { + dmi_memory_device_extended_size(sect_n, WORD(data + 0x1C)); + } else { + 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_AddDMIstring(sect_n, "Locator", h, data[0x10]); @@ -4256,7 +4498,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade break; } - dmi_memory_device_speed(sect_n, WORD(data + 0x15)); + dmi_memory_device_speed(sect_n, "Speed", WORD(data + 0x15)); if(h->length < 0x1B) { break; @@ -4266,10 +4508,22 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmixml_AddDMIstring(sect_n, "SerialNumber", h, data[0x18]); dmixml_AddDMIstring(sect_n, "AssetTag", h, data[0x19]); dmixml_AddDMIstring(sect_n, "PartNumber", h, data[0x1A]); + + if(h->length < 0x1C) { + break; + } + + dmixml_AddTextChild(sect_n, "Rank", "%u", data[0x1B] & 0x0F); + + if(h->length < 0x22) { + break; + } + + dmi_memory_device_speed(sect_n, "CurrentClockSpeed", WORD(data + 0x20)); break; - case 18: /* 3.3.19 32-bit Memory Error Information */ - case 33: /* 3.3.34 64-bit Memory Error Information */ + case 18: /* 7.19 32-bit Memory Error Information */ + case 33: /* 7.34 64-bit Memory Error Information */ if( h->type == 18 ) { dmixml_AddAttribute(sect_n, "bits", "32"); } else { @@ -4300,23 +4554,32 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade } break; - case 19: /* 3.3.20 Memory Array Mapped Address */ + case 19: /* 7.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); + if (h->length >= 0x1F && DWORD(data + 0x04) == 0xFFFFFFFF) { + u64 start, end; + + start = QWORD(data + 0x0F); + end = QWORD(data + 0x17); + dmi_mapped_address_extended_size(sect_n, start, end); + } else { + 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 */ + case 20: /* 7.21 Memory Device Mapped Address */ if(h->length < 0x13) { break; } @@ -4340,7 +4603,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmi_mapped_address_interleaved_data_depth(sect_n, data[0x12]); break; - case 21: /* 3.3.22 Built-in Pointing Device */ + case 21: /* 7.22 Built-in Pointing Device */ if(h->length < 0x07) { break; } @@ -4350,7 +4613,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmixml_AddTextChild(sect_n, "Buttons", "%i", data[0x06]); break; - case 22: /* 3.3.23 Portable Battery */ + case 22: /* 7.23 Portable Battery */ if(h->length < 0x10) { break; } @@ -4398,7 +4661,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmixml_AddTextChild(sect_n, "OEMinformation", "0x%08x", DWORD(data + 0x16)); break; - case 23: /* 3.3.24 System Reset */ + case 23: /* 7.24 System Reset */ if(h->length < 0x0D) { break; } @@ -4427,7 +4690,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmi_system_reset_timer(sect_n, "Timeout", WORD(data + 0x0B)); break; - case 24: /* 3.3.25 Hardware Security */ + case 24: /* 7.25 Hardware Security */ if(h->length < 0x05) { break; } @@ -4439,7 +4702,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade break; - case 25: /* 3.3.26 System Power Controls */ + case 25: /* 7.26 System Power Controls */ if(h->length < 0x09) { break; } @@ -4447,7 +4710,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmi_power_controls_power_on(sect_n, "NextSchedPowerOn", data + 0x04); break; - case 26: /* 3.3.27 Voltage Probe */ + case 26: /* 7.27 Voltage Probe */ dmixml_AddAttribute(sect_n, "probetype", "Voltage"); if(h->length < 0x14) { @@ -4475,7 +4738,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmi_voltage_probe_value(sect_n, "NominalValue", WORD(data + 0x14)); break; - case 27: /* 3.3.28 Cooling Device */ + case 27: /* 7.28 Cooling Device */ if(h->length < 0x0C) { break; } @@ -4500,7 +4763,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmi_cooling_device_speed(sect_n, WORD(data + 0x0C)); break; - case 28: /* 3.3.29 Temperature Probe */ + case 28: /* 7.29 Temperature Probe */ dmixml_AddAttribute(sect_n, "probetype", "Temperature"); if(h->length < 0x14) { @@ -4526,7 +4789,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmi_temperature_probe_value(sect_n, "NominalValue", WORD(data + 0x14)); break; - case 29: /* 3.3.30 Electrical Current Probe */ + case 29: /* 7.30 Electrical Current Probe */ dmixml_AddAttribute(sect_n, "probetype", "Electrical Current"); if(h->length < 0x14) { @@ -4553,7 +4816,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmi_current_probe_value(sect_n, "NominalValue", WORD(data + 0x14)); break; - case 30: /* 3.3.31 Out-of-band Remote Access */ + case 30: /* 7.31 Out-of-band Remote Access */ if(h->length < 0x06) { break; } @@ -4563,11 +4826,11 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmixml_AddAttribute(sect_n, "OutboundConnectionEnabled", "%i", data[0x05] & (1 << 1) ? 1 : 0); break; - case 31: /* 3.3.32 Boot Integrity Services Entry Point */ + case 31: /* 7.32 Boot Integrity Services Entry Point */ dmixml_AddAttribute(sect_n, "NOT_IMPLEMENTED", "1"); break; - case 32: /* 3.3.33 System Boot Information */ + case 32: /* 7.33 System Boot Information */ if(h->length < 0x0B) { break; } @@ -4575,7 +4838,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmi_system_boot_status(sect_n, data[0x0A]); break; - case 34: /* 3.3.35 Management Device */ + case 34: /* 7.35 Management Device */ dmixml_AddAttribute(sect_n, "mgmtype", ""); if(h->length < 0x0B) { @@ -4588,7 +4851,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmi_management_device_address_type(sect_n, data[0x0A]); break; - case 35: /* 3.3.36 Management Device Component */ + case 35: /* 7.36 Management Device Component */ dmixml_AddAttribute(sect_n, "mgmtype", "Component"); if(h->length < 0x0B) { @@ -4604,7 +4867,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade } break; - case 36: /* 3.3.37 Management Device Threshold Data */ + case 36: /* 7.37 Management Device Threshold Data */ dmixml_AddAttribute(sect_n, "mgmtype", "Threshold Data"); if(h->length < 0x10) { @@ -4649,7 +4912,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade sub_n = NULL; break; - case 37: /* 3.3.38 Memory Channel */ + case 37: /* 7.38 Memory Channel */ if(h->length < 0x07) { break; } @@ -4670,7 +4933,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade sub_n = NULL; break; - case 38: /* 3.3.39 IPMI Device Information */ + case 38: /* 7.39 IPMI Device Information */ /* * We use the word "Version" instead of "Revision", conforming to * the IPMI specification. @@ -4696,7 +4959,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade sub_n = NULL; dmi_ipmi_base_address(sect_n, data[0x04], data + 0x08, - h->length < 0x12 ? 0 : (data[0x10] >> 5) & 1); + h->length < 0x11 ? 0 : (data[0x10] >> 4) & 1); if(h->length < 0x12) { break; @@ -4725,7 +4988,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade sub_n = NULL; break; - case 39: /* 3.3.40 System Power Supply */ + case 39: /* 7.40 System Power Supply */ if(h->length < 0x10) { break; } @@ -4783,7 +5046,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade sub_n = NULL; break; - case 40: /* 3.3.41 Additional Information */ + case 40: /* 7.41 Additional Information */ dmixml_AddAttribute(sect_n, "subtype", "AdditionalInformation"); if(h->length < 0x0B) { @@ -4793,9 +5056,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmi_additional_info(sect_n, h); break; - case 41: /* 3.3.42 Onboard Device Extended Information */ - dmixml_AddAttribute(sect_n, "subtype", "OnboardDeviceExtendedInformation"); - + case 41: /* 7.42 Onboard Device Extended Information */ if(h->length < 0x0B) { break; } @@ -4811,8 +5072,30 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade sub_n = NULL; break; - case 126: /* 3.3.43 Inactive */ - case 127: /* 3.3.44 End Of Table */ + case 42: /* 7.43 Management Controller Host Interface */ + if (h->length < 0x05) { + break; + } + + sub_n = dmi_management_controller_host_type(sect_n, data[0x04]); + /* + * There you have a type-dependent, variable-length + * part in the middle of the structure, with no + * length specifier, so no easy way to decode the + * common, final part of the structure. What a pity. + */ + if (h->length < 0x09) { + break; + } + if (data[0x04] == 0xF0) { /* OEM */ + dmixml_AddTextChild(sub_n, "VendorID", "0x%02X%02X%02X%02X\n", + data[0x05], data[0x06], data[0x07], + data[0x08]); + } + sub_n = NULL; + break; + case 126: /* 7.43 Inactive */ + case 127: /* 7.44 End Of Table */ break; default: @@ -4854,6 +5137,7 @@ dmi_codes_major *find_dmiMajor(const struct dmi_header *h) static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver, const char *devmem, xmlNode *xmlnode) { + static u8 version_added = 0; u8 *buf; u8 *data; int i = 0; @@ -4884,6 +5168,18 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver return; } + if (ver > SUPPORTED_SMBIOS_VER) { + log_append(logp, LOGFL_NODUPS, LOG_WARNING, + "# SMBIOS implementations newer than version %u.%u are not\n" + "# fully supported by this version of dmidecode.\n", + SUPPORTED_SMBIOS_VER >> 8, SUPPORTED_SMBIOS_VER & 0xFF); + } + // FIXME: This is hackerish ... rather try to avoid looping dmi_table() calls too much + if( version_added == 0 ) { + dmixml_AddAttribute(xmlnode, "smbios_version", "%u.%u", ver >> 8, ver & 0xFF); + version_added = 1; + } + data = buf; while(i < num && data + 4 <= buf + len) { /* 4 is the length of an SMBIOS structure header */ @@ -5053,7 +5349,7 @@ int smbios_decode(Log_t *logp, int type, u8 *buf, const char *devmem, xmlNode *x ver = 0x0206; break; } - //printf(">>%d @ %d, %d<<\n", DWORD(buf+0x18), WORD(buf+0x16), WORD(buf+0x1C)); + // printf(">>%d @ %d, %d<<\n", DWORD(buf+0x18), WORD(buf+0x16), WORD(buf+0x1C)); dmi_table(logp, type, DWORD(buf + 0x18), WORD(buf + 0x16), WORD(buf + 0x1C), ver, devmem, xmlnode); } diff --git a/src/dmihelper.h b/src/dmihelper.h index 8d07feb..3811392 100644 --- a/src/dmihelper.h +++ b/src/dmihelper.h @@ -65,50 +65,52 @@ typedef struct _dmi_codes_major { } dmi_codes_major; static const dmi_codes_major dmiCodesMajor[] = { - {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"}, + {0, "7.1", "BIOS Information", "BIOSinfo"}, + {1, "7.2", "System Information", "SystemInfo"}, + {2, "7.3", "Base Board Information", "BaseBoardInfo"}, + {3, "7.4", "Chassis Information", "ChassisInfo"}, + {4, "7.5", "Processor Information", "ProcessorInfo"}, + {5, "7.6", "Memory Controller Information", "MemoryCtrlInfo"}, + {6, "7.7", "Memory Module Information", "MemoryModuleInfo"}, + {7, "7.8", "Cache Information", "CacheInfo"}, + {8, "7.9", "Port Connector Information", "PortConnectorInfo"}, + {9, "7.10", "System Slots", "SystemSlots"}, + {10, "7.11", "On Board Devices Information", "OnBoardDevicesInfo"}, + {11, "7.12", "OEM Strings", "OEMstrings"}, + {12, "7.13", "System Configuration Options", "SysConfigOptions"}, + {13, "7.14", "BIOS Language Information", "BIOSlanguage"}, + {14, "7.15", "Group Associations", "GroupAssoc"}, + {15, "7.16", "System Event Log", "SysEventLog"}, + {16, "7.17", "Physical Memory Array", "PhysicalMemoryArray"}, + {17, "7.18", "Memory Device", "MemoryDevice"}, + {18, "7.19", "32-bit Memory Error Information", "MemoryErrorInfo"}, + {19, "7.20", "Memory Array Mapped Address", "MemoryArrayMappedAddress"}, + {20, "7.21", "Memory Device Mapped Address", "MemoryDeviceMappedAddress"}, + {21, "7.22", "Built-in Pointing Device", "BuiltIntPointingDevice"}, + {22, "7.23", "Portable Battery", "PortableBattery"}, + {23, "7.24", "System Reset", "SystemReset"}, + {24, "7.25", "Hardware Security", "HardwareSecurity"}, + {25, "7.26", "System Power Controls", "SystemPowerCtrls"}, + {26, "7.27", "Voltage Probe", "Probe"}, + {27, "7.28", "Cooling Device", "CoolingDevice"}, + {28, "7.29", "Temperature Probe", "Probe"}, + {29, "7.30", "Electrical Current Probe", "Probe"}, + {30, "7.31", "Out-of-band Remote Access", "RemoteAccess"}, + {31, "7.32", "Boot Integrity Services Entry Point", "BootIntegrity"}, + {32, "7.33", "System Boot Information", "SystemBootInfo"}, + {33, "7.34", "64-bit Memory Error Information", "MemoryErrorInfo"}, + {34, "7.35", "Management Device", "ManagementDevice"}, + {35, "7.36", "Management Device Component", "ManagementDevice"}, + {36, "7.37", "Management Device Threshold Data", "ManagementDevice"}, + {37, "7.38", "Memory Channel", "MemoryChannel"}, + {38, "7.39", "IPMI Device Information", "IPMIdeviceInfo"}, + {39, "7.40", "System Power Supply", "SystemPowerSupply"}, + {40, "7.41", "-------------------", "Unknown"}, + {41, "7.42", "Onboard Device Extended Information", "OnBoardDevicesExtendedInfo"}, + {41, "7.43", "Management Controller Host Interface", "MgmntCtrltHostIntf"}, + {126, "7.44", "Inactive", "Inactive"}, + {127, "7.45", "End Of Table", "EndOfTable"}, + {-1, NULL, NULL, NULL} }; diff --git a/src/dmixml.h b/src/dmixml.h index cc2c303..d8861ac 100644 --- a/src/dmixml.h +++ b/src/dmixml.h @@ -32,6 +32,8 @@ #define foreach_xmlnode(n, itn) for( itn = n; itn != NULL; itn = itn->next ) +struct dmi_header; + xmlAttr *dmixml_AddAttribute(xmlNode *node, const char *atrname, const char *fmt, ...); xmlNode *dmixml_AddTextChild(xmlNode *node, const char *tagname, const char *fmt, ...); xmlNode *dmixml_AddDMIstring(xmlNode *node, const char *tagname, const struct dmi_header *dm, u8 s); diff --git a/src/pymap.xml b/src/pymap.xml index a07512c..6857b1b 100644 --- a/src/pymap.xml +++ b/src/pymap.xml @@ -1,7 +1,7 @@ + + + + + + + + + + + + + + + + + + + + + + + @@ -858,6 +883,7 @@ + diff --git a/src/util.c b/src/util.c index 8da554b..acef5bd 100644 --- a/src/util.c +++ b/src/util.c @@ -191,3 +191,18 @@ void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem) return p; } +/* Returns end - start + 1, assuming start < end */ +u64 u64_range(u64 start, u64 end) +{ + u64 res; + + res.h = end.h - start.h; + res.l = end.l - start.l; + + if (end.l < start.l) + res.h--; + if (++res.l == 0) + res.h++; + + return res; +} diff --git a/src/util.h b/src/util.h index a93af6b..aa0487a 100644 --- a/src/util.h +++ b/src/util.h @@ -29,3 +29,4 @@ int checksum(const u8 * buf, size_t len); void *mem_chunk(Log_t *logp, 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); +u64 u64_range(u64 start, u64 end); diff --git a/src/version.h b/src/version.h index c07b06f..0970d0d 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define VERSION "3.10.15" +#define VERSION "3.11.1" From 4684a9178a32bc1420571025c9874b203efd6784 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Mon, 8 Jul 2013 20:10:21 +0200 Subject: [PATCH 095/146] New upstream release v3.12.1 This includes a rebase against upstream dmidecode v2.12 and an update against the SMBIOS reference specification v2.8.0. Signed-off-by: David Sommerseth --- contrib/python-dmidecode.spec | 5 ++- man/dmidecode.8 | 14 +++++- src/config.h | 2 +- src/dmidecode.c | 80 +++++++++++++++++++++++++++++++---- src/dmioem.c | 2 +- src/version.h | 2 +- 6 files changed, 90 insertions(+), 15 deletions(-) diff --git a/contrib/python-dmidecode.spec b/contrib/python-dmidecode.spec index b016a72..8da8936 100644 --- a/contrib/python-dmidecode.spec +++ b/contrib/python-dmidecode.spec @@ -3,7 +3,7 @@ Summary: Python module to access DMI data Name: python-dmidecode -Version: 3.11.1 +Version: 3.12.1 Release: 1%{?dist} License: GPLv2 Group: System Environment/Libraries @@ -49,6 +49,9 @@ rm -rf $RPM_BUILD_ROOT %{_datadir}/python-dmidecode/ %changelog +* Mon Jul 8 2013 David Sommerseth - 3.12.1-1 +- Updated against upstream v3.12.1, which realigns against dmidecode 2.12 + * Thu Jul 4 2013 David Sommerseth - 3.11.1-1 - Updated against upstream v3.11.1, which realigns against dmidecode 2.11 diff --git a/man/dmidecode.8 b/man/dmidecode.8 index 1e8fed8..f5fef0d 100644 --- a/man/dmidecode.8 +++ b/man/dmidecode.8 @@ -1,4 +1,4 @@ -.TH DMIDECODE 8 "October 2008" "dmidecode" +.TH DMIDECODE 8 "March 2012" "dmidecode" .SH NAME dmidecode \- \s-1DMI\s0 table decoder .SH SYNOPSIS @@ -127,6 +127,13 @@ Display the version and exit .P Options --string, --type, --dump and --dump-bin determine the output format and are mutually exclusive. +.P +Please note in case of +.B dmidecode +is run on a system with BIOS that boasts new SMBIOS specification, which +is not supported by the tool yet, it will print out relevant message in +addition to requested data on the very top of the output. Thus informs the +output data is not reliable. .SH "DMI TYPES" The \s-1SMBIOS\s0 specification defines the following \s-1DMI\s0 types: @@ -138,7 +145,7 @@ r l. Type Information 0 BIOS 1 System -2 Base Board +2 Baseboard 3 Chassis 4 Processor 5 Memory Controller @@ -176,6 +183,9 @@ Type Information 37 Memory Channel 38 IPMI Device 39 Power Supply +40 Additional Information +41 Onboard Devices Extended Information +42 Management Controller Host Interface .TE Additionally, type 126 is used for disabled entries and type 127 is an diff --git a/src/config.h b/src/config.h index 2876788..4fb28df 100644 --- a/src/config.h +++ b/src/config.h @@ -41,7 +41,7 @@ #define CONFIG_H /* Default memory device file */ -#ifdef __BEOS__ +#if defined(__BEOS__) || defined(__HAIKU__) #define DEFAULT_MEM_DEV "/dev/misc/mem" #else #define DEFAULT_MEM_DEV "/dev/mem" diff --git a/src/dmidecode.c b/src/dmidecode.c index 36f390b..0615bad 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -44,7 +44,7 @@ * DMI Decode * * Unless specified otherwise, all references are aimed at the "System - * Management BIOS Reference Specification, Version 2.7.0" document, + * Management BIOS Reference Specification, Version 2.8.0" document, * available from http://www.dmtf.org/standards/smbios. * * Note to contributors: @@ -627,6 +627,8 @@ void dmi_chassis_type(xmlNode *node, u8 code) dmixml_AddAttribute(type_n, "dmispec", "7.4.1"); dmixml_AddAttribute(type_n, "flags", "0x%04x", code); + code &= 0x7F; /* bits 6:0 are chassis type, 7th bit is the lock bit */ + if(code >= 0x01 && code <= 0x1B) { dmixml_AddAttribute(type_n, "available", "1"); dmixml_AddTextContent(type_n, "%s", type[code - 0x01]); @@ -841,7 +843,9 @@ void dmi_processor_family(xmlNode *node, const struct dmi_header *h, u16 ver) { 0x3A, "Athlon II Dual-Core M" }, { 0x3B, "Opteron 6100" }, { 0x3C, "Opteron 4100" }, - + { 0x3D, "Opteron 6200" }, + { 0x3E, "Opteron 4200" }, + { 0x3F, "FX" }, { 0x40, "MIPS" }, { 0x41, "MIPS R4000" }, @@ -849,6 +853,16 @@ void dmi_processor_family(xmlNode *node, const struct dmi_header *h, u16 ver) { 0x43, "MIPS R4400" }, { 0x44, "MIPS R4600" }, { 0x45, "MIPS R10000" }, + { 0x46, "C-Series" }, + { 0x47, "E-Series" }, + { 0x48, "A-Series" }, + { 0x49, "G-Series" }, + { 0x4A, "Z-Series" }, + { 0x4B, "R-Series" }, + { 0x4C, "Opteron 4300" }, + { 0x4D, "Opteron 6300" }, + { 0x4E, "Opteron 3300" }, + { 0x4F, "FirePro" }, { 0x50, "SPARC" }, { 0x51, "SuperSPARC" }, @@ -962,6 +976,8 @@ void dmi_processor_family(xmlNode *node, const struct dmi_header *h, u16 ver) { 0xDF, "Multi-Core Xeon 7xxx" }, { 0xE0, "Multi-Core Xeon 3400" }, + { 0xE4, "Opteron 3000" }, + { 0xE5, "Sempron II" }, { 0xE6, "Embedded Opteron Quad-Core" }, { 0xE7, "Phenom Triple-Core" }, { 0xE8, "Turion Ultra Dual-Core Mobile" }, @@ -1184,7 +1200,8 @@ xmlNode *dmi_processor_id(xmlNode *node, const struct dmi_header *h) } else if((type >= 0x18 && type <= 0x1D) /* AMD */ ||type == 0x1F /* AMD */ - ||(type >= 0x38 && type <= 0x3C) /* AMD */ + ||(type >= 0x38 && type <= 0x3E) /* AMD */ + ||(type >= 0x46 && type <= 0x49) /* AMD */ ||(type >= 0x83 && type <= 0x8F) /* AMD */ ||(type >= 0xB6 && type <= 0xB7) /* AMD */ ||(type >= 0xE6 && type <= 0xEF) /* AMD */ @@ -1356,13 +1373,26 @@ void dmi_processor_upgrade(xmlNode *node, u8 code) "Socket LGA1567", "Socket PGA988A", "Socket BGA1288" /* 0x20 */ + "Socket rPGA988B", + "Socket BGA1023", + "Socket BGA1224", + "Socket BGA1155", + "Socket LGA1356", + "Socket LGA2011", + "Socket FS1", + "Socket FS2", + "Socket FM1", + "Socket FM2", + "Socket LGA2011-3", + "Socket LGA1356-3" /* 0x2C */ + }; xmlNode *upgr_n = xmlNewChild(node, NULL, (xmlChar *) "Upgrade", NULL); assert( upgr_n != NULL ); dmixml_AddAttribute(upgr_n, "dmispec", "7.5.5"); dmixml_AddAttribute(upgr_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x20) { + if(code >= 0x01 && code <= 0x2A) { dmixml_AddTextContent(upgr_n, "%s", upgrade[code - 0x01]); } else { dmixml_AddAttribute(upgr_n, "outofspec", "1"); @@ -1811,13 +1841,14 @@ void dmi_cache_associativity(xmlNode *node, u8 code) "32-way Set-associative", "48-way Set-associative", "64-way Set-associative" /* 0x0D */ + "20-way Set-associative" /* 0x0E */ }; xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Associativity", NULL); assert( data_n != NULL ); dmixml_AddAttribute(data_n, "dmispec", "7.8.5"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x0D) { + if(code >= 0x01 && code <= 0x0E) { dmixml_AddTextContent(data_n, type[code - 0x01]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); @@ -1999,6 +2030,12 @@ void dmi_slot_type(xmlNode *node, u8 code) "PCI Express 2 x4", "PCI Express 2 x8", "PCI Express 2 x16", /* 0xB0 */ + "PCI Express 3", + "PCI Express 3 x1", + "PCI Express 3 x2", + "PCI Express 3 x4", + "PCI Express 3 x8", + "PCI Express 3 x16" /* 0xB6 */ }; xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "SlotType", NULL); assert( data_n != NULL ); @@ -2007,7 +2044,7 @@ void dmi_slot_type(xmlNode *node, u8 code) if(code >= 0x01 && code <= 0x13) { dmixml_AddTextContent(data_n, "%s", type[code - 0x01]); - } else if(code >= 0xA0 && code <= 0xB0) { + } else if(code >= 0xA0 && code <= 0xB6) { dmixml_AddTextContent(data_n, "%s", type_0xA0[code - 0xA0]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); @@ -2605,7 +2642,7 @@ void dmi_memory_array_location(xmlNode *node, u8 code) if(code >= 0x01 && code <= 0x0A) { dmixml_AddTextContent(data_n, location[code - 0x01]); - } else if(code >= 0xA0 && code <= 0xA4) { + } else if(code >= 0xA0 && code <= 0xA3) { dmixml_AddTextContent(data_n, location_0xA0[code - 0xA0]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); @@ -2860,7 +2897,8 @@ void dmi_memory_device_type_detail(xmlNode *node, u16 code) "Cache DRAM", "Non-Volatile", /* 12 */ "Registered (Buffered)", - "Unbuffered (Unregistered)" /* 14 */ + "Unbuffered (Unregistered)", /* 14 */ + "LRDIMM" /* 15 */ }; xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "TypeDetails", NULL); assert( data_n != NULL ); @@ -2893,6 +2931,19 @@ void dmi_memory_device_speed(xmlNode *node, const char *tag, u16 code) } } +void dmi_memory_voltage_value(xmlNode *node, const char *tag, u16 code) { + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tag, NULL); + assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); + + if (code == 0) { + dmixml_AddAttribute(data_n, "unknown", "1"); + } else { + dmixml_AddAttribute(data_n, "unit", "V"); + dmixml_AddTextContent(data_n, "%.3f", (float)(i16)code / 1000); + } +} + /******************************************************************************* * 7.19 32-bit Memory Error Information (Type 18) */ @@ -4074,7 +4125,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade } dmixml_AddDMIstring(sect_n, "Manufacturer", h, data[0x04]); - dmi_chassis_type(sect_n, data[0x05] & 0x7F); + dmi_chassis_type(sect_n, data[0x05]); dmi_chassis_lock(sect_n, data[0x05] >> 7); dmixml_AddDMIstring(sect_n, "Version", h, data[0x06]); dmixml_AddDMIstring(sect_n, "SerialNumber", h, data[0x07]); @@ -4520,6 +4571,17 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade } dmi_memory_device_speed(sect_n, "CurrentClockSpeed", WORD(data + 0x20)); + + if(h->length < 0x28) { + break; + } + sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "MemoryVoltage", NULL); + assert( sub_n != NULL ); + dmi_memory_voltage_value(sub_n, "Minimum", WORD(data + 0x22)); + dmi_memory_voltage_value(sub_n, "Maximum", WORD(data + 0x24)); + dmi_memory_voltage_value(sub_n, "Current", WORD(data + 0x26)); + sub_n = NULL; + break; case 18: /* 7.19 32-bit Memory Error Information */ diff --git a/src/dmioem.c b/src/dmioem.c index 67cd517..055b39f 100644 --- a/src/dmioem.c +++ b/src/dmioem.c @@ -93,7 +93,7 @@ static int dmi_decode_hp(struct dmi_header *h) */ printf(h->type == 221 ? "HP BIOS iSCSI NIC PCI and MAC Information\n" : - "HP BIOS NIC PCI and MAC Information\n"); + "HP BIOS NIC PXE PCI and MAC Information\n"); nic = 1; ptr = 4; while(h->length >= ptr + 8) { diff --git a/src/version.h b/src/version.h index 0970d0d..e9639c1 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define VERSION "3.11.1" +#define VERSION "3.12.1" From 9fa1352cd540aa69dd8b59e56de9b8020563e545 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Mon, 12 Aug 2013 15:59:07 +0200 Subject: [PATCH 096/146] Fix typo in pymap.xml - "Relase Date" -> "Release Date" Thanks to Daniel Mueller for spotting this typo. Unfortunately this fix may break some code if it depends on the "Relase Date" key name. The alternative would be to provide both the old and wrong key name together with the new one, but this particular key was not considered critically enough for special treatment. Signed-off-by: David Sommerseth --- src/pymap.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pymap.xml b/src/pymap.xml index 6857b1b..7d5de70 100644 --- a/src/pymap.xml +++ b/src/pymap.xml @@ -68,7 +68,7 @@ - + From 5cc3d02060f67317049b6e0549c87a407e030e61 Mon Sep 17 00:00:00 2001 From: Slavek Kabrda Date: Wed, 21 Jan 2015 12:57:35 +0100 Subject: [PATCH 097/146] Port to Python 3 while maintaining compatibility with Python >= 2.6 Signed-off-by: David Sommerseth --- Makefile | 15 ++++-- dmidecode.py | 6 +-- examples/dmidump.py | 108 +++++++++++++++++++++--------------------- src/compat.h | 15 ++++++ src/dmidecodemodule.c | 75 ++++++++++++++++++++++++----- src/setup_common.py | 20 ++++---- src/xmlpythonizer.c | 7 +-- unit-tests/Makefile | 4 +- unit-tests/unit | 27 ++++++----- 9 files changed, 179 insertions(+), 98 deletions(-) diff --git a/Makefile b/Makefile index d468b70..76d23de 100644 --- a/Makefile +++ b/Makefile @@ -38,11 +38,19 @@ #. $AutoHeaderSerial::20100225 $ #. ******* AUTOHEADER END v1.2 ******* -VERSION := $(shell cd src;python -c "from setup_common import *; print get_version();") +PY_BIN := python2 +VERSION := $(shell cd src;$(PY_BIN) -c "from setup_common import *; print(get_version());") PACKAGE := python-dmidecode -PY_VER := $(shell python -c 'import sys; print "%d.%d"%sys.version_info[0:2]') +PY_VER := $(shell $(PY_BIN) -c 'import sys; print("%d.%d"%sys.version_info[0:2])') +PY_MV := $(shell echo $(PY_VER) | cut -b 1) PY := python$(PY_VER) -SO := build/lib.linux-$(shell uname -m)-$(PY_VER)/dmidecodemod.so +SO_PATH := build/lib.linux-$(shell uname -m)-$(PY_VER) +ifeq ($(PY_MV),2) + SO := $(SO_PATH)/dmidecodemod.so +else + SOABI := $(shell $(PY_BIN) -c 'import sysconfig; print(sysconfig.get_config_var("SOABI"))') + SO := $(SO_PATH)/dmidecodemod.$(SOABI).so +endif SHELL := /bin/bash ############################################################################### @@ -71,6 +79,7 @@ clean: -rm -rf build -rm -rf rpm -rm -rf src/setup_common.py[oc] + -rm -rf __pycache__ src/__pycache__ -rm -rf $(PACKAGE)-$(VERSION) $(PACKAGE)-$(VERSION).tar.gz $(MAKE) -C unit-tests clean diff --git a/dmidecode.py b/dmidecode.py index cd37b40..ac81365 100644 --- a/dmidecode.py +++ b/dmidecode.py @@ -48,7 +48,7 @@ def SetResultType(self, type): elif type == DMIXML_DOC: self.restype = DMIXML_DOC else: - raise TypeError, "Invalid result type value" + raise TypeError("Invalid result type value") return True def QuerySection(self, sectname): @@ -65,7 +65,7 @@ def QuerySection(self, sectname): result_type=self.restype, section=sectname) ) else: - raise TypeError, "Invalid result type value" + raise TypeError("Invalid result type value") return ret @@ -83,7 +83,7 @@ def QueryTypeId(self, tpid): result_type=self.restype, typeid=tpid)) else: - raise TypeError, "Invalid result type value" + raise TypeError("Invalid result type value") return ret diff --git a/examples/dmidump.py b/examples/dmidump.py index 11b04ff..769750d 100755 --- a/examples/dmidump.py +++ b/examples/dmidump.py @@ -35,24 +35,24 @@ def print_warnings(): "Simple function, dumping out warnings with a prefix if warnings are found and clearing warning buffer" warn = dmidecode.get_warnings() if warn: - print "### WARNING: %s" % warn + print("### WARNING: %s" % warn) dmidecode.clear_warnings() # Check if running as root .... provide a warning if not root_user = (os.getuid() == 0 and True or False) if not root_user: - print "####" - print "#### NOT RUNNING AS ROOT" - print "####" - print "#### The first run must always be done as root for this example to work." - print "#### When not run as root, quite some permission errors might appear" - print "####" - print "#### If this script is first run as root, it should be possible to run this script" - print "#### as an unprivileged user afterwards, with less warnings." - print "####" - print - print + print("####") + print("#### NOT RUNNING AS ROOT") + print("####") + print("#### The first run must always be done as root for this example to work.") + print("#### When not run as root, quite some permission errors might appear") + print("####") + print("#### If this script is first run as root, it should be possible to run this script") + print("#### as an unprivileged user afterwards, with less warnings.") + print("####") + print() + print() #. Test for presence of important functions using /dev/mem... Using the legacy API @@ -61,101 +61,101 @@ def print_warnings(): #. for presence of the legacy API, which "under the hood" uses #. dmidecode.QuerySection(name), where name can be 'bios', 'system', etc. if root_user: - print "*** bios ***\n"; dmidecode.bios() + print("*** bios ***\n"); dmidecode.bios() print_warnings() - print "*** system ***\n"; dmidecode.system() + print("*** system ***\n"); dmidecode.system() print_warnings() - print "*** baseboard ***\n"; dmidecode.baseboard() + print("*** baseboard ***\n"); dmidecode.baseboard() print_warnings() - print "*** chassis ***\n"; dmidecode.chassis() + print("*** chassis ***\n"); dmidecode.chassis() print_warnings() - print "*** processor ***\n"; dmidecode.processor() + print("*** processor ***\n"); dmidecode.processor() print_warnings() - print "*** memory ***\n"; dmidecode.memory() + print("*** memory ***\n"); dmidecode.memory() print_warnings() - print "*** cache ***\n"; dmidecode.cache() + print("*** cache ***\n"); dmidecode.cache() print_warnings() - print "*** connector ***\n"; dmidecode.connector() + print("*** connector ***\n"); dmidecode.connector() print_warnings() - print "*** slot ***\n"; dmidecode.slot() + print("*** slot ***\n"); dmidecode.slot() print_warnings() #. Now test get/set of memory device file... -print "*** get_dev()" -print dmidecode.get_dev() +print("*** get_dev()") +print(dmidecode.get_dev()) print_warnings() -print "*** set_dev('dmidata.dump')" -print dmidecode.set_dev("dmidata.dump"); +print("*** set_dev('dmidata.dump')") +print(dmidecode.set_dev("dmidata.dump")); print_warnings() -print "*** get_dev()" -print dmidecode.get_dev() +print("*** get_dev()") +print(dmidecode.get_dev()) print_warnings() #. Test taking a dump... if root_user: - print "*** Dumping DMI data to dump file" - print dmidecode.dump() + print("*** Dumping DMI data to dump file") + print(dmidecode.dump()) print_warnings() #. Test reading the dump... Using the preferred API -print "*** bios ***\n"; pprint(dmidecode.QuerySection('bios')) +print("*** bios ***\n"); pprint(dmidecode.QuerySection('bios')) print_warnings() -print "*** system ***\n"; pprint(dmidecode.QuerySection('system')) +print("*** system ***\n"); pprint(dmidecode.QuerySection('system')) print_warnings() -print "*** baseboard ***\n"; pprint(dmidecode.QuerySection('baseboard')) +print("*** baseboard ***\n"); pprint(dmidecode.QuerySection('baseboard')) print_warnings() -print "*** chassis ***\n"; pprint(dmidecode.QuerySection('chassis')) +print("*** chassis ***\n"); pprint(dmidecode.QuerySection('chassis')) print_warnings() -print "*** processor ***\n"; pprint(dmidecode.QuerySection('processor')) +print("*** processor ***\n"); pprint(dmidecode.QuerySection('processor')) print_warnings() -print "*** memory ***\n"; pprint(dmidecode.QuerySection('memory')) +print("*** memory ***\n"); pprint(dmidecode.QuerySection('memory')) print_warnings() -print "*** cache ***\n"; pprint(dmidecode.QuerySection('cache')) +print("*** cache ***\n"); pprint(dmidecode.QuerySection('cache')) print_warnings() -print "*** connector ***\n"; pprint(dmidecode.QuerySection('connector')) +print("*** connector ***\n"); pprint(dmidecode.QuerySection('connector')) print_warnings() -print "*** slot ***\n"; pprint(dmidecode.QuerySection('slot')) +print("*** slot ***\n"); pprint(dmidecode.QuerySection('slot')) print_warnings() -print "*** Extracting memory information" +print("*** Extracting memory information") for v in dmidecode.memory().values(): if type(v) == dict and v['dmi_type'] == 17: pprint(v['data']['Size']), -print "*** Querying for DMI type 3 and 7" +print("*** Querying for DMI type 3 and 7") pprint(dmidecode.type(3)) # <-- Legacy API pprint(dmidecode.QueryTypeId(7)) # <-- preferred API print_warnings() -print "*** Querying for the BIOS section" +print("*** Querying for the BIOS section") pprint(dmidecode.QuerySection('bios')) print_warnings() # # Test XML stuff # -print -print -print -print "---------------------------------------" -print "*** *** *** Testing XML API *** *** ***" -print "---------------------------------------" -print -print +print() +print() +print() +print("---------------------------------------") +print("*** *** *** Testing XML API *** *** ***") +print("---------------------------------------") +print() +print() dmixml = dmidecode.dmidecodeXML() # Fetch all DMI data into a libxml2.xmlDoc object -print "*** Getting all DMI data into a XML document variable" +print("*** Getting all DMI data into a XML document variable") dmixml.SetResultType(dmidecode.DMIXML_DOC) # Valid values: dmidecode.DMIXML_DOC, dmidecode.DMIXML_NODE xmldoc = dmixml.QuerySection('all') # Dump the XML to dmidump.xml - formated in UTF-8 decoding -print "*** Dumping XML document to dmidump.xml" +print("*** Dumping XML document to dmidump.xml") xmldoc.saveFormatFileEnc('dmidump.xml','UTF-8',1) # Do some XPath queries on the XML document -print "*** Doing some XPath queries against the XML document" +print("*** Doing some XPath queries against the XML document") dmixp = xmldoc.xpathNewContext() # What to look for - XPath expressions @@ -168,12 +168,12 @@ def print_warnings(): for k in keys: data = dmixp.xpathEval(k) for d in data: - print "%s: %s" % (k, d.get_content()) + print("%s: %s" % (k, d.get_content())) del dmixp del xmldoc # Query for only a particular DMI TypeID - 0x04 - Processor -print "*** Quering for Type ID 0x04 - Processor - dumping XML document to stdout" +print("*** Quering for Type ID 0x04 - Processor - dumping XML document to stdout") dmixml.QueryTypeId(0x04).saveFormatFileEnc('-','UTF-8',1) print_warnings() diff --git a/src/compat.h b/src/compat.h index 80a08c6..170f596 100644 --- a/src/compat.h +++ b/src/compat.h @@ -40,4 +40,19 @@ #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None #endif +// Python 2 vs Python 3 compat +#if PY_MAJOR_VERSION >= 3 +#define IS_PY3K +#define MODINITERROR return NULL +#define PYNUMBER_FROMLONG PyLong_FromLong +#define PYTEXT_FROMSTRING PyUnicode_FromString +#else +#include +#define MODINITERROR return +#define PYNUMBER_FROMLONG PyInt_FromLong +#define PYTEXT_FROMSTRING PyString_FromString +#define PyCapsule_New(pointer, name, destructor) \ + (PyCObject_FromVoidPtr(pointer, destructor)) +#endif + #endif diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 1056a8f..8db99cb 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -53,6 +53,17 @@ #include "dmidump.h" #include +#if (PY_VERSION_HEX < 0x03030000) +char *PyUnicode_AsUTF8(PyObject *unicode) { + PyObject *as_bytes = PyUnicode_AsUTF8String(unicode); + if (!as_bytes) { + return NULL; + } + + return PyBytes_AsString(as_bytes); +} +#endif + static void init(options *opt) { opt->devmem = DEFAULT_MEM_DEV; @@ -470,7 +481,12 @@ static PyObject *dmidecode_get_slot(PyObject * self, PyObject * args) static PyObject *dmidecode_get_section(PyObject *self, PyObject *args) { - char *section = PyString_AsString(args); + char *section = NULL; + if (PyUnicode_Check(args)) { + section = PyUnicode_AsUTF8(args); + } else if (PyBytes_Check(args)) { + section = PyBytes_AsString(args); + } if( section != NULL ) { return dmidecode_get_group(global_options, section); @@ -588,7 +604,7 @@ static PyObject *dmidecode_dump(PyObject * self, PyObject * null) static PyObject *dmidecode_get_dev(PyObject * self, PyObject * null) { PyObject *dev = NULL; - dev = PyString_FromString((global_options->dumpfile != NULL + dev = PYTEXT_FROMSTRING((global_options->dumpfile != NULL ? global_options->dumpfile : global_options->devmem)); Py_INCREF(dev); return dev; @@ -596,9 +612,14 @@ static PyObject *dmidecode_get_dev(PyObject * self, PyObject * null) static PyObject *dmidecode_set_dev(PyObject * self, PyObject * arg) { - if(PyString_Check(arg)) { + char *f = NULL; + if(PyUnicode_Check(arg)) { + f = PyUnicode_AsUTF8(arg); + } else if(PyBytes_Check(arg)) { + f = PyBytes_AsString(arg); + } + if(f) { struct stat buf; - char *f = PyString_AsString(arg); if( (f != NULL) && (global_options->dumpfile != NULL ) && (strcmp(global_options->dumpfile, f) == 0) ) { @@ -638,9 +659,9 @@ static PyObject *dmidecode_set_dev(PyObject * self, PyObject * arg) static PyObject *dmidecode_set_pythonxmlmap(PyObject * self, PyObject * arg) { - if(PyString_Check(arg)) { + if(PyBytes_Check(arg)) { struct stat fileinfo; - char *fname = PyString_AsString(arg); + char *fname = PyBytes_AsString(arg); memset(&fileinfo, 0, sizeof(struct stat)); @@ -664,7 +685,7 @@ static PyObject * dmidecode_get_warnings(PyObject *self, PyObject *null) warn = log_retrieve(global_options->logdata, LOG_WARNING); if( warn ) { - ret = PyString_FromString(warn); + ret = PYTEXT_FROMSTRING(warn); free(warn); } else { ret = Py_None; @@ -711,7 +732,7 @@ static PyMethodDef DMIDataMethods[] = { {(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 *)"xmlapi", dmidecode_xmlapi, METH_VARARGS | METH_KEYWORDS, (char *) "Internal API for retrieving data as raw XML data"}, @@ -726,6 +747,9 @@ static PyMethodDef DMIDataMethods[] = { void destruct_options(void *ptr) { +#ifdef IS_PY3K + ptr = PyCapsule_GetPointer(ptr, NULL); +#endif options *opt = (options *) ptr; if( opt->mappingxml != NULL ) { @@ -763,8 +787,25 @@ void destruct_options(void *ptr) free(ptr); } +#ifdef IS_PY3K +static struct PyModuleDef dmidecodemod_def = { + PyModuleDef_HEAD_INIT, + "dmidecodemod", + NULL, + -1, + DMIDataMethods, + NULL, + NULL, + NULL, + NULL +}; -PyMODINIT_FUNC initdmidecodemod(void) +PyMODINIT_FUNC +PyInit_dmidecodemod(void) +#else +PyMODINIT_FUNC +initdmidecodemod(void) +#endif { char *dmiver = NULL; PyObject *module = NULL; @@ -777,19 +818,29 @@ PyMODINIT_FUNC initdmidecodemod(void) opt = (options *) malloc(sizeof(options)+2); memset(opt, 0, sizeof(options)+2); init(opt); +#ifdef IS_PY3K + module = PyModule_Create(&dmidecodemod_def); +#else module = Py_InitModule3((char *)"dmidecodemod", DMIDataMethods, "Python extension module for dmidecode"); +#endif + if (module == NULL) + MODINITERROR; - version = PyString_FromString(VERSION); + version = PYTEXT_FROMSTRING(VERSION); 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); + PyModule_AddObject(module, "dmi", dmiver ? PYTEXT_FROMSTRING(dmiver) : 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)); + // TODO: destructor has wrong type under py3? + PyModule_AddObject(module, "options", PyCapsule_New(opt, NULL, destruct_options)); global_options = opt; +#ifdef IS_PY3K + return module; +#endif } diff --git a/src/setup_common.py b/src/setup_common.py index 209ccef..aec1f9b 100644 --- a/src/setup_common.py +++ b/src/setup_common.py @@ -26,17 +26,19 @@ # are deemed to be part of the source code. # -import commands, sys +import subprocess, sys +if sys.version_info[0] < 3: + import commands as subprocess 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") + (res, libxml2_cflags) = subprocess.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?" + 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 @@ -52,11 +54,11 @@ def libxml2_lib(libdir, libs): 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") + (res, libxml2_libs) = subprocess.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?" + 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 diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index e318023..e9c9242 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -85,6 +85,7 @@ #include "dmilog.h" #include "xmlpythonizer.h" #include "version.h" +#include "compat.h" /** @@ -646,7 +647,7 @@ inline PyObject *StringToPyObj(Log_t *logp, ptzMAP *val_m, const char *instr) { switch( val_m->type_value ) { case ptzINT: case ptzLIST_INT: - value = PyInt_FromLong(atoi(workstr)); + value = PYNUMBER_FROMLONG(atoi(workstr)); break; case ptzFLOAT: @@ -661,7 +662,7 @@ inline PyObject *StringToPyObj(Log_t *logp, ptzMAP *val_m, const char *instr) { case ptzSTR: case ptzLIST_STR: - value = PyString_FromString(workstr); + value = PyBytes_FromString(workstr); break; default: @@ -850,7 +851,7 @@ PyObject *_deep_pythonize(Log_t *logp, PyObject *retdata, switch( map_p->type_value ) { case ptzCONST: if( _get_key_value(logp, key, 256, map_p, xpctx, 0) != NULL ) { - value = PyString_FromString(map_p->value); + value = PyBytes_FromString(map_p->value); PyADD_DICT_VALUE(retdata, key, value); } else { PyReturnError(PyExc_ValueError, "Could not get key value: %s [%i] (Defining key: %s)", diff --git a/unit-tests/Makefile b/unit-tests/Makefile index 95086c1..765fd99 100644 --- a/unit-tests/Makefile +++ b/unit-tests/Makefile @@ -1,5 +1,7 @@ +PY_BIN := python2 + test : - python unit -vv + $(PY_BIN) unit -vv clean : rm -f *.{py[oc],o,so} *~ diff --git a/unit-tests/unit b/unit-tests/unit index 8f9184b..3b06c04 100755 --- a/unit-tests/unit +++ b/unit-tests/unit @@ -2,8 +2,9 @@ #.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 +import os, sys, subprocess, random, tempfile, time +if sys.version_info[0] < 3: + import commands as subprocess from getopt import getopt # Setup temporary sys.path() with our build dir @@ -32,7 +33,7 @@ try: COLOR = True elif o in ("-h", "--help"): HELP = True -except getopt.GetoptError, err: +except getopt.GetoptError as err: # print help information and exit: HELP = True ERROR = True @@ -138,7 +139,7 @@ def vwrite(msg, vLevel=0): ################################################################################ #. Let's ignore warnings from the module for the test units... -err = open('/dev/null', 'a+', 0) +err = open('/dev/null', 'a+', 1) os.dup2(err.fileno(), sys.stderr.fileno()) vwrite(LINE, 1) @@ -208,7 +209,7 @@ try: "Skip testing API function, missing root privileges: dmidecode.dump()" ), 1) - types = range(0, 42)+range(126, 128) + types = list(range(0, 42))+list(range(126, 128)) bad_types = [-1, -1000, 256] sections = [ "bios", @@ -263,7 +264,7 @@ try: test(output is not False) if output: vwrite(" * %s\n"%black(output.keys()), 1) - except LookupError, e: + except LookupError as e: failed(e, 1) for i in bad_types: @@ -279,15 +280,15 @@ try: try: output = dmidecode.type(i) if dmidecode_bin: - _output = commands.getoutput("dmidecode -t %d"%i).strip().split('\n') + _output = subprocess.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: vwrite(" * %s\n"%output.keys(), 1) - except IOError, e: + except IOError as e: failed(e, 1) - except LookupError, e: + except LookupError as e: failed(e, 1) @@ -330,7 +331,7 @@ try: try: output_node = dmixml.QueryTypeId(i) test(isinstance(output_node, libxml2.xmlNode)) - except Exception, e: + except Exception as e: failed(e, 1) except: failed() @@ -347,7 +348,7 @@ try: try: output_doc = dmixml.QuerySection(section) test(isinstance(output_doc, libxml2.xmlDoc)) - except Exception, e: + except Exception as e: failed(e, 1) except: failed() @@ -355,9 +356,9 @@ try: except IOError: skipped() -except ImportError, err: +except ImportError as err: failed() - print err + print(err) vwrite(LINE, 1) vwrite("Devices : %s\n"%cyan(len(devices)), 1) From 3b32d9d05a785a744f5e315ef9267d67723e082c Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Tue, 3 Feb 2015 21:19:13 +0100 Subject: [PATCH 098/146] Fix failing dmidecode.pythonmap() on Python 3 Python 3 uses the Unicode type for strings but it did only support the Bytes type. So the loading of XML-to-Python-dict-map would fail. This patch preserves the Bytes type support while adding Unicode support, which is what is done other places in the code as well. Signed-off-by: David Sommerseth --- src/dmidecodemodule.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 8db99cb..b31c002 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -659,12 +659,17 @@ static PyObject *dmidecode_set_dev(PyObject * self, PyObject * arg) static PyObject *dmidecode_set_pythonxmlmap(PyObject * self, PyObject * arg) { - if(PyBytes_Check(arg)) { + char *fname = NULL; + + if (PyUnicode_Check(arg)) { + fname = PyUnicode_AsUTF8(arg); + } else if (PyBytes_Check(arg)) { + fname = PyBytes_AsString(arg); + } + if (fname) { struct stat fileinfo; - char *fname = PyBytes_AsString(arg); memset(&fileinfo, 0, sizeof(struct stat)); - if( stat(fname, &fileinfo) != 0 ) { PyReturnError(PyExc_IOError, "Could not access the file '%s'", fname); } From 9d0f722cb3c2e45194737b154686887993c9c00a Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Mon, 8 Jun 2015 08:17:09 -0700 Subject: [PATCH 099/146] House-keeping around generated .pyc files in source --- .gitignore | 1 + utils/set_version | 1 + 2 files changed, 2 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0d20b64 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/utils/set_version b/utils/set_version index 97c18c9..bbca211 100755 --- a/utils/set_version +++ b/utils/set_version @@ -13,6 +13,7 @@ fi NEW_VERSION=$1 OLD_VERSION=$(cd src;python -c "from setup_common import *; print get_version();") +rm -f src/setup_common.py[co] # Prepare ChangeLog entry for the python-dmidecode.spec file TSTAMP="$(date +%a\ %b\ %d\ %Y)" From 92f117b13b3ef2506bcf9c15ff1e151206c6faee Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Mon, 8 Jun 2015 08:19:45 -0700 Subject: [PATCH 100/146] New upstream release (v3.12.2) --- contrib/python-dmidecode.spec | 5 ++++- src/version.h | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/contrib/python-dmidecode.spec b/contrib/python-dmidecode.spec index 8da8936..2c74597 100644 --- a/contrib/python-dmidecode.spec +++ b/contrib/python-dmidecode.spec @@ -3,7 +3,7 @@ Summary: Python module to access DMI data Name: python-dmidecode -Version: 3.12.1 +Version: 3.12.2 Release: 1%{?dist} License: GPLv2 Group: System Environment/Libraries @@ -49,6 +49,9 @@ rm -rf $RPM_BUILD_ROOT %{_datadir}/python-dmidecode/ %changelog +* Mon Jun 08 2015 Nima Talebi - 3.12.2-1 +- Update to new release + * Mon Jul 8 2013 David Sommerseth - 3.12.1-1 - Updated against upstream v3.12.1, which realigns against dmidecode 2.12 diff --git a/src/version.h b/src/version.h index e9639c1..9938205 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define VERSION "3.12.1" +#define VERSION "3.12.2" From 392652168505baa5b98a4ead350821ba9c8cc0ce Mon Sep 17 00:00:00 2001 From: Nir Soffer Date: Thu, 13 Oct 2016 13:08:18 +0300 Subject: [PATCH 101/146] dmidecode: Get OEM vendor from System Information (DMI type 1) DMI type 0 is the BIOS information, it doesn't tell us about the system vendor. DMI type 1 does that. It made no difference so far because the only vendor with support for OEM-type decoding was HP and they make their own BIOS, but it will matter as soon as we add support for more vendors. Should fix this crash reported by David Pinkerton: Program received signal SIGSEGV, Segmentation fault. dmi_set_vendor (s=0x0) at src/dmioem.c:45 45 if(strcmp(s, "HP") == 0) This is a backport of https://github.com/mirror/dmidecode/commit/6e3a3f3cd36f633a56437b42e40d6769ad8acfe7 --- src/dmidecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index 0615bad..0f003c3 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -5268,7 +5268,7 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver */ /* assign vendor for vendor-specific decodes later */ - if(h.type == 0 && h.length >= 5) { + if(h.type == 1 && h.length >= 5) { dmi_set_vendor(&h); } From b8a651a8118b9134e12a49997da33edf2b493a94 Mon Sep 17 00:00:00 2001 From: Lianbo Jiang Date: Tue, 20 Mar 2018 10:58:32 +0800 Subject: [PATCH 102/146] python-dmidecode doesn't trim whitespace from some fields. The issue is introduced in commit 10a2d8bd43934966dd842fd8f401f0d679d0d66a. Do not add any contents if the string contents(val_s) is "(null)". Signed-off-by: Lianbo Jiang --- src/dmixml.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/dmixml.c b/src/dmixml.c index 5fe0dd5..682acc7 100644 --- a/src/dmixml.c +++ b/src/dmixml.c @@ -198,8 +198,19 @@ xmlNode *dmixml_AddDMIstring(xmlNode *node, const char *tagname, const struct dm res = xmlNewChild(node, NULL, tagname_s, NULL); dmixml_AddAttribute(res, "badindex", "1"); } else { + xmlChar *ret = NULL; + xmlChar *ptr = NULL; xmlChar *val_s = xmlCharStrdup(dmistr); - res = xmlNewTextChild(node, NULL, tagname_s, val_s); + // Right trim the string + ret = val_s; + ptr = ret + xmlStrlen(ret) - 1; + while( (ptr >= ret) && (*ptr == ' ') ) { + *ptr = 0; + ptr--; + } + // 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(val_s); } return res; From 2ccf9b44de9c5288e887a58df8ba0d22abc33446 Mon Sep 17 00:00:00 2001 From: Sandro Tosi Date: Sat, 15 Dec 2018 19:58:35 -0500 Subject: [PATCH 103/146] fix typo Unkown/Unknown --- src/dmidecode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index 0615bad..8c7282f 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -1040,7 +1040,7 @@ void dmi_processor_family(xmlNode *node, const struct dmi_header *h, u16 ver) const char *manufacturer = dmi_string(h, data[0x07]); if( manufacturer == NULL ) { - dmixml_AddTextContent(family_n, "Core 2 or K7 (Unkown manufacturer)"); + dmixml_AddTextContent(family_n, "Core 2 or K7 (Unknown manufacturer)"); return; } @@ -1056,7 +1056,7 @@ void dmi_processor_family(xmlNode *node, const struct dmi_header *h, u16 ver) dmixml_AddTextContent(family_n, "K7"); return; } - dmixml_AddTextContent(family_n, "Core 2 or K7 (Unkown manufacturer)"); + dmixml_AddTextContent(family_n, "Core 2 or K7 (Unknown manufacturer)"); return; } From af9d5d93e2f12a828ee3e9e843167c15a5426996 Mon Sep 17 00:00:00 2001 From: Chenlizhong Date: Sat, 1 Aug 2020 23:16:27 +0800 Subject: [PATCH 104/146] Fix CI build failure issue (#19) --- .github/.codecov.yml | 26 ++++++++++++++++++++++++++ .travis.yml | 25 +++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 .github/.codecov.yml create mode 100644 .travis.yml diff --git a/.github/.codecov.yml b/.github/.codecov.yml new file mode 100644 index 0000000..2b5037e --- /dev/null +++ b/.github/.codecov.yml @@ -0,0 +1,26 @@ +codecov: + notify: + require_ci_to_pass: yes + +coverage: + precision: 2 + round: down + range: "70...100" + + status: + project: yes + patch: yes + changes: no + +parsers: + gcov: + branch_detection: + conditional: yes + loop: yes + method: no + macro: no + +comment: + layout: "header, diff" + behavior: default + require_changes: no diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..cb46c7e --- /dev/null +++ b/.travis.yml @@ -0,0 +1,25 @@ +language: c +sudo: true + +env: + global: + - CODECOV_TOKEN=4792f32d-1685-4e2d-8cc4-b82e9578a605 + +before_install: + - sudo apt-get update -qq + - sudo apt-get install python-libxml2 libxml2-dev python-dev + +script: + - sed 's/$(CC)/$(CC) -coverage/g' Makefile > t_makefile + - cp t_makefile Makefile + - rm -f t_makefile + - make GCOV=1 build + - make GCOV=1 unit + - find build/ -name '*.gcno' -exec mv {} ./ \; + - find build/ -name '*.gcda' -exec mv {} ./ \; + - make GCOV=1 dmidump + - sudo ./dmidump /dev/mem /dev/null + - make GCOV=1 version + +after_success: + - bash <(curl -s https://codecov.io/bash) -F unittest From ca80b1ab99b50f9c04f97c46dcaac865529f5420 Mon Sep 17 00:00:00 2001 From: Chenlizhong Date: Sun, 2 Aug 2020 00:05:23 +0800 Subject: [PATCH 105/146] Make patch coverage test pass always (#20) Make the patch codecov test pass always Signed-off-by: Chen Lizhong --- .github/.codecov.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/.codecov.yml b/.github/.codecov.yml index 2b5037e..dc93acf 100644 --- a/.github/.codecov.yml +++ b/.github/.codecov.yml @@ -10,6 +10,8 @@ coverage: status: project: yes patch: yes + default: + target: 0% changes: no parsers: From 8c3371ff01b50ccaf9d9f08c7a01cad0e83a0bf1 Mon Sep 17 00:00:00 2001 From: Lianbo Jiang Date: Sun, 9 Aug 2020 20:39:20 +0800 Subject: [PATCH 106/146] codecov: allow to pass the codecov/patch coverage checking. The codecov coverage about the patch is very inconsistent, let's pass the checking no matter what the coverage is. Signed-off-by: Lianbo Jiang --- .github/.codecov.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/.codecov.yml b/.github/.codecov.yml index dc93acf..b89aac2 100644 --- a/.github/.codecov.yml +++ b/.github/.codecov.yml @@ -9,9 +9,10 @@ coverage: status: project: yes - patch: yes + patch: default: - target: 0% + target: auto + threshold: 100% changes: no parsers: From 9ddb75c693238750c74c953b367c54d53b3a26e2 Mon Sep 17 00:00:00 2001 From: Marco Filippi Date: Fri, 17 Mar 2017 12:16:24 +0100 Subject: [PATCH 107/146] Fix memory Type Detail map size Bit mapped type descriptions array size must be kept coerent with bit mask, for index and array size in xml map otherwise nasty errors could arise. Problem discovered on a machine having --- src/dmidecode.c | 4 ++-- src/pymap.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index 0f003c3..272d5a3 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -2905,9 +2905,9 @@ void dmi_memory_device_type_detail(xmlNode *node, u16 code) dmixml_AddAttribute(data_n, "dmispec", "7.18.3"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if((code & 0x1FFE) != 0) { + if((code & 0xFFFE) != 0) { int i; - for(i = 1; i <= 14; i++) { + for(i = 1; i <= 15; i++) { if(code & (1 << i)) { xmlNode *td_n = dmixml_AddTextChild(data_n, "flag", "%s", detail[i - 1]); assert( td_n != NULL ); diff --git a/src/pymap.xml b/src/pymap.xml index 7d5de70..7325a85 100644 --- a/src/pymap.xml +++ b/src/pymap.xml @@ -440,7 +440,7 @@ valuetype="string" value="concat(TotalWidth, ' ', TotalWidth/@unit)"/> + fixedsize="15" index_attr="index"/> Date: Sat, 17 Oct 2020 22:57:17 +0300 Subject: [PATCH 108/146] Enable alignment workaround for ARM arch Or unit test fails with: * Testing type 12...PASS * Testing type 19...make[1]: *** [Makefile:4: test] Bus error make[1]: Leaving directory '/usr/src/RPM/BUILD/python-modules-dmidecode-3.12.2/unit-tests' make: *** [Makefile:104: unit] Error 2 Signed-off-by: Vitaly Chikunov --- src/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.h b/src/config.h index 4fb28df..ac3c942 100644 --- a/src/config.h +++ b/src/config.h @@ -53,7 +53,7 @@ #endif /* Use memory alignment workaround or not */ -#ifdef __ia64__ +#if defined(__ia64__) || defined(__arm__) #define ALIGNMENT_WORKAROUND #endif From 64df8db99fc8b8b9c6ee7afcfae6c207ea1a17c9 Mon Sep 17 00:00:00 2001 From: Coiby Xu Date: Fri, 11 Jun 2021 11:15:06 +0800 Subject: [PATCH 109/146] fix RESOURCE_LEAK errors detected by covscan in src/dmidecodemodule.c Fix the following errors found by covscan, Error: RESOURCE_LEAK (CWE-772): [#def1] python-dmidecode-3.12.2/src/dmidecodemodule.c:274: alloc_fn: Storage is returned from allocation function "xmlNewNode". python-dmidecode-3.12.2/src/dmidecodemodule.c:274: var_assign: Assigning: "dmixml_n" = storage returned from "xmlNewNode(NULL, (xmlChar *)"dmidecode")". python-dmidecode-3.12.2/src/dmidecodemodule.c:284: leaked_storage: Variable "dmixml_n" going out of scope leaks the storage it points to. # 282| if( (group_n = load_mappingxml(opt)) == NULL) { # 283| // Exception already set by calling function # 284|-> return NULL; # 285| } # 286| Error: RESOURCE_LEAK (CWE-772): [#def2] python-dmidecode-3.12.2/src/dmidecodemodule.c:321: alloc_fn: Storage is returned from allocation function "log_retrieve". python-dmidecode-3.12.2/src/dmidecodemodule.c:321: var_assign: Assigning: "err" = storage returned from "log_retrieve(opt->logdata, 3)". python-dmidecode-3.12.2/src/dmidecodemodule.c:323: leaked_storage: Variable "err" going out of scope leaks the storage it points to. # 321| char *err = log_retrieve(opt->logdata, LOG_ERR); # 322| log_clear_partial(opt->logdata, LOG_ERR, 0); # 323|-> PyReturnError(PyExc_RuntimeError, "Invalid type id '%s' -- %s", typeid, err); # 324| } # 325| Error: RESOURCE_LEAK (CWE-772): [#def3] python-dmidecode-3.12.2/src/dmidecodemodule.c:388: alloc_fn: Storage is returned from allocation function "xmlNewNode". python-dmidecode-3.12.2/src/dmidecodemodule.c:388: var_assign: Assigning: "dmixml_n" = storage returned from "xmlNewNode(NULL, (xmlChar *)"dmidecode")". python-dmidecode-3.12.2/src/dmidecodemodule.c:397: leaked_storage: Variable "dmixml_n" going out of scope leaks the storage it points to. # 395| // Fetch the Mapping XML file # 396| if( load_mappingxml(opt) == NULL) { # 397|-> return NULL; # 398| } # 399| Error: RESOURCE_LEAK (CWE-772): [#def4] python-dmidecode-3.12.2/src/dmidecodemodule.c:823: alloc_fn: Storage is returned from allocation function "malloc". python-dmidecode-3.12.2/src/dmidecodemodule.c:823: var_assign: Assigning: "opt" = storage returned from "malloc(58UL)". python-dmidecode-3.12.2/src/dmidecodemodule.c:824: noescape: Resource "opt" is not freed or pointed-to in "memset". [Note: The source code implementation of the function has been overridden by a builtin model.] python-dmidecode-3.12.2/src/dmidecodemodule.c:825: noescape: Resource "opt" is not freed or pointed-to in "init". python-dmidecode-3.12.2/src/dmidecodemodule.c:833: leaked_storage: Variable "opt" going out of scope leaks the storage it points to. # 831| #endif # 832| if (module == NULL) # 833|-> MODINITERROR; # 834| # 835| version = PYTEXT_FROMSTRING(VERSION); Note for "Error: RESOURCE_LEAK (CWE-772): [#def2]", we have to call _PyReturnError directly so we can free the memory before return. --- src/dmidecodemodule.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index b31c002..b73811e 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -280,6 +280,7 @@ xmlNode *__dmidecode_xml_getsection(options *opt, const char *section) { // Fetch the Mapping XML file if( (group_n = load_mappingxml(opt)) == NULL) { + xmlFreeNode(dmixml_n); // Exception already set by calling function return NULL; } @@ -320,7 +321,9 @@ xmlNode *__dmidecode_xml_getsection(options *opt, const char *section) { if(opt->type == -1) { char *err = log_retrieve(opt->logdata, LOG_ERR); log_clear_partial(opt->logdata, LOG_ERR, 0); - PyReturnError(PyExc_RuntimeError, "Invalid type id '%s' -- %s", typeid, err); + _pyReturnError(PyExc_RuntimeError, "Invalid type id '%s' -- %s", typeid, err); + free(err); + return NULL; } // Parse the DMI data and put the result into dmixml_n node chain. @@ -394,6 +397,7 @@ xmlNode *__dmidecode_xml_gettypeid(options *opt, int typeid) // Fetch the Mapping XML file if( load_mappingxml(opt) == NULL) { + xmlFreeNode(dmixml_n); return NULL; } @@ -829,8 +833,10 @@ initdmidecodemod(void) module = Py_InitModule3((char *)"dmidecodemod", DMIDataMethods, "Python extension module for dmidecode"); #endif - if (module == NULL) + if (module == NULL) { + free(opt); MODINITERROR; + } version = PYTEXT_FROMSTRING(VERSION); Py_INCREF(version); From f0f4501e67491aa7deca0681e6285d4b2f9e6f16 Mon Sep 17 00:00:00 2001 From: Lianbo Jiang Date: Tue, 22 Jun 2021 10:04:10 +0800 Subject: [PATCH 110/146] Fix the failure of reporting "undefined symbol: dmixml_GetContent" Importing module...FAIL ../build/lib.linux-x86_64-2.7/dmidecodemod.so: undefined symbol: dmixml_GetContent Resolves: https://github.com/nima/python-dmidecode/issues/25 Signed-off-by: Lianbo Jiang --- src/dmixml.h | 4 ++-- src/xmlpythonizer.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dmixml.h b/src/dmixml.h index d8861ac..28ba2b7 100644 --- a/src/dmixml.h +++ b/src/dmixml.h @@ -75,8 +75,8 @@ xmlNode *__dmixml_FindNodeByAttr(xmlNode *, const char *, const char *, const ch xmlNode *dmixml_FindNode(xmlNode *, const char *key); -inline char *dmixml_GetContent(xmlNode *node); -inline char *dmixml_GetNodeContent(xmlNode *node, const char *key); +char *dmixml_GetContent(xmlNode *node); +char *dmixml_GetNodeContent(xmlNode *node, const char *key); char *dmixml_GetXPathContent(Log_t *logp, char *buf, size_t buflen, xmlXPathObject *xpo, int idx); #endif diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index e9c9242..d85da5f 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -603,7 +603,7 @@ ptzMAP *dmiMAP_ParseMappingXML_GroupName(Log_t *logp, xmlDoc *xmlmap, const char * @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(Log_t *logp, ptzMAP *val_m, const char *instr) { +static inline PyObject *StringToPyObj(Log_t *logp, ptzMAP *val_m, const char *instr) { PyObject *value; const char *workstr = NULL; @@ -772,7 +772,7 @@ char *_get_key_value(Log_t *logp, char *key, size_t buflen, * @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(Log_t *logp, PyObject *pydat, xmlXPathContext *xpctx, ptzMAP *map_p, xmlXPathObject *value) { +static inline void _add_xpath_result(Log_t *logp, PyObject *pydat, xmlXPathContext *xpctx, ptzMAP *map_p, xmlXPathObject *value) { int i = 0; char *key = NULL; char *val = NULL; From 3d172329018a0b5557b6d49ca5577956aaa92450 Mon Sep 17 00:00:00 2001 From: Lianbo Jiang Date: Tue, 22 Jun 2021 11:32:35 +0800 Subject: [PATCH 111/146] use python3 by default Signed-off-by: Lianbo Jiang --- Makefile | 2 +- unit-tests/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 76d23de..2f47a75 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,7 @@ #. $AutoHeaderSerial::20100225 $ #. ******* AUTOHEADER END v1.2 ******* -PY_BIN := python2 +PY_BIN := python3 VERSION := $(shell cd src;$(PY_BIN) -c "from setup_common import *; print(get_version());") PACKAGE := python-dmidecode PY_VER := $(shell $(PY_BIN) -c 'import sys; print("%d.%d"%sys.version_info[0:2])') diff --git a/unit-tests/Makefile b/unit-tests/Makefile index 765fd99..0b8af8e 100644 --- a/unit-tests/Makefile +++ b/unit-tests/Makefile @@ -1,4 +1,4 @@ -PY_BIN := python2 +PY_BIN := python3 test : $(PY_BIN) unit -vv From e8b625e8fb3ee61c0a26cb64c057851d00ef4c82 Mon Sep 17 00:00:00 2001 From: Nima Talebi Date: Wed, 23 Jun 2021 08:41:37 -0700 Subject: [PATCH 112/146] Update README --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 4892ef5..8b13789 100644 --- a/README +++ b/README @@ -1 +1 @@ -Please visit http://projects.autonomy.net.au/python-dmidecode/ + From d4e3206ad5fbfbb629b20f9370ef9fb190fd9719 Mon Sep 17 00:00:00 2001 From: Coiby Xu Date: Fri, 11 Jun 2021 11:00:27 +0800 Subject: [PATCH 113/146] fix RESOURCE_LEAK errors detected by covscan in src/xmlpythonizer.c Fix the following errors found by covscan, Error: RESOURCE_LEAK (CWE-772): [#def6] python-dmidecode-3.12.2/src/xmlpythonizer.c:847: alloc_fn: Storage is returned from allocation function "malloc". python-dmidecode-3.12.2/src/xmlpythonizer.c:847: var_assign: Assigning: "key" = storage returned from "malloc(258UL)". python-dmidecode-3.12.2/src/xmlpythonizer.c:853: noescape: Resource "key" is not freed or pointed-to in "_get_key_value". python-dmidecode-3.12.2/src/xmlpythonizer.c:857: leaked_storage: Variable "key" going out of scope leaks the storage it points to. # 855| PyADD_DICT_VALUE(retdata, key, value); # 856| } else { # 857|-> PyReturnError(PyExc_ValueError, "Could not get key value: %s [%i] (Defining key: %s)", # 858| map_p->rootpath, elmtid, map_p->key); # 859| } Error: RESOURCE_LEAK (CWE-772): [#def7] python-dmidecode-3.12.2/src/xmlpythonizer.c:847: alloc_fn: Storage is returned from allocation function "malloc". python-dmidecode-3.12.2/src/xmlpythonizer.c:847: var_assign: Assigning: "key" = storage returned from "malloc(258UL)". python-dmidecode-3.12.2/src/xmlpythonizer.c:879: noescape: Resource "key" is not freed or pointed-to in "_get_key_value". python-dmidecode-3.12.2/src/xmlpythonizer.c:921: leaked_storage: Variable "key" going out of scope leaks the storage it points to. # 919| xmlXPathFreeObject(xpo); # 920| } else { # 921|-> PyReturnError(PyExc_ValueError, "Could not get key value: " # 922| "%s [%i] (Defining key: %s)", # 923| map_p->rootpath, elmtid, map_p->key); Error: RESOURCE_LEAK (CWE-772): [#def8] python-dmidecode-3.12.2/src/xmlpythonizer.c:877: alloc_fn: Storage is returned from allocation function "_get_xpath_values". python-dmidecode-3.12.2/src/xmlpythonizer.c:877: var_assign: Assigning: "xpo" = storage returned from "_get_xpath_values(xpctx, map_p->value)". python-dmidecode-3.12.2/src/xmlpythonizer.c:921: leaked_storage: Variable "xpo" going out of scope leaks the storage it points to. # 919| xmlXPathFreeObject(xpo); # 920| } else { # 921|-> PyReturnError(PyExc_ValueError, "Could not get key value: " # 922| "%s [%i] (Defining key: %s)", # 923| map_p->rootpath, elmtid, map_p->key); Error: RESOURCE_LEAK (CWE-772): [#def9] python-dmidecode-3.12.2/src/xmlpythonizer.c:847: alloc_fn: Storage is returned from allocation function "malloc". python-dmidecode-3.12.2/src/xmlpythonizer.c:847: var_assign: Assigning: "key" = storage returned from "malloc(258UL)". python-dmidecode-3.12.2/src/xmlpythonizer.c:933: noescape: Resource "key" is not freed or pointed-to in "_get_key_value". python-dmidecode-3.12.2/src/xmlpythonizer.c:934: leaked_storage: Variable "key" going out of scope leaks the storage it points to. # 932| } # 933| if( _get_key_value(logp, key, 256, map_p, xpctx, 0) == NULL ) { # 934|-> PyReturnError(PyExc_ValueError, # 935| "Could not get key value: %s [%i] (Defining key: %s)", # 936| map_p->rootpath, elmtid, map_p->key); Error: RESOURCE_LEAK (CWE-772): [#def10] python-dmidecode-3.12.2/src/xmlpythonizer.c:847: alloc_fn: Storage is returned from allocation function "malloc". python-dmidecode-3.12.2/src/xmlpythonizer.c:847: var_assign: Assigning: "key" = storage returned from "malloc(258UL)". python-dmidecode-3.12.2/src/xmlpythonizer.c:947: noescape: Resource "key" is not freed or pointed-to in "_get_key_value". python-dmidecode-3.12.2/src/xmlpythonizer.c:948: leaked_storage: Variable "key" going out of scope leaks the storage it points to. # 946| } # 947| if( _get_key_value(logp, key, 256, map_p, xpctx, 0) == NULL ) { # 948|-> PyReturnError(PyExc_ValueError, # 949| "Could not get key value: %s [%i] (Defining key: %s)", # 950| map_p->rootpath, elmtid, map_p->key); Error: RESOURCE_LEAK (CWE-772): [#def11] python-dmidecode-3.12.2/src/xmlpythonizer.c:847: alloc_fn: Storage is returned from allocation function "malloc". python-dmidecode-3.12.2/src/xmlpythonizer.c:847: var_assign: Assigning: "key" = storage returned from "malloc(258UL)". python-dmidecode-3.12.2/src/xmlpythonizer.c:947: identity_transfer: Passing "key" as argument 2 to function "_get_key_value", which returns that argument. python-dmidecode-3.12.2/src/xmlpythonizer.c:947: noescape: Resource "key" is not freed or pointed-to in "_get_key_value". python-dmidecode-3.12.2/src/xmlpythonizer.c:959: leaked_storage: Variable "key" going out of scope leaks the storage it points to. # 957| xmlXPathFreeObject(xpo); # 958| } # 959|-> PyReturnError(PyExc_ValueError, # 960| "Could not get key value: %s [%i] (Defining key: %s)", # 961| map_p->rootpath, elmtid, map_p->key); Error: RESOURCE_LEAK (CWE-772): [#def12] python-dmidecode-3.12.2/src/xmlpythonizer.c:847: alloc_fn: Storage is returned from allocation function "malloc". python-dmidecode-3.12.2/src/xmlpythonizer.c:847: var_assign: Assigning: "key" = storage returned from "malloc(258UL)". python-dmidecode-3.12.2/src/xmlpythonizer.c:947: identity_transfer: Passing "key" as argument 2 to function "_get_key_value", which returns that argument. python-dmidecode-3.12.2/src/xmlpythonizer.c:947: noescape: Resource "key" is not freed or pointed-to in "_get_key_value". python-dmidecode-3.12.2/src/xmlpythonizer.c:995: leaked_storage: Variable "key" going out of scope leaks the storage it points to. # 993| } else { # 994| // If NULL, something is wrong - exception is already set. # 995|-> return NULL; # 996| } # 997| } Error: RESOURCE_LEAK (CWE-772): [#def13] python-dmidecode-3.12.2/src/xmlpythonizer.c:954: alloc_fn: Storage is returned from allocation function "_get_xpath_values". python-dmidecode-3.12.2/src/xmlpythonizer.c:954: var_assign: Assigning: "xpo" = storage returned from "_get_xpath_values(xpctx, map_p->value)". python-dmidecode-3.12.2/src/xmlpythonizer.c:995: leaked_storage: Variable "xpo" going out of scope leaks the storage it points to. # 993| } else { # 994| // If NULL, something is wrong - exception is already set. # 995|-> return NULL; # 996| } # 997| } Error: RESOURCE_LEAK (CWE-772): [#def14] python-dmidecode-3.12.2/src/xmlpythonizer.c:1031: alloc_fn: Storage is returned from allocation function "malloc". python-dmidecode-3.12.2/src/xmlpythonizer.c:1031: var_assign: Assigning: "key" = storage returned from "malloc(258UL)". python-dmidecode-3.12.2/src/xmlpythonizer.c:1050: leaked_storage: Variable "key" going out of scope leaks the storage it points to. # 1048| xpctx = xmlXPathNewContext(xpdoc); # 1049| if( xpctx == NULL ) { # 1050|-> PyReturnError(PyExc_MemoryError, "Could not setup new XPath context"); # 1051| } # 1052| xpctx->node = data_n; Error: RESOURCE_LEAK (CWE-772): [#def15] python-dmidecode-3.12.2/src/xmlpythonizer.c:1054: alloc_fn: Storage is returned from allocation function "_get_xpath_values". python-dmidecode-3.12.2/src/xmlpythonizer.c:1054: var_assign: Assigning: "xpo" = storage returned from "_get_xpath_values(xpctx, map_p->rootpath)". python-dmidecode-3.12.2/src/xmlpythonizer.c:1065: leaked_storage: Variable "xpo" going out of scope leaks the storage it points to. # 1063| // Exit if we get NULL - something is wrong # 1064| //and exception is set # 1065|-> return NULL; # 1066| } # 1067| } Error: RESOURCE_LEAK (CWE-772): [#def16] python-dmidecode-3.12.2/src/xmlpythonizer.c:1031: alloc_fn: Storage is returned from allocation function "malloc". python-dmidecode-3.12.2/src/xmlpythonizer.c:1031: var_assign: Assigning: "key" = storage returned from "malloc(258UL)". python-dmidecode-3.12.2/src/xmlpythonizer.c:1059: identity_transfer: Passing "key" as argument 2 to function "_get_key_value", which returns that argument. python-dmidecode-3.12.2/src/xmlpythonizer.c:1059: noescape: Resource "key" is not freed or pointed-to in "_get_key_value". python-dmidecode-3.12.2/src/xmlpythonizer.c:1059: identity_transfer: Passing "key" as argument 2 to function "_get_key_value", which returns that argument. python-dmidecode-3.12.2/src/xmlpythonizer.c:1059: noescape: Resource "key" is not freed or pointed-to in "_get_key_value". python-dmidecode-3.12.2/src/xmlpythonizer.c:1087: leaked_storage: Variable "key" going out of scope leaks the storage it points to. # 1085| // Exit if we get NULL - something is wrong # 1086| //and exception is set # 1087|-> return NULL; # 1088| } # 1089| } --- src/xmlpythonizer.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index d85da5f..9dbf079 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -854,6 +854,9 @@ PyObject *_deep_pythonize(Log_t *logp, PyObject *retdata, value = PyBytes_FromString(map_p->value); PyADD_DICT_VALUE(retdata, key, value); } else { + xmlXPathFreeContext(xpctx); + xmlFreeDoc(xpdoc); + free(key); PyReturnError(PyExc_ValueError, "Could not get key value: %s [%i] (Defining key: %s)", map_p->rootpath, elmtid, map_p->key); } @@ -918,6 +921,10 @@ PyObject *_deep_pythonize(Log_t *logp, PyObject *retdata, PyADD_DICT_VALUE(retdata, key, value); xmlXPathFreeObject(xpo); } else { + xmlXPathFreeObject(xpo); + xmlXPathFreeContext(xpctx); + xmlFreeDoc(xpdoc); + free(key); PyReturnError(PyExc_ValueError, "Could not get key value: " "%s [%i] (Defining key: %s)", map_p->rootpath, elmtid, map_p->key); @@ -931,6 +938,9 @@ PyObject *_deep_pythonize(Log_t *logp, PyObject *retdata, break; } if( _get_key_value(logp, key, 256, map_p, xpctx, 0) == NULL ) { + xmlXPathFreeContext(xpctx); + xmlFreeDoc(xpdoc); + free(key); PyReturnError(PyExc_ValueError, "Could not get key value: %s [%i] (Defining key: %s)", map_p->rootpath, elmtid, map_p->key); @@ -945,6 +955,9 @@ PyObject *_deep_pythonize(Log_t *logp, PyObject *retdata, break; } if( _get_key_value(logp, key, 256, map_p, xpctx, 0) == NULL ) { + xmlXPathFreeContext(xpctx); + xmlFreeDoc(xpdoc); + free(key); PyReturnError(PyExc_ValueError, "Could not get key value: %s [%i] (Defining key: %s)", map_p->rootpath, elmtid, map_p->key); @@ -956,6 +969,9 @@ PyObject *_deep_pythonize(Log_t *logp, PyObject *retdata, if( xpo != NULL ) { xmlXPathFreeObject(xpo); } + xmlXPathFreeContext(xpctx); + xmlFreeDoc(xpdoc); + free(key); PyReturnError(PyExc_ValueError, "Could not get key value: %s [%i] (Defining key: %s)", map_p->rootpath, elmtid, map_p->key); @@ -991,6 +1007,10 @@ PyObject *_deep_pythonize(Log_t *logp, PyObject *retdata, PyList_Append(value, dataset); } } else { + xmlXPathFreeObject(xpo); + xmlXPathFreeContext(xpctx); + xmlFreeDoc(xpdoc); + free(key); // If NULL, something is wrong - exception is already set. return NULL; } @@ -1047,6 +1067,8 @@ PyObject *pythonizeXMLnode(Log_t *logp, ptzMAP *in_map, xmlNode *data_n) { xpctx = xmlXPathNewContext(xpdoc); if( xpctx == NULL ) { + xmlFreeDoc(xpdoc); + free(key); PyReturnError(PyExc_MemoryError, "Could not setup new XPath context"); } xpctx->node = data_n; @@ -1062,6 +1084,10 @@ PyObject *pythonizeXMLnode(Log_t *logp, ptzMAP *in_map, xmlNode *data_n) { if( res == NULL ) { // Exit if we get NULL - something is wrong //and exception is set + xmlXPathFreeObject(xpo); + xmlXPathFreeContext(xpctx); + xmlFreeDoc(xpdoc); + free(key); return NULL; } } @@ -1084,6 +1110,7 @@ PyObject *pythonizeXMLnode(Log_t *logp, ptzMAP *in_map, xmlNode *data_n) { if( res == NULL ) { // Exit if we get NULL - something is wrong //and exception is set + free(key); return NULL; } } From ed25b29e1db35f21ba1c2c4397b42b1444a664bf Mon Sep 17 00:00:00 2001 From: Coiby Xu Date: Fri, 11 Jun 2021 11:06:59 +0800 Subject: [PATCH 114/146] fix RESOURCE_LEAK error detected by covscan in src/util.c Fix the following error, Error: RESOURCE_LEAK (CWE-772): [#def5] python-dmidecode-3.12.2/src/util.c:123: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.] python-dmidecode-3.12.2/src/util.c:123: var_assign: Assigning: "fd" = handle returned from "open(devmem, 0)". python-dmidecode-3.12.2/src/util.c:147: noescape: Resource "fd" is not freed or pointed-to in "mmap". python-dmidecode-3.12.2/src/util.c:191: leaked_handle: Handle variable "fd" going out of scope leaks the handle. by initializing fd to -1 moving close(fd) to exit. --- src/util.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/util.c b/src/util.c index acef5bd..da97767 100644 --- a/src/util.c +++ b/src/util.c @@ -112,7 +112,7 @@ void sigill_handler(int ignore_this) { void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem) { void *p; - int fd; + int fd = -1; #ifdef USE_MMAP size_t mmoffset; @@ -182,10 +182,11 @@ void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem) } #endif /* USE_MMAP */ - if(close(fd) == -1) - perror(devmem); - exit: + if (fd >= 0) { + if(close(fd) == -1) + perror(devmem); + } signal(SIGILL, SIG_DFL); sigill_logobj = NULL; return p; From 9e0371d81b37d76b93605a0f1e285f003a3f0a11 Mon Sep 17 00:00:00 2001 From: Coiby Xu Date: Tue, 15 Jun 2021 10:47:03 +0800 Subject: [PATCH 115/146] fix Error: CONSTANT_EXPRESSION_RESULT detected by covscan This commit fixes the following error found by conscan, Error: CONSTANT_EXPRESSION_RESULT (CWE-569): [#def1] python-dmidecode-3.12.2/src/dmidecode.c:225: logical_vs_bitwise: The expression "16 && i < h->length - (row << 4)" is suspicious because it performs a Boolean operation on a constant other than 0 or 1. # 223| memset(tmp_s, 0, (h->length * 2) + 2); # 224| # 225|-> for(i = 0; i < (16 && i < h->length - (row << 4)); i++) { # 226| snprintf(tmp_s + strlen(tmp_s), (h->length * 2)-strlen(tmp_s), # 227| "0x%02x", (h->data)[(row << 4) + i]); --- src/dmidecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index d2bed53..9efab60 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -222,7 +222,7 @@ void dmi_dump(xmlNode *node, struct dmi_header * h) 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++) { + 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]); } From 70be83244dfcc3fc6b5c583a602941df3e5d1b38 Mon Sep 17 00:00:00 2001 From: Coiby Xu Date: Tue, 15 Jun 2021 10:48:50 +0800 Subject: [PATCH 116/146] fix Error: MISSING_COMMA: detected by covscan This commit fixes the following errors found by conscan, Error: MISSING_COMMA: [#def3] python-dmidecode-3.12.2/src/dmidecode.c:1375: missing_comma: In the initialization of "upgrade", a suspicious concatenated string ""Socket BGA1288Socket rPGA988B"" is produced due to a missing comma between lines. python-dmidecode-3.12.2/src/dmidecode.c:1375: remediation: Did you intend to separate these two string literals with a comma? # 1373| "Socket LGA1567", # 1374| "Socket PGA988A", # 1375|-> "Socket BGA1288" /* 0x20 */ # 1376| "Socket rPGA988B", # 1377| "Socket BGA1023", Error: MISSING_COMMA: [#def4] python-dmidecode-3.12.2/src/dmidecode.c:1843: missing_comma: In the initialization of "type", a suspicious concatenated string ""64-way Set-associative20-way Set-associative"" is produced due to a missing comma between lines. python-dmidecode-3.12.2/src/dmidecode.c:1843: remediation: Did you intend to separate these two string literals with a comma? Error: MISSING_COMMA: [#def6] python-dmidecode-3.12.2/src/dmidecode.c:2868: missing_comma: In the initialization of "type", a suspicious concatenated string ""DDR3FBD2"" is produced. python-dmidecode-3.12.2/src/dmidecode.c:2868: remediation: Did you intend to separate these two string literals with a comma? # 2866| "Reserved", # 2867| "Reserved", # 2868|-> "DDR3" # 2869| "FBD2" /* 0x19 */ # 2870| }; # 1841| "32-way Set-associative", # 1842| "48-way Set-associative", # 1843|-> "64-way Set-associative" /* 0x0D */ # 1844| "20-way Set-associative" /* 0x0E */ --- src/dmidecode.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index 9efab60..d30a5d3 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -1372,7 +1372,7 @@ void dmi_processor_upgrade(xmlNode *node, u8 code) "Socket LGA1156", "Socket LGA1567", "Socket PGA988A", - "Socket BGA1288" /* 0x20 */ + "Socket BGA1288", /* 0x20 */ "Socket rPGA988B", "Socket BGA1023", "Socket BGA1224", @@ -1840,7 +1840,7 @@ void dmi_cache_associativity(xmlNode *node, u8 code) "24-way Set-associative", "32-way Set-associative", "48-way Set-associative", - "64-way Set-associative" /* 0x0D */ + "64-way Set-associative", /* 0x0D */ "20-way Set-associative" /* 0x0E */ }; xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Associativity", NULL); @@ -2865,7 +2865,7 @@ void dmi_memory_device_type(xmlNode *node, u8 code) "Reserved", "Reserved", "Reserved", - "DDR3" + "DDR3", "FBD2" /* 0x19 */ }; xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Type", NULL); From 17e01f358f2cbf9845e9dfdaa5e92677f37a30f7 Mon Sep 17 00:00:00 2001 From: Coiby Xu Date: Tue, 15 Jun 2021 10:57:45 +0800 Subject: [PATCH 117/146] fix "src/dmierror.c:55:9: warning[-Wanalyzer-possible-null-argument]: use of possibly-NULL buf where non-null expected" Fix the following error found by covscan, python-dmidecode-3.12.2/src/dmierror.c:55:9: warning[-Wanalyzer-possible-null-argument]: use of possibly-NULL buf where non-null expected /usr/include/python3.9/Python.h:30: included_from: Included from here. python-dmidecode-3.12.2/src/dmierror.c:32: included_from: Included from here. /usr/include/string.h:61:14: note: argument 1 of memset must be non-null # 53| va_start(ap, fmt); # 54| buf = (char *) malloc(4098); # 55|-> memset(buf, 0, 4098); # 56| # 57| if( buf == NULL ) { --- src/dmierror.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dmierror.c b/src/dmierror.c index d64b4b9..7054cd8 100644 --- a/src/dmierror.c +++ b/src/dmierror.c @@ -52,7 +52,6 @@ void _pyReturnError(void *exception, const char *fname, int line, const char *fm 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 @@ -64,6 +63,7 @@ void _pyReturnError(void *exception, const char *fname, int line, const char *fm return; } + memset(buf, 0, 4098); // Set the error state and message snprintf(buf, 4096, "[%s:%i] %s", fname, line, fmt); PyErr_Format(exception, buf, ap); From 19a382fedd7e3a3784ecb2d77f627285fd0333b4 Mon Sep 17 00:00:00 2001 From: Coiby Xu Date: Tue, 15 Jun 2021 11:03:21 +0800 Subject: [PATCH 118/146] fix Error: FORWARD_NULL (CWE-476): [#def23] Fix the following errors found by covscan, Error: FORWARD_NULL (CWE-476): [#def23] python-dmidecode-3.12.2/src/dmilog.c:48: var_compare_op: Comparing "ret" to null implies that "ret" might be null. python-dmidecode-3.12.2/src/dmilog.c:51: var_deref_op: Dereferencing null pointer "ret". # 49| fprintf(stderr, "** ERROR ** Could not allocate memory for log data\n"); # 50| } # 51|-> ret->level = -1; // Initialised - chain header pointer always have -1. # 52| return ret; # 53| } Error: CLANG_WARNING: [#def24] python-dmidecode-3.12.2/src/dmilog.c:51:13: warning[core.NullDereference]: Access to field 'level' results in a dereference of a null pointer (loaded from variable 'ret') # 49| fprintf(stderr, "** ERROR ** Could not allocate memory for log data\n"); # 50| } # 51|-> ret->level = -1; // Initialised - chain header pointer always have -1. # 52| return ret; # 53| } Error: GCC_ANALYZER_WARNING (CWE-476): [#def25] python-dmidecode-3.12.2/src/dmilog.c: scope_hint: In function 'log_init' python-dmidecode-3.12.2/src/dmilog.c:51:20: warning[-Wanalyzer-null-dereference]: dereference of NULL 'ret' # 49| fprintf(stderr, "** ERROR ** Could not allocate memory for log data\n"); # 50| } # 51|-> ret->level = -1; // Initialised - chain header pointer always have -1. # 52| return ret; # 53| } Error: GCC_ANALYZER_WARNING (CWE-476): [#def26] python-dmidecode-3.12.2/src/dmilog.c: scope_hint: In function log_init python-dmidecode-3.12.2/src/dmilog.c:51:20: warning[-Wanalyzer-null-dereference]: dereference of NULL ret # 49| fprintf(stderr, "** ERROR ** Could not allocate memory for log data\n"); # 50| } # 51|-> ret->level = -1; // Initialised - chain header pointer always have -1. # 52| return ret; # 53| } --- src/dmilog.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dmilog.c b/src/dmilog.c index f7ade5d..80b2ac3 100644 --- a/src/dmilog.c +++ b/src/dmilog.c @@ -47,6 +47,7 @@ Log_t * log_init() ret = (Log_t *) calloc(1, sizeof(Log_t)+2); if( !ret ) { fprintf(stderr, "** ERROR ** Could not allocate memory for log data\n"); + return ret; } ret->level = -1; // Initialised - chain header pointer always have -1. return ret; From 467038237266e2c1bec79d1d6698170b81208026 Mon Sep 17 00:00:00 2001 From: Coiby Xu Date: Tue, 15 Jun 2021 11:09:33 +0800 Subject: [PATCH 119/146] fix "src/dmidecodemodule.c:828:9 warning[-Wanalyzer-possible-null-argument]: use of possibly-NULL opt where non-null expected" Fix the following error found by covscan, Error: GCC_ANALYZER_WARNING (CWE-688): [#def20] python-dmidecode-3.12.2/src/dmidecodemodule.c:828:9: warning[-Wanalyzer-possible-null-argument]: use of possibly-NULL opt where non-null expected /usr/include/python3.9/Python.h:30: included_from: Included from here. python-dmidecode-3.12.2/src/dmidecodemodule.c:42: included_from: Included from here. /usr/include/string.h:61:14: note: argument 1 of memset must be non-null --- src/dmidecodemodule.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index b73811e..44ef7aa 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -825,6 +825,9 @@ initdmidecodemod(void) xmlXPathInit(); opt = (options *) malloc(sizeof(options)+2); + if (opt == NULL) + MODINITERROR; + memset(opt, 0, sizeof(options)+2); init(opt); #ifdef IS_PY3K From aef6454e2c916a705539bbc551f0ff6aa3f31987 Mon Sep 17 00:00:00 2001 From: Huzz Date: Sat, 3 Sep 2022 20:03:27 +0800 Subject: [PATCH 120/146] Fix reading info permission deny bugs. Details: 1. Change default /dev/mem to sysfs tables, if /dev/mem is unavailable, use sysfs tables instead. 2. Modify init method from dmidecodemodule. 3. Add read_file function instead memchunk. 4. Add SM3 reading function and get version function. 5. Test physical machine and KVM machine Resolves: https://github.com/nima/python-dmidecode/pull/39 Signed-off-by: Huzz --- src/dmidecode.c | 117 ++++++++++---- src/dmidecode.h | 13 +- src/dmidecodemodule.c | 367 ++++++++++++++++++++++++++++++------------ src/dmidecodemodule.h | 6 +- src/dmidump.c | 272 +++++++++++++++++++------------ src/dmidump.h | 7 + src/util.c | 166 +++++++++++++++++-- src/util.h | 1 + 8 files changed, 703 insertions(+), 246 deletions(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index d30a5d3..19958d3 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -5197,7 +5197,7 @@ dmi_codes_major *find_dmiMajor(const struct dmi_header *h) return NULL; } -static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver, const char *devmem, xmlNode *xmlnode) +static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver, const char *devmem, u32 flags, xmlNode *xmlnode) { static u8 version_added = 0; u8 *buf; @@ -5221,35 +5221,40 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver info_n = NULL; } - if((buf = mem_chunk(logp, base, len, devmem)) == NULL) { - log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Table is unreachable, sorry." -#ifndef USE_MMAP - "Try compiling dmidecode with -DUSE_MMAP." -#endif - ); - return; - } + if(flags & FLAG_NO_FILE_OFFSET){ + /* + * When reading from sysfs or from a dump file, the file may be + * shorter than announced. For SMBIOS v3 this is expcted, as we + * only know the maximum table size, not the actual table size. + * For older implementations (and for SMBIOS v3 too), this + * would be the result of the kernel truncating the table on + * parse error. + */ + size_t size = len; + buf = read_file(logp, flags & FLAG_NO_FILE_OFFSET ? 0 : base, &size, devmem); + if (num && size != (size_t)len){ + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Wrong DMI structures length: %i bytes announced, only %lu bytes available.\n", len, (unsigned long)size ); + } + len = size; + } else { + buf = mem_chunk(logp, base, len, devmem); + } + + if (ver > SUPPORTED_SMBIOS_VER){ + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "# SMBIOS implementations newer than version %u.%u are not\n", "# fully supported by this version of dmidecode.\n", SUPPORTED_SMBIOS_VER >> 8, SUPPORTED_SMBIOS_VER & 0xFF); + } - if (ver > SUPPORTED_SMBIOS_VER) { - log_append(logp, LOGFL_NODUPS, LOG_WARNING, - "# SMBIOS implementations newer than version %u.%u are not\n" - "# fully supported by this version of dmidecode.\n", - SUPPORTED_SMBIOS_VER >> 8, SUPPORTED_SMBIOS_VER & 0xFF); - } - // FIXME: This is hackerish ... rather try to avoid looping dmi_table() calls too much if( version_added == 0 ) { dmixml_AddAttribute(xmlnode, "smbios_version", "%u.%u", ver >> 8, ver & 0xFF); version_added = 1; } - data = buf; - while(i < num && data + 4 <= buf + len) { /* 4 is the length of an SMBIOS structure header */ - + 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. @@ -5258,8 +5263,8 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver */ if(h.length < 4) { log_append(logp, LOGFL_NORMAL, LOG_WARNING, - "Invalid entry length (%i) for type %i. DMI table is broken! Stop.", - (unsigned int)h.length, type); + "Invalid entry length (%i) for type %i. DMI table is broken! Stop.", + (unsigned int)h.length, type); break; } @@ -5278,7 +5283,6 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver next++; } next += 2; - xmlNode *handle_n = NULL; if( h.type == type ) { if(next - buf <= len) { @@ -5309,6 +5313,7 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver dmixml_AddAttribute(handle_n, "length", "%i", (next - buf)); dmixml_AddAttribute(handle_n, "expected_length", "%i", len); + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "DMI/SMBIOS type 0x%02X is exceeding the expected buffer " "size by %i bytes. Will not decode this entry.", @@ -5344,6 +5349,60 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver free(buf); } +int _smbios3_decode_check(u8 *buf){ + int check = (!checksum(buf, buf[0x06])) ? 0 : 1; + return check; +} + +xmlNode *smbios3_decode_get_version(u8 * buf, const char *devmem) +{ + int check = _smbios3_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[0x07] << 16) + (buf[0x08] << 8) + buf[0x09]; + + dmixml_AddTextContent(data_n, "SMBIOS %i.%i.%i present", buf[0x07], buf[0x08], buf[0x09]); + dmixml_AddAttribute(data_n, "version", "%i.%i.%i", buf[0x07], buf[0x08],buf[0x09]); + } else if(check == 0) { + dmixml_AddTextContent(data_n, "No SMBIOS nor DMI entry point found"); + dmixml_AddAttribute(data_n, "unknown", "1"); + } + return data_n; +} + +int smbios3_decode(Log_t *logp, int type, u8 *buf, const char *devmem, u32 flags, xmlNode *xmlnode) +{ + u32 ver; + u64 offset; + + /* Don't let checksum run beyond the buffer */ + if (buf[0x06] > 0x20) + { + return 0; + } + + int check = _smbios3_decode_check(buf); + if (check == 1) + { + ver = (buf[0x07] << 16) + (buf[0x08] << 8) + buf[0x09]; + offset = QWORD(buf + 0x10); + + if (!(flags & FLAG_NO_FILE_OFFSET) && offset.h && sizeof(off_t) < 8) + { + return 0; + } + + dmi_table(logp, type, ((off_t)offset.h << 32) | offset.l, DWORD(buf+0x0C), 0, ver, devmem, flags | FLAG_STOP_AT_EOT, xmlnode); + } + + return check; +} + int _smbios_decode_check(u8 * buf) { int check = (!checksum(buf, buf[0x05]) || memcmp(buf + 0x10, "_DMI_", 5) != 0 || @@ -5370,7 +5429,8 @@ xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem) _M = 0; switch (ver) { case 0x021F: - _m = 31; + case 0x0221: + _m = ver & 0xFF; _M = 3; ver = 0x0203; break; @@ -5396,7 +5456,7 @@ xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem) return data_n; } -int smbios_decode(Log_t *logp, int type, u8 *buf, const char *devmem, xmlNode *xmlnode) +int smbios_decode(Log_t *logp, int type, u8 *buf, const char *devmem, u32 flags, xmlNode *xmlnode) { int check = _smbios_decode_check(buf); @@ -5405,6 +5465,7 @@ int smbios_decode(Log_t *logp, int type, u8 *buf, const char *devmem, xmlNode *x switch (ver) { case 0x021F: + case 0x0221: ver = 0x0203; break; case 0x0233: @@ -5413,7 +5474,7 @@ int smbios_decode(Log_t *logp, int type, u8 *buf, const char *devmem, xmlNode *x } // printf(">>%d @ %d, %d<<\n", DWORD(buf+0x18), WORD(buf+0x16), WORD(buf+0x1C)); dmi_table(logp, type, DWORD(buf + 0x18), WORD(buf + 0x16), WORD(buf + 0x1C), ver, devmem, - xmlnode); + flags, xmlnode); } return check; } @@ -5451,13 +5512,13 @@ xmlNode *legacy_decode_get_version(u8 * buf, const char *devmem) return data_n; } -int legacy_decode(Log_t *logp, int type, u8 *buf, const char *devmem, xmlNode *xmlnode) +int legacy_decode(Log_t *logp, int type, u8 *buf, const char *devmem, u32 flags, xmlNode *xmlnode) { int check = _legacy_decode_check(buf); if(check == 1) dmi_table(logp, type, DWORD(buf + 0x08), WORD(buf + 0x06), WORD(buf + 0x0C), - ((buf[0x0E] & 0xF0) << 4) + (buf[0x0E] & 0x0F), devmem, xmlnode); + ((buf[0x0E] & 0xF0) << 4) + (buf[0x0E] & 0x0F), devmem, flags, xmlnode); return check; } diff --git a/src/dmidecode.h b/src/dmidecode.h index 926bd5d..22d70e1 100644 --- a/src/dmidecode.h +++ b/src/dmidecode.h @@ -23,6 +23,13 @@ #include "dmihelper.h" #include "dmierror.h" +#define FLAG_NO_FILE_OFFSET (1 << 0) +#define FLAG_STOP_AT_EOT (1 << 1) + +#define SYS_FIRMWARE_DIR "/sys/firmware/dmi/tables" +#define SYS_ENTRY_FILE SYS_FIRMWARE_DIR "/smbios_entry_point" +#define SYS_TABLE_FILE SYS_FIRMWARE_DIR "/DMI" + struct dmi_header { u8 type; u8 length; @@ -34,10 +41,12 @@ 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); +xmlNode *smbios3_decode_get_version(u8 * buf, const char *devmem); xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem); xmlNode *legacy_decode_get_version(u8 * buf, const char *devmem); -int smbios_decode(Log_t *logp, int type, u8 *buf, const char *devmem, xmlNode *xmlnode); -int legacy_decode(Log_t *logp, int type, u8 *buf, const char *devmem, xmlNode *xmlnode); +int smbios3_decode(Log_t *logp, int type, u8 *buf, const char *devmem, u32 flags, xmlNode *xmlnode); +int smbios_decode(Log_t *logp, int type, u8 *buf, const char *devmem, u32 flags, xmlNode *xmlnode); +int legacy_decode(Log_t *logp, int type, u8 *buf, const char *devmem, u32 flags, xmlNode *xmlnode); const char *dmi_string(const struct dmi_header *dm, u8 s); void dmi_system_uuid(xmlNode *node, const u8 * p, u16 ver); diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 44ef7aa..d3ac7ff 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -66,7 +66,9 @@ char *PyUnicode_AsUTF8(PyObject *unicode) { static void init(options *opt) { - opt->devmem = DEFAULT_MEM_DEV; + int efi; + size_t fp; + opt->dumpfile = NULL; opt->flags = 0; opt->type = -1; @@ -75,6 +77,13 @@ static void init(options *opt) opt->python_xml_map = strdup(PYTHON_XML_MAP); opt->logdata = log_init(); + efi = address_from_efi(opt->logdata, &fp); + if(efi == EFI_NOT_FOUND){ + opt->devmem = DEFAULT_MEM_DEV; + } else { + opt->devmem = SYS_TABLE_FILE; + } + /* sanity check */ if(sizeof(u8) != 1 || sizeof(u16) != 2 || sizeof(u32) != 4 || '\0' != 0) { log_append(opt->logdata, LOGFL_NORMAL, LOG_WARNING, @@ -116,70 +125,149 @@ xmlNode *dmidecode_get_version(options *opt) int efi; u8 *buf = NULL; xmlNode *ver_n = NULL; + size_t size; - /* Set default option values */ + /* + * First, if devmem is available, set default as DEFAULT_MEM_DEV + * Set default option values + */ if( opt->devmem == NULL ) { - opt->devmem = DEFAULT_MEM_DEV; + efi = address_from_efi(opt->logdata, &fp); + if(efi == EFI_NOT_FOUND){ + opt->devmem = DEFAULT_MEM_DEV; + } else { + opt->devmem = SYS_TABLE_FILE; + } } /* Read from dump if so instructed */ if(opt->dumpfile != NULL) { //. printf("Reading SMBIOS/DMI data from file %s.\n", dumpfile); if((buf = mem_chunk(opt->logdata, 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(opt->logdata, &fp); - if(efi == EFI_NOT_FOUND) { - /* Fallback to memory scan (x86, x86_64) */ - if((buf = mem_chunk(opt->logdata, 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(opt->logdata, 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); - } + ver_n = NULL; + goto exit_free; + } + if(memcmp(buf, "_SM3_", 5) == 0){ + ver_n = smbios3_decode_get_version(buf, opt->dumpfile); + if ( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) + found++; + } else 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++; } } - if( buf != NULL ) { - free(buf); - } - if( !found ) { + + /* + * First try reading from sysfs tables. The entry point file could + * contain one of several types of entry points, so read enough for + * the largest one, then determine what type it contains. + */ + size = 0x20; + if ( (buf = read_file(opt->logdata, 0, &size, SYS_ENTRY_FILE)) != NULL ){ + if(size >= 24 && memcmp(buf, "_SM3_", 5) == 0){ + ver_n = smbios3_decode_get_version(buf, opt->devmem); + if (dmixml_GetAttrValue(ver_n, "unknown") == NULL) + found++; + } else if (size >= 31 && memcmp(buf, "_SM_", 4) == 0 ){ + ver_n = smbios_decode_get_version(buf, opt->devmem); + if (dmixml_GetAttrValue(ver_n, "unknown") == NULL) + found++; + } else if (size >= 15 && memcmp(buf, "_DMI_", 5) == 0){ + ver_n = legacy_decode_get_version (buf, opt->devmem); + if (dmixml_GetAttrValue(ver_n, "unknown") == NULL) + found++; + } + + if(found) + goto done; + } else { + ver_n = NULL; + goto exit_free; + } + + /* Read from /dev/mem */ + /* Next try EFI (ia64, Intel-based Mac) */ + efi = address_from_efi(opt->logdata, &fp); + switch(efi){ + case EFI_NOT_FOUND: + goto memory_scan; + case EFI_NO_SMBIOS: + ver_n = NULL; + goto exit_free; + } + + if(buf = mem_chunk(opt->logdata, fp, 0x20, opt->devmem) == NULL){ + ver_n = NULL; + goto exit_free; + } + + if(memcmp(buf, "_SM3_", 5) == 0){ + ver_n = smbios3_decode_get_version(buf, opt->devmem); + if(dmixml_GetAttrValue(ver_n, "unknown") == NULL) + found++; + } else if (memcmp(buf, "_SM_", 4) == 0 ) { + ver_n = smbios_decode_get_version(buf, opt->devmem); + if(dmixml_GetAttrValue(ver_n, "unknown") == NULL) + found++; + } + + goto done; + +memory_scan: +#if defined __i386__ || defined __x86_64__ + /* Fallback to memory scan (x86, x86_64) */ + if((buf = mem_chunk(opt->logdata, 0xF0000, 0x10000, opt->devmem)) == NULL) { + ver_n = NULL; + goto exit_free; + } + + /* Look for a 64-bit entry point first */ + for (fp = 0; fp <= 0xFFE0; fp+= 16){ + if(memcmp(buf+fp, "_SM3_", 5) == 0){ + ver_n = smbios3_decode_get_version(buf+fp, opt->devmem); + if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) { + found++; + goto done; + } + } + } + + /* If none found, look for a 32-bit entry point */ + 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++; + goto done; + } + 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++; + goto done; + } + } + } +#endif + +done: + if(!found){ log_append(opt->logdata, LOGFL_NODUPS, LOG_WARNING, - "No SMBIOS nor DMI entry point found, sorry."); - } - return ver_n; + "No SMBIOS nor DMI entry point found, sorry."); + } + +exit_free: + if (buf != NULL) + free(buf); + + return ver_n; + } int dmidecode_get_xml(options *opt, xmlNode* dmixml_n) @@ -195,6 +283,7 @@ int dmidecode_get_xml(options *opt, xmlNode* dmixml_n) size_t fp; int efi; u8 *buf = NULL; + size_t size; const char *f = opt->dumpfile ? opt->dumpfile : opt->devmem; if(access(f, R_OK) < 0) { @@ -205,53 +294,119 @@ int dmidecode_get_xml(options *opt, xmlNode* dmixml_n) /* Read from dump if so instructed */ if(opt->dumpfile != NULL) { - // printf("Reading SMBIOS/DMI data from file %s.\n", dumpfile); - if((buf = mem_chunk(opt->logdata, 0, 0x20, opt->dumpfile)) != NULL) { - if(memcmp(buf, "_SM_", 4) == 0) { - if(smbios_decode(opt->logdata, opt->type, buf, opt->dumpfile, dmixml_n)) - found++; - } else if(memcmp(buf, "_DMI_", 5) == 0) { - if(legacy_decode(opt->logdata, opt->type, buf, opt->dumpfile, dmixml_n)) - found++; + if((buf = mem_chunk(opt->logdata, 0, 0x20, opt->dumpfile)) == NULL) { + ret = 1; + goto exit_free; + } + if(memcmp(buf, "_SM3_", 5) == 0){ + if(smbios3_decode(opt->logdata, opt->type, buf,opt->dumpfile, 0, dmixml_n)) + found++; + } else if (memcmp(buf, "_SM_", 4) == 0){ + if(smbios_decode(opt->logdata, opt->type, buf, opt->dumpfile, 0, dmixml_n)) + found++; + } else if (memcmp(buf, "_DMI_", 5) == 0){ + if(legacy_decode(opt->logdata, opt->type, buf, opt->dumpfile, 0, dmixml_n)) + found++; + } + goto done; + } + + /* + * First try reading from sysfs tables. The entry point file could + * contain one of several types of entry points, so read enough for + * the largest one, then determine what type it contains. + */ + size = 0x20; + if ( (buf = read_file(opt->logdata, 0, &size, SYS_ENTRY_FILE)) != NULL){ + if ( size >= 24 && memcmp(buf, "_SM3_", 5) == 0) { + if (smbios3_decode(opt->logdata, opt->type, buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET, dmixml_n)) + found++; + } else if (size >= 31 && memcmp(buf, "_SM_", 4) == 0){ + if (smbios_decode(opt->logdata, opt->type, buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET, dmixml_n)) + found++; + } else if (size >= 15 && memcmp(buf, "_DMI_", 5) == 0){ + if (legacy_decode(opt->logdata, opt->type, buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET, dmixml_n)) + found++; + } + if (found) + goto done; + } else { + ret = 1; + goto done; + } + + /* Next try EFI (ia64, Intel-based Mac) */ + efi = address_from_efi(opt->logdata, &fp); + switch(efi){ + case EFI_NOT_FOUND: + goto memory_scan; + case EFI_NO_SMBIOS: + ret = 1; + goto exit_free; + } + + if(buf = mem_chunk(opt->logdata, fp, 0x20, opt->devmem) == NULL ){ + ret = 1; + goto exit_free; + } + + if (memcmp(buf, "_SM3_", 5) == 0){ + if (smbios3_decode(opt->logdata, opt->type, buf + fp, opt->devmem, 0, dmixml_n)) + found++; + } else if (memcmp(buf, "_SM_", 4) == 0){ + if(smbios_decode(opt->logdata, opt->type, buf + fp, opt->devmem, 0, dmixml_n)) + found++; + } + + goto done; + +memory_scan: +#if defined __i386__ || defined __x86_64__ + if((buf = mem_chunk(opt->logdata, 0xF0000, 0x10000, opt->devmem)) == NULL) + { + ret = 1; + goto exit_free; + } + + /* Look for a 64-bit entry point first */ + for (fp = 0; fp <= 0xFFE0; fp += 16){ + if (memcmp(buf + fp, "_SM3_", 5) == 0) + { + if(smbios3_decode(opt->logdata, opt->type, + buf + fp, opt->devmem, 0, dmixml_n)){ + found++; + goto done; } - } else { - ret = 1; } - } else { /* Read from /dev/mem */ - /* First try EFI (ia64, Intel-based Mac) */ - efi = address_from_efi(opt->logdata, &fp); - if(efi == EFI_NOT_FOUND) { - /* Fallback to memory scan (x86, x86_64) */ - if((buf = mem_chunk(opt->logdata, 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->logdata, opt->type, - buf + fp, opt->devmem, dmixml_n)) { - found++; - fp += 16; - } - } else if(memcmp(buf + fp, "_DMI_", 5) == 0) { - if(legacy_decode(opt->logdata, 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(opt->logdata, fp, 0x20, opt->devmem)) == NULL) - ret = 1; - else if(smbios_decode(opt->logdata, opt->type, buf, opt->devmem, dmixml_n)) + } + + /* If none found, look for a 32-bit entry point */ + for(fp = 0; fp <= 0xFFF0; fp += 16) { + if(memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0) { + if(smbios_decode(opt->logdata, opt->type, + buf + fp, opt->devmem, 0, dmixml_n)) { + found++; + goto done; + } + } else if(memcmp(buf + fp, "_DMI_", 5) == 0) { + if(legacy_decode(opt->logdata, opt->type, + buf + fp, opt->devmem, 0, dmixml_n)) found++; - // TODO: dmixml_AddAttribute(dmixml_n, "efi_address", "0x%08x", efiAddress); + goto done; + } } +#endif + +done: + if( !found ) { + log_append(opt->logdata, LOGFL_NODUPS, LOG_WARNING, + "No SMBIOS nor DMI entry point found, sorry."); } - if(ret == 0) { + +exit_free: + if(buf != NULL) free(buf); - } - //muntrace(); + return ret; } @@ -342,14 +497,21 @@ xmlNode *__dmidecode_xml_getsection(options *opt, const char *section) { static PyObject *dmidecode_get_group(options *opt, const char *section) { + int efi; + size_t fp; PyObject *pydata = NULL; xmlNode *dmixml_n = NULL; ptzMAP *mapping = NULL; /* Set default option values */ if( opt->devmem == NULL ) { - opt->devmem = DEFAULT_MEM_DEV; - } + efi = address_from_efi(opt->logdata, &fp); + if(efi == EFI_NOT_FOUND){ + opt->devmem = DEFAULT_MEM_DEV; + } else { + opt->devmem = SYS_TABLE_FILE; + } + } opt->flags = 0; // Decode the dmidata into an XML node @@ -380,11 +542,18 @@ static PyObject *dmidecode_get_group(options *opt, const char *section) xmlNode *__dmidecode_xml_gettypeid(options *opt, int typeid) { + int efi; + size_t fp; xmlNode *dmixml_n = NULL; /* Set default option values */ if( opt->devmem == NULL ) { - opt->devmem = DEFAULT_MEM_DEV; + efi = address_from_efi(opt->logdata, &fp); + if(efi == EFI_NOT_FOUND){ + opt->devmem = DEFAULT_MEM_DEV; + } else { + opt->devmem = SYS_TABLE_FILE; + } } opt->flags = 0; @@ -598,7 +767,7 @@ static PyObject *dmidecode_dump(PyObject * self, PyObject * null) 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) ) { + if( dump(SYS_TABLE_FILE, f) ) { Py_RETURN_TRUE; } } diff --git a/src/dmidecodemodule.h b/src/dmidecodemodule.h index 3600ba9..044317e 100644 --- a/src/dmidecodemodule.h +++ b/src/dmidecodemodule.h @@ -68,8 +68,10 @@ xmlNode *dmidecode_get_version(options *); extern void dmi_dump(xmlNode *node, struct dmi_header *h); extern int address_from_efi(Log_t *logp, size_t * address); extern void to_dmi_header(struct dmi_header *h, u8 * data); -extern int smbios_decode(Log_t *logp, int type, u8 *buf, const char *devmem, xmlNode *node); -extern int legacy_decode(Log_t *logp, int type, u8 *buf, const char *devmem, xmlNode *node); +extern int smbios3_decode(Log_t *logp, int type, u8 *buf, const char *devmem, u32 flags, xmlNode *node); +extern int smbios_decode(Log_t *logp, int type, u8 *buf, const char *devmem, u32 flags, xmlNode *node); +extern int legacy_decode(Log_t *logp, int type, u8 *buf, const char *devmem, u32 flags, xmlNode *node); +extern xmlNode *smbios3_decode_get_version(u8 * buf, const char *devmem); 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(Log_t *logp, size_t base, size_t len, const char *devmem); diff --git a/src/dmidump.c b/src/dmidump.c index fc67481..0d052fc 100644 --- a/src/dmidump.c +++ b/src/dmidump.c @@ -51,144 +51,214 @@ static void overwrite_dmi_address(u8 * buf) buf[0x0B] = 0; } +/* Same thing for SMBIOS3 entry points */ +static void overwrite_smbios3_address(u8 *buf) +{ + buf[0x05] += buf[0x10] + buf[0x11] + buf[0x12] + buf[0x13] + + buf[0x14] + buf[0x15] + buf[0x16] + buf[0x17] - 32; + buf[0x10] = 32; + buf[0x11] = 0; + buf[0x12] = 0; + buf[0x13] = 0; + buf[0x14] = 0; + buf[0x15] = 0; + buf[0x16] = 0; + buf[0x17] = 0; +} -int write_dump(size_t base, size_t len, const void *data, const char *dumpfile, int add) +void dmi_table_dump(const u8 *buf, u32 len, const char *dumpfile) { - FILE *f; + write_dump(32, len, buf, dumpfile, 0); +} - f = fopen(dumpfile, add ? "r+b" : "wb"); - if(!f) { - fprintf(stderr, "%s: ", dumpfile); - perror("fopen"); - return -1; - } +void dmi_table(off_t base, u32 len, u16 num, u32 ver, const char *devmem, + u32 flags, const char *dumpfile) +{ + u8 *buf; + size_t size = len; - if(fseek(f, base, SEEK_SET) != 0) { - fprintf(stderr, "%s: ", dumpfile); - perror("fseek"); - goto err_close; - } + buf = read_file(NULL, flags & FLAG_NO_FILE_OFFSET ? 0 : base, + &size, devmem); + len = size; - if(fwrite(data, len, 1, f) != 1) { - fprintf(stderr, "%s: ", dumpfile); - perror("fwrite"); - goto err_close; + if (buf == NULL) + { + printf("read failed\n"); } + dmi_table_dump(buf, len, dumpfile); + free(buf); +} - if(fclose(f)) { - fprintf(stderr, "%s: ", dumpfile); - perror("fclose"); - return -1; - } +static int smbios3_decode(u8 *buf, const char *devmem, u32 flags, const char *dumpfile) +{ + u32 ver; + u64 offset; + offset = QWORD(buf + 0x10); + ver = (buf[0x07] << 16) + (buf[0x08] << 8) + buf[0x09]; - return 0; + dmi_table(((off_t)offset.h << 32) | offset.l,DWORD(buf + 0x0C), 0, ver, devmem, flags | FLAG_STOP_AT_EOT, dumpfile); - err_close: - fclose(f); - return -1; -} + if (!checksum(buf, buf[0x05])) + return 0; + u8 crafted[32]; + memcpy(crafted, buf, 32); + overwrite_smbios3_address(crafted); + //overwrite_dmi_address(crafted); + //printf("Writing %d bytes to %s.",crafted[0x06], dumpfile); + write_dump(0, crafted[0x06], crafted, dumpfile, 1); + return 1; +} -int dumpling(u8 * buf, const char *dumpfile, u8 mode) +static int smbios_decode(u8 *buf, const char *devmem, u32 flags, const char *dumpfile) { - 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); - } + u16 ver; + if (!checksum(buf, buf[0x05]) + || memcmp(buf + 0x10, "_DMI_", 5) != 0 + || !checksum(buf + 0x10, 0x0F)) + return 0; - u8 *buff; + ver = (buf[0x06] << 8) + buf[0x07]; + switch (ver) + { + case 0x021F: + case 0x0221: + ver = 0x0203; + break; + case 0x0233: + ver = 0x0206; + break; + } - if((buff = mem_chunk(NULL, 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]; + dmi_table(DWORD(buf + 0x18), WORD(buf + 0x16), WORD(buf + 0x1C), + ver << 8, devmem, flags, dumpfile); - 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"); - } + u8 crafted[32]; + memcpy(crafted, buf, 32); + overwrite_dmi_address(crafted + 0x10); + write_dump(0, crafted[0x05], crafted, dumpfile, 1); - //. TODO: Cleanup return 1; } +static int legacy_decode(u8 *buf, const char *devmem, u32 flags, const char *dumpfile) +{ + u8 crafted[16]; + + //dmi_table(); + dmi_table(DWORD(buf + 0x08), WORD(buf + 0x06), WORD(buf + 0x0C), + ((buf[0x0E] & 0xF0) << 12) + ((buf[0x0E] & 0x0F) << 8), + devmem, flags, dumpfile); + + memcpy(crafted, buf, 16); + overwrite_smbios3_address(crafted); + write_dump(0, 0x0F, crafted, dumpfile, 1); +} int dump(const char *memdev, const char *dumpfile) { - /* On success, return found, otherwise return -1 */ + /* On success, return found, otherwise return 0 */ int ret = 0; int found = 0; size_t fp; int efi; u8 *buf; + size_t size; + + /* + * First try reading from sysfs tables. The entry point file could + * contain one of several types of entry points, so read enough for + * the largest one, then determine what type it contains. + */ + size = 0x20; + if ( (buf = read_file(NULL, 0, &size, SYS_ENTRY_FILE)) != NULL){ + if (size >= 24 && memcmp(buf, "_SM3_", 5) == 0){ + if (smbios3_decode(buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET, dumpfile)) + found++; + } else if (size >= 31 && memcmp(buf, "_SM_", 4) == 0) { + if (smbios_decode(buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET, dumpfile)) + found++; + } else if (size >= 15 && memcmp(buf, "_DMI_", 5) == 0){ + if (legacy_decode(buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET, dumpfile)) + found++; + } + if (found){ + ret = 1; + goto exit_free; + } + } /* First try EFI (ia64, Intel-based Mac) */ efi = address_from_efi(NULL, &fp); - if(efi == EFI_NOT_FOUND) { - /* Fallback to memory scan (x86, x86_64) */ - if((buf = mem_chunk(NULL, 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(NULL, fp, 0x20, memdev)) == NULL) - ret = -1; - else if(dumpling(buf, dumpfile, NON_LEGACY)) + switch(efi) + { + case EFI_NOT_FOUND: + goto memory_scan; + case EFI_NO_SMBIOS: + ret = 1; + goto exit_free; + } + + if ((buf = mem_chunk(NULL, fp, 0x20, memdev )) == NULL){ + ret = 1; + goto exit_free; + } + + if (memcmp(buf, "_SM3_", 5) == 0){ + if(smbios3_decode(buf, memdev, 0, dumpfile)) + found++; + } else if (memcmp(buf, "_SM_", 4) == 0){ + if(smbios_decode(buf, memdev, 0, dumpfile)) found++; } + goto done; - if(ret == 0) { - free(buf); - if(!found) { - ret = -1; +memory_scan: +#if defined __i386__ || defined __x86_64__ + /* Fallback to memory scan (x86, x86_64) */ + if((buf = mem_chunk(NULL, 0xF0000, 0x10000, memdev)) == NULL) { + ret = 1; + goto exit_free; + } + + /* Look for a 64-bit entry point first */ + for(fp = 0; fp <= 0xFFF0; fp += 16){ + if(memcmp(buf + fp, "_SM3_", 5) == 0 && fp <= 0xFFE0){ + if(smbios3_decode(buf + fp, memdev, 0, dumpfile)){ + found++; + goto done; + } + } + } + + /* If none found, look for a 32-bit entry point */ + for(fp = 0; fp <= 0xFFF0; fp += 16) { + if(memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0) { + if(smbios_decode(buf + fp, memdev, 0, dumpfile)){ + found++; + goto done; + } + } else if (memcmp(buf+fp, "_DMI_", 5) == 0){ + if(legacy_decode(buf+fp, memdev, 0, dumpfile)){ + found++; + goto done; + } } } +#endif + +done: + if(!found){ + printf("No SMBIOS nor DMI entry point found, sorry.\n"); + } + free(buf); + +exit_free: + if (!found) + free(buf); - return ret == 0 ? found : ret; + return ret; } diff --git a/src/dmidump.h b/src/dmidump.h index 3c12248..a025829 100644 --- a/src/dmidump.h +++ b/src/dmidump.h @@ -32,6 +32,13 @@ #define NON_LEGACY 0 #define LEGACY 1 +#define FLAG_NO_FILE_OFFSET (1 << 0) +#define FLAG_STOP_AT_EOT (1 << 1) + +#define SYS_FIRMWARE_DIR "/sys/firmware/dmi/tables" +#define SYS_ENTRY_FILE SYS_FIRMWARE_DIR "/smbios_entry_point" +#define SYS_TABLE_FILE SYS_FIRMWARE_DIR "/DMI" + int dump(const char *memdev, const char *dumpfile); #endif diff --git a/src/util.c b/src/util.c index da97767..4f233ff 100644 --- a/src/util.c +++ b/src/util.c @@ -50,7 +50,6 @@ #include "util.h" #include "dmilog.h" -#ifndef USE_MMAP static int myread(Log_t *logp, int fd, u8 * buf, size_t count, const char *prefix) { ssize_t r = 1; @@ -76,7 +75,6 @@ static int myread(Log_t *logp, int fd, u8 * buf, size_t count, const char *prefi return 0; } -#endif int checksum(const u8 * buf, size_t len) { @@ -88,6 +86,73 @@ int checksum(const u8 * buf, size_t len) return (sum == 0); } +/* + * Reads all of file from given offset, up to max_len bytes. + * A buffer of at most max_len bytes is allocated by this function, and + * needs to be freed by the caller. + * This provides a similar usage model to mem_chunk() + * + * Returns a pointer to the allocated buffer, or NULL on error, and + * sets max_len to the length actually read. + */ +void *read_file(Log_t *logp, off_t base, size_t *max_len, const char *filename) +{ + struct stat statbuf; + int fd; + u8 *p; + /* + * Don't print error message on missing file, as we will try to read + * files that may or may not be present. + */ + if ((fd = open(filename, O_RDONLY)) == -1) + { + if (errno != ENOENT) + perror(filename); + return NULL; + } + + /* + * Check file size, don't allocate more than can be read. + */ + if (fstat(fd, &statbuf) == 0) + { + if (base >= statbuf.st_size) + { + fprintf(stderr, "%s: Can't read data beyond EOF\n", + filename); + p = NULL; + goto out; + } + if (*max_len > (size_t)statbuf.st_size - base) + *max_len = statbuf.st_size - base; + } + + if ((p = malloc(*max_len)) == NULL) + { + perror("malloc"); + goto out; + } + + if (lseek(fd, base, SEEK_SET) == -1) + { + fprintf(stderr, "%s: ", filename); + perror("lseek"); + goto err_free; + } + if (myread(logp, fd, p, *max_len, filename) == 0) + goto out; + +err_free: + free(p); + p = NULL; + +out: + if (close(fd) == -1) + perror(filename); + + return p; +} + /* Static global variables which should only * be used by the sigill_handler() */ @@ -105,6 +170,18 @@ void sigill_handler(int ignore_this) { } } +static void safe_memcpy(void *dest, const void *src, size_t n) +{ +#ifdef USE_SLOW_MEMCPY + size_t i; + + for (i = 0; i < n; i++) + *((u8 *)dest + i) = *((const u8 *)src + i); +#else + memcpy(dest, src, n); +#endif +} + /* * Copy a physical memory chunk into a memory buffer. * This function allocates memory. @@ -115,7 +192,8 @@ void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem) int fd = -1; #ifdef USE_MMAP - size_t mmoffset; + struct stat statbuf; + size_t mmoffset; void *mmp; #endif sigill_logobj = logp; @@ -134,6 +212,23 @@ void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem) goto exit; } #ifdef USE_MMAP + if (sigill_error || fstat(fd, &statbuf) == -1 ) + { + log_append(logp, LOGFL_NORMAL, LOG_WARNING,"fstat: %s", strerror(errno)); + goto err_free; + } + + /* + * mmap() will fail with SIGBUS if trying to map beyond the end of + * the file. + */ + if (sigill_error || S_ISREG(statbuf.st_mode) && base + (off_t)len > statbuf.st_size ) + { + log_append(logp, LOGFL_NORMAL, LOG_WARNING, + "mmap: Can't map beyond end of file %s: %s", + devmem, strerror(errno)); + goto err_free; + } #ifdef _SC_PAGESIZE mmoffset = base % sysconf(_SC_PAGESIZE); #else @@ -147,9 +242,7 @@ void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem) mmp = mmap(0, mmoffset + len, PROT_READ, MAP_SHARED, fd, base - mmoffset); if(sigill_error || (mmp == MAP_FAILED)) { log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s (mmap): %s", devmem, strerror(errno)); - free(p); - p = NULL; - goto exit; + goto try_read; } memcpy(p, (u8 *) mmp + mmoffset, len); @@ -167,28 +260,34 @@ void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem) p = NULL; goto exit; } -#else /* USE_MMAP */ - if(sigill_error || (lseek(fd, base, SEEK_SET) == -1)) { + goto exit; + +try_read: +#endif /* USE_MMAP */ + if (lseek(fd, base, SEEK_SET) == -1 ) + { log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s (lseek): %s", devmem, strerror(errno)); - free(p); - p = NULL; - goto exit; + goto err_free; } - if(sigill_error || (myread(logp, fd, p, len, devmem) == -1)) { + if(sigill_error || (myread(logp, fd, p, len, devmem) == 0)) { free(p); p = NULL; goto exit; } -#endif /* USE_MMAP */ - exit: +err_free: + free(p); + p = NULL; + +exit: if (fd >= 0) { if(close(fd) == -1) perror(devmem); } signal(SIGILL, SIG_DFL); sigill_logobj = NULL; + return p; } @@ -207,3 +306,42 @@ u64 u64_range(u64 start, u64 end) return res; } + +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; +} diff --git a/src/util.h b/src/util.h index aa0487a..3c803c0 100644 --- a/src/util.h +++ b/src/util.h @@ -27,6 +27,7 @@ #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) int checksum(const u8 * buf, size_t len); +void *read_file( Log_t *logp, off_t base, size_t *len, const char *filename); void *mem_chunk(Log_t *logp, 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); u64 u64_range(u64 start, u64 end); From a37fc124b558a9fda5e81faca12a35ab076aa006 Mon Sep 17 00:00:00 2001 From: Zhongze Hu Date: Mon, 5 Sep 2022 02:14:39 +0800 Subject: [PATCH 121/146] Fix bugs: 1. Fix smbios3_decode decoding sysfs table dump error. 2. Fix check smbios version error warning message. --- src/dmidecode.c | 12 +++++------- src/dmidump.c | 6 +++--- src/efi.c | 5 ++++- src/util.c | 5 +++-- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index 19958d3..cd9e420 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -92,7 +92,7 @@ #include "dmihelper.h" -#define SUPPORTED_SMBIOS_VER 0x0207 +#define SUPPORTED_SMBIOS_VER 0x030300 /******************************************************************************* ** Type-independant Stuff @@ -5197,7 +5197,7 @@ dmi_codes_major *find_dmiMajor(const struct dmi_header *h) return NULL; } -static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver, const char *devmem, u32 flags, xmlNode *xmlnode) +static void dmi_table(Log_t *logp, int type, u32 base, u32 len, u16 num, u32 ver, const char *devmem, u32 flags, xmlNode *xmlnode) { static u8 version_added = 0; u8 *buf; @@ -5241,7 +5241,7 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver } if (ver > SUPPORTED_SMBIOS_VER){ - log_append(logp, LOGFL_NODUPS, LOG_WARNING, "# SMBIOS implementations newer than version %u.%u are not\n", "# fully supported by this version of dmidecode.\n", SUPPORTED_SMBIOS_VER >> 8, SUPPORTED_SMBIOS_VER & 0xFF); + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "# SMBIOS implementations newer than version %u.%u.%u are not\n fully supported by this version of dmidecode.\n", SUPPORTED_SMBIOS_VER >> 16, (SUPPORTED_SMBIOS_VER >> 8) & 0xFF, SUPPORTED_SMBIOS_VER & 0xFF); } if( version_added == 0 ) { @@ -5250,7 +5250,7 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver } data = buf; - while(i < num && data + 4 <= buf + len) { /* 4 is the length of an SMBIOS structure header */ + while((i < num||!num) && data + 4 <= buf + len) { /* 4 is the length of an SMBIOS structure header */ u8 *next; struct dmi_header h; @@ -5364,8 +5364,7 @@ xmlNode *smbios3_decode_get_version(u8 * buf, const char *devmem) dmixml_AddAttribute(data_n, "type", "SMBIOS"); if(check == 1) { - u16 ver = (buf[0x07] << 16) + (buf[0x08] << 8) + buf[0x09]; - + u32 ver = (buf[0x07] << 16) + (buf[0x08] << 8) + buf[0x09]; dmixml_AddTextContent(data_n, "SMBIOS %i.%i.%i present", buf[0x07], buf[0x08], buf[0x09]); dmixml_AddAttribute(data_n, "version", "%i.%i.%i", buf[0x07], buf[0x08],buf[0x09]); } else if(check == 0) { @@ -5396,7 +5395,6 @@ int smbios3_decode(Log_t *logp, int type, u8 *buf, const char *devmem, u32 flags { return 0; } - dmi_table(logp, type, ((off_t)offset.h << 32) | offset.l, DWORD(buf+0x0C), 0, ver, devmem, flags | FLAG_STOP_AT_EOT, xmlnode); } diff --git a/src/dmidump.c b/src/dmidump.c index 0d052fc..da0d676 100644 --- a/src/dmidump.c +++ b/src/dmidump.c @@ -96,11 +96,11 @@ static int smbios3_decode(u8 *buf, const char *devmem, u32 flags, const char *du offset = QWORD(buf + 0x10); ver = (buf[0x07] << 16) + (buf[0x08] << 8) + buf[0x09]; - dmi_table(((off_t)offset.h << 32) | offset.l,DWORD(buf + 0x0C), 0, ver, devmem, flags | FLAG_STOP_AT_EOT, dumpfile); - - if (!checksum(buf, buf[0x05])) + if (!checksum(buf, buf[0x06])) return 0; + dmi_table(((off_t)offset.h << 32) | offset.l,DWORD(buf + 0x0C), 0, ver, devmem, flags | FLAG_STOP_AT_EOT, dumpfile); + u8 crafted[32]; memcpy(crafted, buf, 32); overwrite_smbios3_address(crafted); diff --git a/src/efi.c b/src/efi.c index ae8d0db..362e2f9 100644 --- a/src/efi.c +++ b/src/efi.c @@ -49,6 +49,7 @@ int address_from_efi(Log_t *logp, size_t * address) FILE *efi_systab; const char *filename = NULL; char linebuf[64]; + const char *eptype; int ret; *address = 0; /* Prevent compiler warning */ @@ -67,8 +68,10 @@ int address_from_efi(Log_t *logp, size_t * address) char *addrp = strchr(linebuf, '='); *(addrp++) = '\0'; - if(strcmp(linebuf, "SMBIOS") == 0) { + if(strcmp(linebuf, "SMBIOS3") == 0 + || strcmp(linebuf, "SMBIOS") == 0) { *address = strtoul(addrp, NULL, 0); + eptype = linebuf; ret = 0; break; } diff --git a/src/util.c b/src/util.c index 4f233ff..465376e 100644 --- a/src/util.c +++ b/src/util.c @@ -239,13 +239,14 @@ void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem) * 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); + mmp = mmap(NULL, mmoffset + len, PROT_READ, MAP_SHARED, fd, base - mmoffset); if(sigill_error || (mmp == MAP_FAILED)) { log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s (mmap): %s", devmem, strerror(errno)); goto try_read; } - memcpy(p, (u8 *) mmp + mmoffset, len); + safe_memcpy(p, (u8 *) mmp + mmoffset, len); + if (sigill_error) { log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Failed to do memcpy() due to SIGILL signal"); From c97d1ca021ddc160d70525d0840b1731f50ac4ca Mon Sep 17 00:00:00 2001 From: Zhongze Hu Date: Sat, 3 Sep 2022 20:03:27 +0800 Subject: [PATCH 122/146] Fix the failure of opening "/dev/mem": Permission denied The "/dev/mem" may be disabled(e.g kernel enables lockdown), which makes python-dmidecode has no permission to access the "/dev/mem". As a result, python-dmidecode will report an error as below: ** COLLECTED WARNINGS ** Failed to open memory buffer (/dev/mem): Permission denied No SMBIOS nor DMI entry point found, sorry. ** END OF WARNINGS ** Let's try to read the sysfs tables if the "/dev/mem" is unavailable. Resolves: https://github.com/nima/python-dmidecode/issues/15 Signed-off-by: Zhongze Hu --- src/dmidecode.c | 117 ++++++++++---- src/dmidecode.h | 13 +- src/dmidecodemodule.c | 367 ++++++++++++++++++++++++++++++------------ src/dmidecodemodule.h | 6 +- src/dmidump.c | 272 +++++++++++++++++++------------ src/dmidump.h | 7 + src/util.c | 166 +++++++++++++++++-- src/util.h | 1 + 8 files changed, 703 insertions(+), 246 deletions(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index d30a5d3..19958d3 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -5197,7 +5197,7 @@ dmi_codes_major *find_dmiMajor(const struct dmi_header *h) return NULL; } -static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver, const char *devmem, xmlNode *xmlnode) +static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver, const char *devmem, u32 flags, xmlNode *xmlnode) { static u8 version_added = 0; u8 *buf; @@ -5221,35 +5221,40 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver info_n = NULL; } - if((buf = mem_chunk(logp, base, len, devmem)) == NULL) { - log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Table is unreachable, sorry." -#ifndef USE_MMAP - "Try compiling dmidecode with -DUSE_MMAP." -#endif - ); - return; - } + if(flags & FLAG_NO_FILE_OFFSET){ + /* + * When reading from sysfs or from a dump file, the file may be + * shorter than announced. For SMBIOS v3 this is expcted, as we + * only know the maximum table size, not the actual table size. + * For older implementations (and for SMBIOS v3 too), this + * would be the result of the kernel truncating the table on + * parse error. + */ + size_t size = len; + buf = read_file(logp, flags & FLAG_NO_FILE_OFFSET ? 0 : base, &size, devmem); + if (num && size != (size_t)len){ + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Wrong DMI structures length: %i bytes announced, only %lu bytes available.\n", len, (unsigned long)size ); + } + len = size; + } else { + buf = mem_chunk(logp, base, len, devmem); + } + + if (ver > SUPPORTED_SMBIOS_VER){ + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "# SMBIOS implementations newer than version %u.%u are not\n", "# fully supported by this version of dmidecode.\n", SUPPORTED_SMBIOS_VER >> 8, SUPPORTED_SMBIOS_VER & 0xFF); + } - if (ver > SUPPORTED_SMBIOS_VER) { - log_append(logp, LOGFL_NODUPS, LOG_WARNING, - "# SMBIOS implementations newer than version %u.%u are not\n" - "# fully supported by this version of dmidecode.\n", - SUPPORTED_SMBIOS_VER >> 8, SUPPORTED_SMBIOS_VER & 0xFF); - } - // FIXME: This is hackerish ... rather try to avoid looping dmi_table() calls too much if( version_added == 0 ) { dmixml_AddAttribute(xmlnode, "smbios_version", "%u.%u", ver >> 8, ver & 0xFF); version_added = 1; } - data = buf; - while(i < num && data + 4 <= buf + len) { /* 4 is the length of an SMBIOS structure header */ - + 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. @@ -5258,8 +5263,8 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver */ if(h.length < 4) { log_append(logp, LOGFL_NORMAL, LOG_WARNING, - "Invalid entry length (%i) for type %i. DMI table is broken! Stop.", - (unsigned int)h.length, type); + "Invalid entry length (%i) for type %i. DMI table is broken! Stop.", + (unsigned int)h.length, type); break; } @@ -5278,7 +5283,6 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver next++; } next += 2; - xmlNode *handle_n = NULL; if( h.type == type ) { if(next - buf <= len) { @@ -5309,6 +5313,7 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver dmixml_AddAttribute(handle_n, "length", "%i", (next - buf)); dmixml_AddAttribute(handle_n, "expected_length", "%i", len); + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "DMI/SMBIOS type 0x%02X is exceeding the expected buffer " "size by %i bytes. Will not decode this entry.", @@ -5344,6 +5349,60 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver free(buf); } +int _smbios3_decode_check(u8 *buf){ + int check = (!checksum(buf, buf[0x06])) ? 0 : 1; + return check; +} + +xmlNode *smbios3_decode_get_version(u8 * buf, const char *devmem) +{ + int check = _smbios3_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[0x07] << 16) + (buf[0x08] << 8) + buf[0x09]; + + dmixml_AddTextContent(data_n, "SMBIOS %i.%i.%i present", buf[0x07], buf[0x08], buf[0x09]); + dmixml_AddAttribute(data_n, "version", "%i.%i.%i", buf[0x07], buf[0x08],buf[0x09]); + } else if(check == 0) { + dmixml_AddTextContent(data_n, "No SMBIOS nor DMI entry point found"); + dmixml_AddAttribute(data_n, "unknown", "1"); + } + return data_n; +} + +int smbios3_decode(Log_t *logp, int type, u8 *buf, const char *devmem, u32 flags, xmlNode *xmlnode) +{ + u32 ver; + u64 offset; + + /* Don't let checksum run beyond the buffer */ + if (buf[0x06] > 0x20) + { + return 0; + } + + int check = _smbios3_decode_check(buf); + if (check == 1) + { + ver = (buf[0x07] << 16) + (buf[0x08] << 8) + buf[0x09]; + offset = QWORD(buf + 0x10); + + if (!(flags & FLAG_NO_FILE_OFFSET) && offset.h && sizeof(off_t) < 8) + { + return 0; + } + + dmi_table(logp, type, ((off_t)offset.h << 32) | offset.l, DWORD(buf+0x0C), 0, ver, devmem, flags | FLAG_STOP_AT_EOT, xmlnode); + } + + return check; +} + int _smbios_decode_check(u8 * buf) { int check = (!checksum(buf, buf[0x05]) || memcmp(buf + 0x10, "_DMI_", 5) != 0 || @@ -5370,7 +5429,8 @@ xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem) _M = 0; switch (ver) { case 0x021F: - _m = 31; + case 0x0221: + _m = ver & 0xFF; _M = 3; ver = 0x0203; break; @@ -5396,7 +5456,7 @@ xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem) return data_n; } -int smbios_decode(Log_t *logp, int type, u8 *buf, const char *devmem, xmlNode *xmlnode) +int smbios_decode(Log_t *logp, int type, u8 *buf, const char *devmem, u32 flags, xmlNode *xmlnode) { int check = _smbios_decode_check(buf); @@ -5405,6 +5465,7 @@ int smbios_decode(Log_t *logp, int type, u8 *buf, const char *devmem, xmlNode *x switch (ver) { case 0x021F: + case 0x0221: ver = 0x0203; break; case 0x0233: @@ -5413,7 +5474,7 @@ int smbios_decode(Log_t *logp, int type, u8 *buf, const char *devmem, xmlNode *x } // printf(">>%d @ %d, %d<<\n", DWORD(buf+0x18), WORD(buf+0x16), WORD(buf+0x1C)); dmi_table(logp, type, DWORD(buf + 0x18), WORD(buf + 0x16), WORD(buf + 0x1C), ver, devmem, - xmlnode); + flags, xmlnode); } return check; } @@ -5451,13 +5512,13 @@ xmlNode *legacy_decode_get_version(u8 * buf, const char *devmem) return data_n; } -int legacy_decode(Log_t *logp, int type, u8 *buf, const char *devmem, xmlNode *xmlnode) +int legacy_decode(Log_t *logp, int type, u8 *buf, const char *devmem, u32 flags, xmlNode *xmlnode) { int check = _legacy_decode_check(buf); if(check == 1) dmi_table(logp, type, DWORD(buf + 0x08), WORD(buf + 0x06), WORD(buf + 0x0C), - ((buf[0x0E] & 0xF0) << 4) + (buf[0x0E] & 0x0F), devmem, xmlnode); + ((buf[0x0E] & 0xF0) << 4) + (buf[0x0E] & 0x0F), devmem, flags, xmlnode); return check; } diff --git a/src/dmidecode.h b/src/dmidecode.h index 926bd5d..22d70e1 100644 --- a/src/dmidecode.h +++ b/src/dmidecode.h @@ -23,6 +23,13 @@ #include "dmihelper.h" #include "dmierror.h" +#define FLAG_NO_FILE_OFFSET (1 << 0) +#define FLAG_STOP_AT_EOT (1 << 1) + +#define SYS_FIRMWARE_DIR "/sys/firmware/dmi/tables" +#define SYS_ENTRY_FILE SYS_FIRMWARE_DIR "/smbios_entry_point" +#define SYS_TABLE_FILE SYS_FIRMWARE_DIR "/DMI" + struct dmi_header { u8 type; u8 length; @@ -34,10 +41,12 @@ 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); +xmlNode *smbios3_decode_get_version(u8 * buf, const char *devmem); xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem); xmlNode *legacy_decode_get_version(u8 * buf, const char *devmem); -int smbios_decode(Log_t *logp, int type, u8 *buf, const char *devmem, xmlNode *xmlnode); -int legacy_decode(Log_t *logp, int type, u8 *buf, const char *devmem, xmlNode *xmlnode); +int smbios3_decode(Log_t *logp, int type, u8 *buf, const char *devmem, u32 flags, xmlNode *xmlnode); +int smbios_decode(Log_t *logp, int type, u8 *buf, const char *devmem, u32 flags, xmlNode *xmlnode); +int legacy_decode(Log_t *logp, int type, u8 *buf, const char *devmem, u32 flags, xmlNode *xmlnode); const char *dmi_string(const struct dmi_header *dm, u8 s); void dmi_system_uuid(xmlNode *node, const u8 * p, u16 ver); diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 44ef7aa..d3ac7ff 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -66,7 +66,9 @@ char *PyUnicode_AsUTF8(PyObject *unicode) { static void init(options *opt) { - opt->devmem = DEFAULT_MEM_DEV; + int efi; + size_t fp; + opt->dumpfile = NULL; opt->flags = 0; opt->type = -1; @@ -75,6 +77,13 @@ static void init(options *opt) opt->python_xml_map = strdup(PYTHON_XML_MAP); opt->logdata = log_init(); + efi = address_from_efi(opt->logdata, &fp); + if(efi == EFI_NOT_FOUND){ + opt->devmem = DEFAULT_MEM_DEV; + } else { + opt->devmem = SYS_TABLE_FILE; + } + /* sanity check */ if(sizeof(u8) != 1 || sizeof(u16) != 2 || sizeof(u32) != 4 || '\0' != 0) { log_append(opt->logdata, LOGFL_NORMAL, LOG_WARNING, @@ -116,70 +125,149 @@ xmlNode *dmidecode_get_version(options *opt) int efi; u8 *buf = NULL; xmlNode *ver_n = NULL; + size_t size; - /* Set default option values */ + /* + * First, if devmem is available, set default as DEFAULT_MEM_DEV + * Set default option values + */ if( opt->devmem == NULL ) { - opt->devmem = DEFAULT_MEM_DEV; + efi = address_from_efi(opt->logdata, &fp); + if(efi == EFI_NOT_FOUND){ + opt->devmem = DEFAULT_MEM_DEV; + } else { + opt->devmem = SYS_TABLE_FILE; + } } /* Read from dump if so instructed */ if(opt->dumpfile != NULL) { //. printf("Reading SMBIOS/DMI data from file %s.\n", dumpfile); if((buf = mem_chunk(opt->logdata, 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(opt->logdata, &fp); - if(efi == EFI_NOT_FOUND) { - /* Fallback to memory scan (x86, x86_64) */ - if((buf = mem_chunk(opt->logdata, 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(opt->logdata, 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); - } + ver_n = NULL; + goto exit_free; + } + if(memcmp(buf, "_SM3_", 5) == 0){ + ver_n = smbios3_decode_get_version(buf, opt->dumpfile); + if ( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) + found++; + } else 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++; } } - if( buf != NULL ) { - free(buf); - } - if( !found ) { + + /* + * First try reading from sysfs tables. The entry point file could + * contain one of several types of entry points, so read enough for + * the largest one, then determine what type it contains. + */ + size = 0x20; + if ( (buf = read_file(opt->logdata, 0, &size, SYS_ENTRY_FILE)) != NULL ){ + if(size >= 24 && memcmp(buf, "_SM3_", 5) == 0){ + ver_n = smbios3_decode_get_version(buf, opt->devmem); + if (dmixml_GetAttrValue(ver_n, "unknown") == NULL) + found++; + } else if (size >= 31 && memcmp(buf, "_SM_", 4) == 0 ){ + ver_n = smbios_decode_get_version(buf, opt->devmem); + if (dmixml_GetAttrValue(ver_n, "unknown") == NULL) + found++; + } else if (size >= 15 && memcmp(buf, "_DMI_", 5) == 0){ + ver_n = legacy_decode_get_version (buf, opt->devmem); + if (dmixml_GetAttrValue(ver_n, "unknown") == NULL) + found++; + } + + if(found) + goto done; + } else { + ver_n = NULL; + goto exit_free; + } + + /* Read from /dev/mem */ + /* Next try EFI (ia64, Intel-based Mac) */ + efi = address_from_efi(opt->logdata, &fp); + switch(efi){ + case EFI_NOT_FOUND: + goto memory_scan; + case EFI_NO_SMBIOS: + ver_n = NULL; + goto exit_free; + } + + if(buf = mem_chunk(opt->logdata, fp, 0x20, opt->devmem) == NULL){ + ver_n = NULL; + goto exit_free; + } + + if(memcmp(buf, "_SM3_", 5) == 0){ + ver_n = smbios3_decode_get_version(buf, opt->devmem); + if(dmixml_GetAttrValue(ver_n, "unknown") == NULL) + found++; + } else if (memcmp(buf, "_SM_", 4) == 0 ) { + ver_n = smbios_decode_get_version(buf, opt->devmem); + if(dmixml_GetAttrValue(ver_n, "unknown") == NULL) + found++; + } + + goto done; + +memory_scan: +#if defined __i386__ || defined __x86_64__ + /* Fallback to memory scan (x86, x86_64) */ + if((buf = mem_chunk(opt->logdata, 0xF0000, 0x10000, opt->devmem)) == NULL) { + ver_n = NULL; + goto exit_free; + } + + /* Look for a 64-bit entry point first */ + for (fp = 0; fp <= 0xFFE0; fp+= 16){ + if(memcmp(buf+fp, "_SM3_", 5) == 0){ + ver_n = smbios3_decode_get_version(buf+fp, opt->devmem); + if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) { + found++; + goto done; + } + } + } + + /* If none found, look for a 32-bit entry point */ + 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++; + goto done; + } + 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++; + goto done; + } + } + } +#endif + +done: + if(!found){ log_append(opt->logdata, LOGFL_NODUPS, LOG_WARNING, - "No SMBIOS nor DMI entry point found, sorry."); - } - return ver_n; + "No SMBIOS nor DMI entry point found, sorry."); + } + +exit_free: + if (buf != NULL) + free(buf); + + return ver_n; + } int dmidecode_get_xml(options *opt, xmlNode* dmixml_n) @@ -195,6 +283,7 @@ int dmidecode_get_xml(options *opt, xmlNode* dmixml_n) size_t fp; int efi; u8 *buf = NULL; + size_t size; const char *f = opt->dumpfile ? opt->dumpfile : opt->devmem; if(access(f, R_OK) < 0) { @@ -205,53 +294,119 @@ int dmidecode_get_xml(options *opt, xmlNode* dmixml_n) /* Read from dump if so instructed */ if(opt->dumpfile != NULL) { - // printf("Reading SMBIOS/DMI data from file %s.\n", dumpfile); - if((buf = mem_chunk(opt->logdata, 0, 0x20, opt->dumpfile)) != NULL) { - if(memcmp(buf, "_SM_", 4) == 0) { - if(smbios_decode(opt->logdata, opt->type, buf, opt->dumpfile, dmixml_n)) - found++; - } else if(memcmp(buf, "_DMI_", 5) == 0) { - if(legacy_decode(opt->logdata, opt->type, buf, opt->dumpfile, dmixml_n)) - found++; + if((buf = mem_chunk(opt->logdata, 0, 0x20, opt->dumpfile)) == NULL) { + ret = 1; + goto exit_free; + } + if(memcmp(buf, "_SM3_", 5) == 0){ + if(smbios3_decode(opt->logdata, opt->type, buf,opt->dumpfile, 0, dmixml_n)) + found++; + } else if (memcmp(buf, "_SM_", 4) == 0){ + if(smbios_decode(opt->logdata, opt->type, buf, opt->dumpfile, 0, dmixml_n)) + found++; + } else if (memcmp(buf, "_DMI_", 5) == 0){ + if(legacy_decode(opt->logdata, opt->type, buf, opt->dumpfile, 0, dmixml_n)) + found++; + } + goto done; + } + + /* + * First try reading from sysfs tables. The entry point file could + * contain one of several types of entry points, so read enough for + * the largest one, then determine what type it contains. + */ + size = 0x20; + if ( (buf = read_file(opt->logdata, 0, &size, SYS_ENTRY_FILE)) != NULL){ + if ( size >= 24 && memcmp(buf, "_SM3_", 5) == 0) { + if (smbios3_decode(opt->logdata, opt->type, buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET, dmixml_n)) + found++; + } else if (size >= 31 && memcmp(buf, "_SM_", 4) == 0){ + if (smbios_decode(opt->logdata, opt->type, buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET, dmixml_n)) + found++; + } else if (size >= 15 && memcmp(buf, "_DMI_", 5) == 0){ + if (legacy_decode(opt->logdata, opt->type, buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET, dmixml_n)) + found++; + } + if (found) + goto done; + } else { + ret = 1; + goto done; + } + + /* Next try EFI (ia64, Intel-based Mac) */ + efi = address_from_efi(opt->logdata, &fp); + switch(efi){ + case EFI_NOT_FOUND: + goto memory_scan; + case EFI_NO_SMBIOS: + ret = 1; + goto exit_free; + } + + if(buf = mem_chunk(opt->logdata, fp, 0x20, opt->devmem) == NULL ){ + ret = 1; + goto exit_free; + } + + if (memcmp(buf, "_SM3_", 5) == 0){ + if (smbios3_decode(opt->logdata, opt->type, buf + fp, opt->devmem, 0, dmixml_n)) + found++; + } else if (memcmp(buf, "_SM_", 4) == 0){ + if(smbios_decode(opt->logdata, opt->type, buf + fp, opt->devmem, 0, dmixml_n)) + found++; + } + + goto done; + +memory_scan: +#if defined __i386__ || defined __x86_64__ + if((buf = mem_chunk(opt->logdata, 0xF0000, 0x10000, opt->devmem)) == NULL) + { + ret = 1; + goto exit_free; + } + + /* Look for a 64-bit entry point first */ + for (fp = 0; fp <= 0xFFE0; fp += 16){ + if (memcmp(buf + fp, "_SM3_", 5) == 0) + { + if(smbios3_decode(opt->logdata, opt->type, + buf + fp, opt->devmem, 0, dmixml_n)){ + found++; + goto done; } - } else { - ret = 1; } - } else { /* Read from /dev/mem */ - /* First try EFI (ia64, Intel-based Mac) */ - efi = address_from_efi(opt->logdata, &fp); - if(efi == EFI_NOT_FOUND) { - /* Fallback to memory scan (x86, x86_64) */ - if((buf = mem_chunk(opt->logdata, 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->logdata, opt->type, - buf + fp, opt->devmem, dmixml_n)) { - found++; - fp += 16; - } - } else if(memcmp(buf + fp, "_DMI_", 5) == 0) { - if(legacy_decode(opt->logdata, 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(opt->logdata, fp, 0x20, opt->devmem)) == NULL) - ret = 1; - else if(smbios_decode(opt->logdata, opt->type, buf, opt->devmem, dmixml_n)) + } + + /* If none found, look for a 32-bit entry point */ + for(fp = 0; fp <= 0xFFF0; fp += 16) { + if(memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0) { + if(smbios_decode(opt->logdata, opt->type, + buf + fp, opt->devmem, 0, dmixml_n)) { + found++; + goto done; + } + } else if(memcmp(buf + fp, "_DMI_", 5) == 0) { + if(legacy_decode(opt->logdata, opt->type, + buf + fp, opt->devmem, 0, dmixml_n)) found++; - // TODO: dmixml_AddAttribute(dmixml_n, "efi_address", "0x%08x", efiAddress); + goto done; + } } +#endif + +done: + if( !found ) { + log_append(opt->logdata, LOGFL_NODUPS, LOG_WARNING, + "No SMBIOS nor DMI entry point found, sorry."); } - if(ret == 0) { + +exit_free: + if(buf != NULL) free(buf); - } - //muntrace(); + return ret; } @@ -342,14 +497,21 @@ xmlNode *__dmidecode_xml_getsection(options *opt, const char *section) { static PyObject *dmidecode_get_group(options *opt, const char *section) { + int efi; + size_t fp; PyObject *pydata = NULL; xmlNode *dmixml_n = NULL; ptzMAP *mapping = NULL; /* Set default option values */ if( opt->devmem == NULL ) { - opt->devmem = DEFAULT_MEM_DEV; - } + efi = address_from_efi(opt->logdata, &fp); + if(efi == EFI_NOT_FOUND){ + opt->devmem = DEFAULT_MEM_DEV; + } else { + opt->devmem = SYS_TABLE_FILE; + } + } opt->flags = 0; // Decode the dmidata into an XML node @@ -380,11 +542,18 @@ static PyObject *dmidecode_get_group(options *opt, const char *section) xmlNode *__dmidecode_xml_gettypeid(options *opt, int typeid) { + int efi; + size_t fp; xmlNode *dmixml_n = NULL; /* Set default option values */ if( opt->devmem == NULL ) { - opt->devmem = DEFAULT_MEM_DEV; + efi = address_from_efi(opt->logdata, &fp); + if(efi == EFI_NOT_FOUND){ + opt->devmem = DEFAULT_MEM_DEV; + } else { + opt->devmem = SYS_TABLE_FILE; + } } opt->flags = 0; @@ -598,7 +767,7 @@ static PyObject *dmidecode_dump(PyObject * self, PyObject * null) 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) ) { + if( dump(SYS_TABLE_FILE, f) ) { Py_RETURN_TRUE; } } diff --git a/src/dmidecodemodule.h b/src/dmidecodemodule.h index 3600ba9..044317e 100644 --- a/src/dmidecodemodule.h +++ b/src/dmidecodemodule.h @@ -68,8 +68,10 @@ xmlNode *dmidecode_get_version(options *); extern void dmi_dump(xmlNode *node, struct dmi_header *h); extern int address_from_efi(Log_t *logp, size_t * address); extern void to_dmi_header(struct dmi_header *h, u8 * data); -extern int smbios_decode(Log_t *logp, int type, u8 *buf, const char *devmem, xmlNode *node); -extern int legacy_decode(Log_t *logp, int type, u8 *buf, const char *devmem, xmlNode *node); +extern int smbios3_decode(Log_t *logp, int type, u8 *buf, const char *devmem, u32 flags, xmlNode *node); +extern int smbios_decode(Log_t *logp, int type, u8 *buf, const char *devmem, u32 flags, xmlNode *node); +extern int legacy_decode(Log_t *logp, int type, u8 *buf, const char *devmem, u32 flags, xmlNode *node); +extern xmlNode *smbios3_decode_get_version(u8 * buf, const char *devmem); 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(Log_t *logp, size_t base, size_t len, const char *devmem); diff --git a/src/dmidump.c b/src/dmidump.c index fc67481..0d052fc 100644 --- a/src/dmidump.c +++ b/src/dmidump.c @@ -51,144 +51,214 @@ static void overwrite_dmi_address(u8 * buf) buf[0x0B] = 0; } +/* Same thing for SMBIOS3 entry points */ +static void overwrite_smbios3_address(u8 *buf) +{ + buf[0x05] += buf[0x10] + buf[0x11] + buf[0x12] + buf[0x13] + + buf[0x14] + buf[0x15] + buf[0x16] + buf[0x17] - 32; + buf[0x10] = 32; + buf[0x11] = 0; + buf[0x12] = 0; + buf[0x13] = 0; + buf[0x14] = 0; + buf[0x15] = 0; + buf[0x16] = 0; + buf[0x17] = 0; +} -int write_dump(size_t base, size_t len, const void *data, const char *dumpfile, int add) +void dmi_table_dump(const u8 *buf, u32 len, const char *dumpfile) { - FILE *f; + write_dump(32, len, buf, dumpfile, 0); +} - f = fopen(dumpfile, add ? "r+b" : "wb"); - if(!f) { - fprintf(stderr, "%s: ", dumpfile); - perror("fopen"); - return -1; - } +void dmi_table(off_t base, u32 len, u16 num, u32 ver, const char *devmem, + u32 flags, const char *dumpfile) +{ + u8 *buf; + size_t size = len; - if(fseek(f, base, SEEK_SET) != 0) { - fprintf(stderr, "%s: ", dumpfile); - perror("fseek"); - goto err_close; - } + buf = read_file(NULL, flags & FLAG_NO_FILE_OFFSET ? 0 : base, + &size, devmem); + len = size; - if(fwrite(data, len, 1, f) != 1) { - fprintf(stderr, "%s: ", dumpfile); - perror("fwrite"); - goto err_close; + if (buf == NULL) + { + printf("read failed\n"); } + dmi_table_dump(buf, len, dumpfile); + free(buf); +} - if(fclose(f)) { - fprintf(stderr, "%s: ", dumpfile); - perror("fclose"); - return -1; - } +static int smbios3_decode(u8 *buf, const char *devmem, u32 flags, const char *dumpfile) +{ + u32 ver; + u64 offset; + offset = QWORD(buf + 0x10); + ver = (buf[0x07] << 16) + (buf[0x08] << 8) + buf[0x09]; - return 0; + dmi_table(((off_t)offset.h << 32) | offset.l,DWORD(buf + 0x0C), 0, ver, devmem, flags | FLAG_STOP_AT_EOT, dumpfile); - err_close: - fclose(f); - return -1; -} + if (!checksum(buf, buf[0x05])) + return 0; + u8 crafted[32]; + memcpy(crafted, buf, 32); + overwrite_smbios3_address(crafted); + //overwrite_dmi_address(crafted); + //printf("Writing %d bytes to %s.",crafted[0x06], dumpfile); + write_dump(0, crafted[0x06], crafted, dumpfile, 1); + return 1; +} -int dumpling(u8 * buf, const char *dumpfile, u8 mode) +static int smbios_decode(u8 *buf, const char *devmem, u32 flags, const char *dumpfile) { - 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); - } + u16 ver; + if (!checksum(buf, buf[0x05]) + || memcmp(buf + 0x10, "_DMI_", 5) != 0 + || !checksum(buf + 0x10, 0x0F)) + return 0; - u8 *buff; + ver = (buf[0x06] << 8) + buf[0x07]; + switch (ver) + { + case 0x021F: + case 0x0221: + ver = 0x0203; + break; + case 0x0233: + ver = 0x0206; + break; + } - if((buff = mem_chunk(NULL, 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]; + dmi_table(DWORD(buf + 0x18), WORD(buf + 0x16), WORD(buf + 0x1C), + ver << 8, devmem, flags, dumpfile); - 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"); - } + u8 crafted[32]; + memcpy(crafted, buf, 32); + overwrite_dmi_address(crafted + 0x10); + write_dump(0, crafted[0x05], crafted, dumpfile, 1); - //. TODO: Cleanup return 1; } +static int legacy_decode(u8 *buf, const char *devmem, u32 flags, const char *dumpfile) +{ + u8 crafted[16]; + + //dmi_table(); + dmi_table(DWORD(buf + 0x08), WORD(buf + 0x06), WORD(buf + 0x0C), + ((buf[0x0E] & 0xF0) << 12) + ((buf[0x0E] & 0x0F) << 8), + devmem, flags, dumpfile); + + memcpy(crafted, buf, 16); + overwrite_smbios3_address(crafted); + write_dump(0, 0x0F, crafted, dumpfile, 1); +} int dump(const char *memdev, const char *dumpfile) { - /* On success, return found, otherwise return -1 */ + /* On success, return found, otherwise return 0 */ int ret = 0; int found = 0; size_t fp; int efi; u8 *buf; + size_t size; + + /* + * First try reading from sysfs tables. The entry point file could + * contain one of several types of entry points, so read enough for + * the largest one, then determine what type it contains. + */ + size = 0x20; + if ( (buf = read_file(NULL, 0, &size, SYS_ENTRY_FILE)) != NULL){ + if (size >= 24 && memcmp(buf, "_SM3_", 5) == 0){ + if (smbios3_decode(buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET, dumpfile)) + found++; + } else if (size >= 31 && memcmp(buf, "_SM_", 4) == 0) { + if (smbios_decode(buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET, dumpfile)) + found++; + } else if (size >= 15 && memcmp(buf, "_DMI_", 5) == 0){ + if (legacy_decode(buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET, dumpfile)) + found++; + } + if (found){ + ret = 1; + goto exit_free; + } + } /* First try EFI (ia64, Intel-based Mac) */ efi = address_from_efi(NULL, &fp); - if(efi == EFI_NOT_FOUND) { - /* Fallback to memory scan (x86, x86_64) */ - if((buf = mem_chunk(NULL, 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(NULL, fp, 0x20, memdev)) == NULL) - ret = -1; - else if(dumpling(buf, dumpfile, NON_LEGACY)) + switch(efi) + { + case EFI_NOT_FOUND: + goto memory_scan; + case EFI_NO_SMBIOS: + ret = 1; + goto exit_free; + } + + if ((buf = mem_chunk(NULL, fp, 0x20, memdev )) == NULL){ + ret = 1; + goto exit_free; + } + + if (memcmp(buf, "_SM3_", 5) == 0){ + if(smbios3_decode(buf, memdev, 0, dumpfile)) + found++; + } else if (memcmp(buf, "_SM_", 4) == 0){ + if(smbios_decode(buf, memdev, 0, dumpfile)) found++; } + goto done; - if(ret == 0) { - free(buf); - if(!found) { - ret = -1; +memory_scan: +#if defined __i386__ || defined __x86_64__ + /* Fallback to memory scan (x86, x86_64) */ + if((buf = mem_chunk(NULL, 0xF0000, 0x10000, memdev)) == NULL) { + ret = 1; + goto exit_free; + } + + /* Look for a 64-bit entry point first */ + for(fp = 0; fp <= 0xFFF0; fp += 16){ + if(memcmp(buf + fp, "_SM3_", 5) == 0 && fp <= 0xFFE0){ + if(smbios3_decode(buf + fp, memdev, 0, dumpfile)){ + found++; + goto done; + } + } + } + + /* If none found, look for a 32-bit entry point */ + for(fp = 0; fp <= 0xFFF0; fp += 16) { + if(memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0) { + if(smbios_decode(buf + fp, memdev, 0, dumpfile)){ + found++; + goto done; + } + } else if (memcmp(buf+fp, "_DMI_", 5) == 0){ + if(legacy_decode(buf+fp, memdev, 0, dumpfile)){ + found++; + goto done; + } } } +#endif + +done: + if(!found){ + printf("No SMBIOS nor DMI entry point found, sorry.\n"); + } + free(buf); + +exit_free: + if (!found) + free(buf); - return ret == 0 ? found : ret; + return ret; } diff --git a/src/dmidump.h b/src/dmidump.h index 3c12248..a025829 100644 --- a/src/dmidump.h +++ b/src/dmidump.h @@ -32,6 +32,13 @@ #define NON_LEGACY 0 #define LEGACY 1 +#define FLAG_NO_FILE_OFFSET (1 << 0) +#define FLAG_STOP_AT_EOT (1 << 1) + +#define SYS_FIRMWARE_DIR "/sys/firmware/dmi/tables" +#define SYS_ENTRY_FILE SYS_FIRMWARE_DIR "/smbios_entry_point" +#define SYS_TABLE_FILE SYS_FIRMWARE_DIR "/DMI" + int dump(const char *memdev, const char *dumpfile); #endif diff --git a/src/util.c b/src/util.c index da97767..4f233ff 100644 --- a/src/util.c +++ b/src/util.c @@ -50,7 +50,6 @@ #include "util.h" #include "dmilog.h" -#ifndef USE_MMAP static int myread(Log_t *logp, int fd, u8 * buf, size_t count, const char *prefix) { ssize_t r = 1; @@ -76,7 +75,6 @@ static int myread(Log_t *logp, int fd, u8 * buf, size_t count, const char *prefi return 0; } -#endif int checksum(const u8 * buf, size_t len) { @@ -88,6 +86,73 @@ int checksum(const u8 * buf, size_t len) return (sum == 0); } +/* + * Reads all of file from given offset, up to max_len bytes. + * A buffer of at most max_len bytes is allocated by this function, and + * needs to be freed by the caller. + * This provides a similar usage model to mem_chunk() + * + * Returns a pointer to the allocated buffer, or NULL on error, and + * sets max_len to the length actually read. + */ +void *read_file(Log_t *logp, off_t base, size_t *max_len, const char *filename) +{ + struct stat statbuf; + int fd; + u8 *p; + /* + * Don't print error message on missing file, as we will try to read + * files that may or may not be present. + */ + if ((fd = open(filename, O_RDONLY)) == -1) + { + if (errno != ENOENT) + perror(filename); + return NULL; + } + + /* + * Check file size, don't allocate more than can be read. + */ + if (fstat(fd, &statbuf) == 0) + { + if (base >= statbuf.st_size) + { + fprintf(stderr, "%s: Can't read data beyond EOF\n", + filename); + p = NULL; + goto out; + } + if (*max_len > (size_t)statbuf.st_size - base) + *max_len = statbuf.st_size - base; + } + + if ((p = malloc(*max_len)) == NULL) + { + perror("malloc"); + goto out; + } + + if (lseek(fd, base, SEEK_SET) == -1) + { + fprintf(stderr, "%s: ", filename); + perror("lseek"); + goto err_free; + } + if (myread(logp, fd, p, *max_len, filename) == 0) + goto out; + +err_free: + free(p); + p = NULL; + +out: + if (close(fd) == -1) + perror(filename); + + return p; +} + /* Static global variables which should only * be used by the sigill_handler() */ @@ -105,6 +170,18 @@ void sigill_handler(int ignore_this) { } } +static void safe_memcpy(void *dest, const void *src, size_t n) +{ +#ifdef USE_SLOW_MEMCPY + size_t i; + + for (i = 0; i < n; i++) + *((u8 *)dest + i) = *((const u8 *)src + i); +#else + memcpy(dest, src, n); +#endif +} + /* * Copy a physical memory chunk into a memory buffer. * This function allocates memory. @@ -115,7 +192,8 @@ void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem) int fd = -1; #ifdef USE_MMAP - size_t mmoffset; + struct stat statbuf; + size_t mmoffset; void *mmp; #endif sigill_logobj = logp; @@ -134,6 +212,23 @@ void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem) goto exit; } #ifdef USE_MMAP + if (sigill_error || fstat(fd, &statbuf) == -1 ) + { + log_append(logp, LOGFL_NORMAL, LOG_WARNING,"fstat: %s", strerror(errno)); + goto err_free; + } + + /* + * mmap() will fail with SIGBUS if trying to map beyond the end of + * the file. + */ + if (sigill_error || S_ISREG(statbuf.st_mode) && base + (off_t)len > statbuf.st_size ) + { + log_append(logp, LOGFL_NORMAL, LOG_WARNING, + "mmap: Can't map beyond end of file %s: %s", + devmem, strerror(errno)); + goto err_free; + } #ifdef _SC_PAGESIZE mmoffset = base % sysconf(_SC_PAGESIZE); #else @@ -147,9 +242,7 @@ void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem) mmp = mmap(0, mmoffset + len, PROT_READ, MAP_SHARED, fd, base - mmoffset); if(sigill_error || (mmp == MAP_FAILED)) { log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s (mmap): %s", devmem, strerror(errno)); - free(p); - p = NULL; - goto exit; + goto try_read; } memcpy(p, (u8 *) mmp + mmoffset, len); @@ -167,28 +260,34 @@ void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem) p = NULL; goto exit; } -#else /* USE_MMAP */ - if(sigill_error || (lseek(fd, base, SEEK_SET) == -1)) { + goto exit; + +try_read: +#endif /* USE_MMAP */ + if (lseek(fd, base, SEEK_SET) == -1 ) + { log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s (lseek): %s", devmem, strerror(errno)); - free(p); - p = NULL; - goto exit; + goto err_free; } - if(sigill_error || (myread(logp, fd, p, len, devmem) == -1)) { + if(sigill_error || (myread(logp, fd, p, len, devmem) == 0)) { free(p); p = NULL; goto exit; } -#endif /* USE_MMAP */ - exit: +err_free: + free(p); + p = NULL; + +exit: if (fd >= 0) { if(close(fd) == -1) perror(devmem); } signal(SIGILL, SIG_DFL); sigill_logobj = NULL; + return p; } @@ -207,3 +306,42 @@ u64 u64_range(u64 start, u64 end) return res; } + +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; +} diff --git a/src/util.h b/src/util.h index aa0487a..3c803c0 100644 --- a/src/util.h +++ b/src/util.h @@ -27,6 +27,7 @@ #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) int checksum(const u8 * buf, size_t len); +void *read_file( Log_t *logp, off_t base, size_t *len, const char *filename); void *mem_chunk(Log_t *logp, 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); u64 u64_range(u64 start, u64 end); From fbaab9283729b0de4862bdd774d2cf866bd4ea5f Mon Sep 17 00:00:00 2001 From: Zhongze Hu Date: Mon, 5 Sep 2022 02:14:39 +0800 Subject: [PATCH 123/146] Fix for printing an empty dictionary Currently, python-dmidecode will print an empty dictionary as below: # python3 Python 3.9.13 (main, Jul 25 2022, 00:00:00) [GCC 11.3.1 20220421 (Red Hat 11.3.1-2)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import dmidecode >>> dmidecode.bios() {} >>> This patch will solve the above issue. Signed-off-by: Zhongze Hu --- src/dmidecode.c | 12 +++++------- src/dmidump.c | 6 +++--- src/efi.c | 5 ++++- src/util.c | 5 +++-- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index 19958d3..cd9e420 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -92,7 +92,7 @@ #include "dmihelper.h" -#define SUPPORTED_SMBIOS_VER 0x0207 +#define SUPPORTED_SMBIOS_VER 0x030300 /******************************************************************************* ** Type-independant Stuff @@ -5197,7 +5197,7 @@ dmi_codes_major *find_dmiMajor(const struct dmi_header *h) return NULL; } -static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver, const char *devmem, u32 flags, xmlNode *xmlnode) +static void dmi_table(Log_t *logp, int type, u32 base, u32 len, u16 num, u32 ver, const char *devmem, u32 flags, xmlNode *xmlnode) { static u8 version_added = 0; u8 *buf; @@ -5241,7 +5241,7 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver } if (ver > SUPPORTED_SMBIOS_VER){ - log_append(logp, LOGFL_NODUPS, LOG_WARNING, "# SMBIOS implementations newer than version %u.%u are not\n", "# fully supported by this version of dmidecode.\n", SUPPORTED_SMBIOS_VER >> 8, SUPPORTED_SMBIOS_VER & 0xFF); + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "# SMBIOS implementations newer than version %u.%u.%u are not\n fully supported by this version of dmidecode.\n", SUPPORTED_SMBIOS_VER >> 16, (SUPPORTED_SMBIOS_VER >> 8) & 0xFF, SUPPORTED_SMBIOS_VER & 0xFF); } if( version_added == 0 ) { @@ -5250,7 +5250,7 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver } data = buf; - while(i < num && data + 4 <= buf + len) { /* 4 is the length of an SMBIOS structure header */ + while((i < num||!num) && data + 4 <= buf + len) { /* 4 is the length of an SMBIOS structure header */ u8 *next; struct dmi_header h; @@ -5364,8 +5364,7 @@ xmlNode *smbios3_decode_get_version(u8 * buf, const char *devmem) dmixml_AddAttribute(data_n, "type", "SMBIOS"); if(check == 1) { - u16 ver = (buf[0x07] << 16) + (buf[0x08] << 8) + buf[0x09]; - + u32 ver = (buf[0x07] << 16) + (buf[0x08] << 8) + buf[0x09]; dmixml_AddTextContent(data_n, "SMBIOS %i.%i.%i present", buf[0x07], buf[0x08], buf[0x09]); dmixml_AddAttribute(data_n, "version", "%i.%i.%i", buf[0x07], buf[0x08],buf[0x09]); } else if(check == 0) { @@ -5396,7 +5395,6 @@ int smbios3_decode(Log_t *logp, int type, u8 *buf, const char *devmem, u32 flags { return 0; } - dmi_table(logp, type, ((off_t)offset.h << 32) | offset.l, DWORD(buf+0x0C), 0, ver, devmem, flags | FLAG_STOP_AT_EOT, xmlnode); } diff --git a/src/dmidump.c b/src/dmidump.c index 0d052fc..da0d676 100644 --- a/src/dmidump.c +++ b/src/dmidump.c @@ -96,11 +96,11 @@ static int smbios3_decode(u8 *buf, const char *devmem, u32 flags, const char *du offset = QWORD(buf + 0x10); ver = (buf[0x07] << 16) + (buf[0x08] << 8) + buf[0x09]; - dmi_table(((off_t)offset.h << 32) | offset.l,DWORD(buf + 0x0C), 0, ver, devmem, flags | FLAG_STOP_AT_EOT, dumpfile); - - if (!checksum(buf, buf[0x05])) + if (!checksum(buf, buf[0x06])) return 0; + dmi_table(((off_t)offset.h << 32) | offset.l,DWORD(buf + 0x0C), 0, ver, devmem, flags | FLAG_STOP_AT_EOT, dumpfile); + u8 crafted[32]; memcpy(crafted, buf, 32); overwrite_smbios3_address(crafted); diff --git a/src/efi.c b/src/efi.c index ae8d0db..362e2f9 100644 --- a/src/efi.c +++ b/src/efi.c @@ -49,6 +49,7 @@ int address_from_efi(Log_t *logp, size_t * address) FILE *efi_systab; const char *filename = NULL; char linebuf[64]; + const char *eptype; int ret; *address = 0; /* Prevent compiler warning */ @@ -67,8 +68,10 @@ int address_from_efi(Log_t *logp, size_t * address) char *addrp = strchr(linebuf, '='); *(addrp++) = '\0'; - if(strcmp(linebuf, "SMBIOS") == 0) { + if(strcmp(linebuf, "SMBIOS3") == 0 + || strcmp(linebuf, "SMBIOS") == 0) { *address = strtoul(addrp, NULL, 0); + eptype = linebuf; ret = 0; break; } diff --git a/src/util.c b/src/util.c index 4f233ff..465376e 100644 --- a/src/util.c +++ b/src/util.c @@ -239,13 +239,14 @@ void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem) * 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); + mmp = mmap(NULL, mmoffset + len, PROT_READ, MAP_SHARED, fd, base - mmoffset); if(sigill_error || (mmp == MAP_FAILED)) { log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s (mmap): %s", devmem, strerror(errno)); goto try_read; } - memcpy(p, (u8 *) mmp + mmoffset, len); + safe_memcpy(p, (u8 *) mmp + mmoffset, len); + if (sigill_error) { log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Failed to do memcpy() due to SIGILL signal"); From 2ff3641933ca9fb732f6bcd3d3dd09946f88f7d7 Mon Sep 17 00:00:00 2001 From: Zhongze Hu Date: Wed, 7 Sep 2022 19:33:38 +0800 Subject: [PATCH 124/146] Update python-dmidecode to smbios 3.3.0 1. Update case 1 to case 42 to smbios 3.3.0; 2. Add case 43 for TPM device and Redfish; 3. Add case 43 in pymap file; 4. Using OUT_OF_SPEC Macro for outofspec string; 5. Modify smbios version to 0x030300 6. Test this commit by private/dumpfiles --- src/dmidecode.c | 1342 +++++++++++++++++++++++++++++++++++++++-------- src/dmidecode.h | 3 +- src/pymap.xml | 3 + 3 files changed, 1130 insertions(+), 218 deletions(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index cd9e420..0eeb1ac 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -79,6 +79,7 @@ #include #include #include +#include #include "version.h" #include "config.h" @@ -93,11 +94,24 @@ #include "dmihelper.h" #define SUPPORTED_SMBIOS_VER 0x030300 +#define OUT_OF_SPEC "outofspec" /******************************************************************************* ** Type-independant Stuff */ +/* Returns 1 if the buffer contains only printable ASCII characters */ +int is_printable(const u8 *data, int len) +{ + int i; + + for (i = 0; i < len; i++) + if (data[i] < 32 || data[i] >= 127) + return 0; + + return 1; +} + const char *dmi_string(const struct dmi_header *dm, u8 s) { char *bp = (char *)dm->data; @@ -177,11 +191,12 @@ xmlNode *dmi_smbios_structure_type(xmlNode *node, u8 code) {"Additional Information", "AdditionalInfo", NULL, NULL}, {"Onboard Device", "OnboardDevice", NULL, NULL}, /* 41 */ {"Management Controller Host Interface", "MgmntCtrltHostIntf", NULL, NULL}, /* 42 */ + {"TPM Device", "TPMDevice", NULL, NULL}, /* 43 */ /* *INDENT-ON* */ }; xmlNode *type_n = NULL; - if(code <= 42) { + if(code <= 43) { type_n = xmlNewChild(node, NULL, (xmlChar *)types[code].tagname, NULL); assert( type_n != NULL ); @@ -191,6 +206,10 @@ xmlNode *dmi_smbios_structure_type(xmlNode *node, u8 code) if( (types[code].attrname != NULL) && (types[code].attrvalue != NULL) ) { dmixml_AddAttribute(type_n, types[code].attrname, "%s", types[code].attrvalue); } + } else if (code >= 128) { + type_n = xmlNewChild(node, NULL, (xmlChar *)"OEMspecific", NULL); + assert( type_n != NULL ); + dmixml_AddAttribute(type_n, "flags", "0x%04x", code); } else { type_n = xmlNewChild(node, NULL, (xmlChar *) "UnknownSMBiosType", NULL); dmixml_AddAttribute(type_n, "flags", "0x%04x", code); @@ -307,8 +326,6 @@ static void dmi_add_memory_size(xmlNode *node, u64 code, int shift) } - - /******************************************************************************* ** 7.1 BIOS Information (Type 0) */ @@ -328,6 +345,30 @@ void dmi_bios_runtime_size(xmlNode *node, u32 code) } } +void dmi_bios_rom_size(xmlNode *node, u8 code1, u16 code2) +{ + static const char *unit[4] = { + "MB", "GB" + }; + + xmlNode *brz_n = xmlNewChild(node, NULL, (xmlChar *)"ROMSize", NULL); + dmixml_AddAttribute(brz_n, "flags", "0x%04x", code1); + + if (code1 != 0xFF) + { + u64 s = { .l = (code1 + 1) << 6}; + dmi_add_memory_size(brz_n, s, 1); + }else{ + if ( (code2 >> 14) <= 0x02 ){ + dmixml_AddAttribute(brz_n, "unit", unit[code2 >> 14]); + dmixml_AddTextContent(brz_n, "%i", code2 & 0x3FFF); + }else{ + dmixml_AddAttribute(brz_n, OUT_OF_SPEC, "1"); + } + + } +} + /* 7.1.1 */ void dmi_bios_characteristics(xmlNode *node, u64 code) { @@ -500,7 +541,7 @@ void dmi_system_wake_up_type(xmlNode *node, u8 code) if(code <= 0x08) { dmixml_AddTextContent(swut_n, type[code]); } else { - dmixml_AddAttribute(swut_n, "outofspec", "1"); + dmixml_AddAttribute(swut_n, OUT_OF_SPEC, "1"); } } @@ -620,7 +661,14 @@ void dmi_chassis_type(xmlNode *node, u8 code) "CompactPCI", "AdvancedTCA", /* 0x1B */ "Blade", - "Blade Enclosing" /* 0x1D */ + "Blade Enclosing", /* 0x1D */ + "Tablet", + "Convertible", + "Detachable", + "IoT Gateway", + "Embedded PC", + "Mini PC", + "Stick PC" /* 0x24 */ }; xmlNode *type_n = xmlNewChild(node, NULL, (xmlChar *)"ChassisType", NULL); assert( type_n != NULL ); @@ -629,7 +677,7 @@ void dmi_chassis_type(xmlNode *node, u8 code) code &= 0x7F; /* bits 6:0 are chassis type, 7th bit is the lock bit */ - if(code >= 0x01 && code <= 0x1B) { + if(code >= 0x01 && code <= 0x24) { dmixml_AddAttribute(type_n, "available", "1"); dmixml_AddTextContent(type_n, "%s", type[code - 0x01]); } else { @@ -691,7 +739,7 @@ void dmi_chassis_security_status(xmlNode *node, u8 code) if(code >= 0x01 && code <= 0x05) { dmixml_AddTextContent(secstat_n, "%s", status[code - 0x01]); } else { - dmixml_AddAttribute(secstat_n, "unavailable", "1"); + dmixml_AddAttribute(secstat_n, OUT_OF_SPEC, "1"); } } @@ -701,7 +749,7 @@ void dmi_chassis_height(xmlNode *node, u8 code) assert( hght_n != NULL ); if(code == 0x00) { - dmixml_AddAttribute(hght_n, "unspecified", "1"); + dmixml_AddAttribute(hght_n, OUT_OF_SPEC, "1"); } else { dmixml_AddAttribute(hght_n, "unit", "U"); dmixml_AddTextContent(hght_n, "%i", code); @@ -714,7 +762,7 @@ void dmi_chassis_power_cords(xmlNode *node, u8 code) assert( pwrc_n != NULL ); if(code == 0x00) { - dmixml_AddAttribute(pwrc_n, "unspecified", "1"); + dmixml_AddAttribute(pwrc_n, OUT_OF_SPEC, "1"); } else { dmixml_AddTextContent(pwrc_n, "%i", code); } @@ -771,7 +819,7 @@ void dmi_processor_type(xmlNode *node, u8 code) if(code >= 0x01 && code <= 0x06) { dmixml_AddTextContent(proct_n, type[code - 0x01]); } else { - dmixml_AddAttribute(proct_n, "outofspec", "1"); + dmixml_AddAttribute(proct_n, OUT_OF_SPEC, "1"); } } @@ -829,6 +877,10 @@ void dmi_processor_family(xmlNode *node, const struct dmi_header *h, u16 ver) { 0x29, "Core Duo Mobile" }, { 0x2A, "Core Solo Mobile" }, { 0x2B, "Atom" }, + { 0x2C, "Core M" }, + { 0x2D, "Core m3" }, + { 0x2E, "Core m5" }, + { 0x2F, "Core m7" }, { 0x30, "Alpha" }, { 0x31, "Alpha 21064" }, @@ -880,6 +932,12 @@ void dmi_processor_family(xmlNode *node, const struct dmi_header *h, u16 ver) { 0x63, "68010" }, { 0x64, "68020" }, { 0x65, "68030" }, + { 0x66, "Athlon X4" }, + { 0x67, "Opteron X1000" }, + { 0x68, "Opteron X2000" }, + { 0x69, "Opteron A-Series" }, + { 0x6A, "Opteron X3000" }, + { 0x6B, "Zen" }, { 0x70, "Hobbit" }, @@ -992,6 +1050,8 @@ void dmi_processor_family(xmlNode *node, const struct dmi_header *h, u16 ver) { 0xFA, "i860" }, { 0xFB, "i960" }, + { 0x100, "ARMv7" }, + { 0x101, "ARMv8" }, { 0x104, "SH-3" }, { 0x105, "SH-4" }, @@ -1007,6 +1067,9 @@ void dmi_processor_family(xmlNode *node, const struct dmi_header *h, u16 ver) { 0x15E, "DSP" }, { 0x1F4, "Video Processor" }, + { 0x200, "RV32" }, + { 0x201, "RV64" }, + { 0x202, "RV128" } /* *INDENT-ON* */ }; @@ -1071,7 +1134,7 @@ void dmi_processor_family(xmlNode *node, const struct dmi_header *h, u16 ver) } if(low == high) { /* Not found */ - dmixml_AddAttribute(family_n, "outofspec", "1"); + dmixml_AddAttribute(family_n, OUT_OF_SPEC, "1"); return; } @@ -1081,7 +1144,7 @@ void dmi_processor_family(xmlNode *node, const struct dmi_header *h, u16 ver) low = i + 1; } - dmixml_AddAttribute(family_n, "outofspec", "1"); + dmixml_AddAttribute(family_n, OUT_OF_SPEC, "1"); } xmlNode *dmi_processor_id(xmlNode *node, const struct dmi_header *h) @@ -1134,7 +1197,7 @@ xmlNode *dmi_processor_id(xmlNode *node, const struct dmi_header *h) assert( data_n != NULL ); assert( h && h->data ); - type = h->data[0x06]; + type = (h->data[0x06] == 0xFE && h->length >=0x2A) ? WORD(h->data+0x28) : h->data[0x06]; p = h->data + 8; version = (char *) dmi_string(h, h->data[0x10]); @@ -1186,6 +1249,21 @@ xmlNode *dmi_processor_id(xmlNode *node, const struct dmi_header *h) dx & 0xF); return data_n; } + } else if ( (type >= 0x100 && type <= 0x101) /* ARM */ + || (type >= 0x118 && type <= 0x119)) /* ARM */ + { + u32 midr = DWORD(p); + /* + * The format of this field was not defined for ARM processors + * before version 3.1.0 of the SMBIOS specification, so we + * silently skip it if it reads all zeroes. + */ + if (midr == 0) + return data_n; + dmixml_AddTextChild(data_n, "Signature", + "Implementor 0x%02x, Variant 0x%x, Architecture %i, Part 0x%03x, Revision %i", + midr >> 24, (midr >> 20) & 0xF, (midr >> 16) & 0xF, (midr >> 4) & 0xFFF, midr & 0xF); + return data_n; } else if( (type >= 0x0B && type <= 0x15) /* Intel, Cyrix */ ||(type >= 0x28 && type <= 0x2B) /* Intel */ ||(type >= 0xA1 && type <= 0xB3) /* Intel */ @@ -1197,14 +1275,14 @@ xmlNode *dmi_processor_id(xmlNode *node, const struct dmi_header *h) ) { sig = 1; - - } else if((type >= 0x18 && type <= 0x1D) /* AMD */ - ||type == 0x1F /* AMD */ - ||(type >= 0x38 && type <= 0x3E) /* AMD */ - ||(type >= 0x46 && type <= 0x49) /* AMD */ - ||(type >= 0x83 && type <= 0x8F) /* AMD */ - ||(type >= 0xB6 && type <= 0xB7) /* AMD */ - ||(type >= 0xE6 && type <= 0xEF) /* AMD */ + } else if((type >= 0x18 && type <= 0x1D) /* AMD */ + ||type == 0x1F /* AMD */ + ||(type >= 0x38 && type <= 0x3F) /* AMD */ + ||(type >= 0x46 && type <= 0x4F) /* AMD */ + ||(type >= 0x66 && type <= 0x6B) /* AMD */ + ||(type >= 0x83 && type <= 0x8F) /* AMD */ + ||(type >= 0xB6 && type <= 0xB7) /* AMD */ + ||(type >= 0xE6 && type <= 0xEF) /* AMD */ ) { sig = 2; @@ -1236,14 +1314,21 @@ xmlNode *dmi_processor_id(xmlNode *node, const struct dmi_header *h) return data_n; } + /* + * 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. + */ 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); + (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", @@ -1290,7 +1375,7 @@ void dmi_processor_voltage(xmlNode *node, u8 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 ) { + } else if( (code & 0x07 ) == 0x00 ) { dmixml_AddAttribute(vltg_n, "unknown_value", "1"); } else { for(i = 0; i <= 2; i++) { @@ -1333,7 +1418,7 @@ void dmi_processor_status(xmlNode *node, u8 code) } else if( code == 0x07 ) { dmixml_AddTextContent(prst_n, "%s", status[5]); } else { - dmixml_AddAttribute(prst_n, "outofspec", "1"); + dmixml_AddAttribute(prst_n, OUT_OF_SPEC, "1"); } } @@ -1384,18 +1469,33 @@ void dmi_processor_upgrade(xmlNode *node, u8 code) "Socket FM1", "Socket FM2", "Socket LGA2011-3", - "Socket LGA1356-3" /* 0x2C */ - + "Socket LGA1356-3", /* 0x2C */ + "Socket LGA1150", + "Socket BGA1168", + "Socket BGA1234", + "Socket BGA1364", + "Socket AM4", + "Socket LGA1151", + "Socket BGA1356", + "Socket BGA1440", + "Socket BGA1515", + "Socket LGA3647-1", + "Socket SP3", + "Socket SP3r2", + "Socket LGA2066", + "Socket BGA1392", + "Socket BGA1510", + "Socket BGA1528" /* 0x3C */ }; xmlNode *upgr_n = xmlNewChild(node, NULL, (xmlChar *) "Upgrade", NULL); assert( upgr_n != NULL ); dmixml_AddAttribute(upgr_n, "dmispec", "7.5.5"); dmixml_AddAttribute(upgr_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x2A) { + if(code >= 0x01 && code <= 0x3C) { dmixml_AddTextContent(upgr_n, "%s", upgrade[code - 0x01]); } else { - dmixml_AddAttribute(upgr_n, "outofspec", "1"); + dmixml_AddAttribute(upgr_n, OUT_OF_SPEC, "1"); } } @@ -1474,7 +1574,7 @@ void dmi_memory_controller_ed_method(xmlNode *node, u8 code) if(code >= 0x01 && code <= 0x08) { dmixml_AddTextContent(ercm_n, method[code - 0x01]); } else { - dmixml_AddAttribute(ercm_n, "outofspec", "1"); + dmixml_AddAttribute(ercm_n, OUT_OF_SPEC, "1"); } } @@ -1527,7 +1627,7 @@ void dmi_memory_controller_interleave(xmlNode *node, const char *tagname, u8 cod if(code >= 0x01 && code <= 0x07) { dmixml_AddTextContent(mci_n, interleave[code - 0x01]); } else { - dmixml_AddAttribute(mci_n, "outofspec", "1"); + dmixml_AddAttribute(mci_n, OUT_OF_SPEC, "1"); } } @@ -1681,19 +1781,17 @@ void dmi_memory_module_error(xmlNode *node, u8 code) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "ModuleErrorStatus", NULL); assert( data_n != NULL ); + static const char *status[] = { + "OK", /* 0x00 */ + "Uncorrectable Errors", + "Correctable Errors", + "Correctable and Uncorrectable Errors" /* 0x03 */ + }; 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"); - } + dmixml_AddAttribute(data_n, "Error Status", "%s", status[code & 0x03]); } } @@ -1729,24 +1827,36 @@ void dmi_cache_location(xmlNode *node, u8 code) if(location[code] != NULL) { dmixml_AddTextContent(data_n, location[code]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } -void dmi_cache_size(xmlNode *node, const char *tagname, u16 code) +void dmi_cache_size_2(xmlNode *node, const char *tagname, u32 code) { - xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); - assert( data_n != NULL ); - dmixml_AddAttribute(data_n, "dmispec", "7.8"); - dmixml_AddAttribute(data_n, "flags", "0x%04x", code); + xmlNode *caches_n = xmlNewChild(node, NULL, (xmlChar *)tagname, NULL); + assert(caches_n != NULL); + dmixml_AddAttribute(caches_n, "dmispec", "7.8"); + dmixml_AddAttribute(caches_n, "flags", "0x%04x", code); - if(code & 0x8000) { - dmixml_AddAttribute(data_n, "unit", "KB"); - dmixml_AddTextContent(data_n, "%i", (code & 0x7FFF) << 6); + u64 size; + if (code & 0x80000000){ + code &= 0x7FFFFFFFLU; + size.l = code << 6; + size.h = code >> 26; } else { - dmixml_AddAttribute(data_n, "unit", "KB"); - dmixml_AddTextContent(data_n, "%i", code); + dmixml_AddAttribute(caches_n, "unit", "KB"); + dmixml_AddTextContent(caches_n, "%i", code); + size.l = code; + size.h = 0; } + + /* Use a more convenient unit for large cache size */ + dmi_add_memory_size(caches_n, size, 1); +} + +void dmi_cache_size(xmlNode *node, const char *tagname, u16 code) +{ + dmi_cache_size_2(node, tagname, (((u32)code & 0x8000LU) << 16) | (code & 0x7FFFLU)); } /* 7.8.2 */ @@ -1798,7 +1908,7 @@ void dmi_cache_ec_type(xmlNode *node, u8 code) if(code >= 0x01 && code <= 0x06) { dmixml_AddTextContent(data_n, type[code - 0x01]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -1820,7 +1930,7 @@ void dmi_cache_type(xmlNode *node, u8 code) if(code >= 0x01 && code <= 0x05) { dmixml_AddTextContent(data_n, type[code - 0x01]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -1851,7 +1961,7 @@ void dmi_cache_associativity(xmlNode *node, u8 code) if(code >= 0x01 && code <= 0x0E) { dmixml_AddTextContent(data_n, type[code - 0x01]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -1897,7 +2007,8 @@ void dmi_port_connector_type(xmlNode *node, const char *tpref, u8 code) "Mini Jack (headphones)", "BNC", "IEEE 1394", - "SAS/SATA Plug Receptacle" /* 0x22 */ + "SAS/SATA Plug Receptacle", /* 0x22 */ + "USB Type-C Receptacle" /* 0x23 */ }; static const char *type_0xA0[] = { "PC-98", /* 0xA0 */ @@ -1913,14 +2024,14 @@ void dmi_port_connector_type(xmlNode *node, const char *tpref, u8 code) dmixml_AddAttribute(data_n, "flags", "0x%04x", code); dmixml_AddAttribute(data_n, "type", "%s", tpref); - if(code <= 0x22) { + if(code <= 0x23) { 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"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -1980,7 +2091,7 @@ void dmi_port_type(xmlNode *node, u8 code) } else if(code == 0xFF) { dmixml_AddTextContent(data_n, "Other"); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -2010,8 +2121,29 @@ void dmi_slot_type(xmlNode *node, u8 code) "AGP 2x", "AGP 4x", "PCI-X", - "AGP 8x" /* 0x13 */ + "AGP 8x", /* 0x13 */ + "M.2 Socket 1-DP", + "M.2 Socket 1-SD", + "M.2 Socket 2", + "M.2 Socket 3", + "MXM Type I", + "MXM Type II", + "MXM Type III", + "MXM Type III-HE", + "MXM Type IV", + "MXM 3.0 Type A", + "MXM 3.0 Type B", + "PCI Express 2 SFF-8639", + "PCI Express 3 SFF-8639", + "PCI Express Mini 52-pin with bottom-side keep-outs", + "PCI Express Mini 52-pin without bottom-side keep-outs", + "PCI Express Mini 76-pin" /* 0x23 */ + }; + + static const char *type_0x30[] = { + "CXL FLexbus 1.0" /* 0x30 */ }; + static const char *type_0xA0[] = { "PC-98/C20", /* 0xA0 */ "PC-98/C24", @@ -2035,19 +2167,30 @@ void dmi_slot_type(xmlNode *node, u8 code) "PCI Express 3 x2", "PCI Express 3 x4", "PCI Express 3 x8", - "PCI Express 3 x16" /* 0xB6 */ + "PCI Express 3 x16", /* 0xB6 */ + NULL, /* 0xB7 */ + "PCI Express 4", + "PCI Express 4 x1", + "PCI Express 4 x2", + "PCI Express 4 x4", + "PCI Express 4 x8", + "PCI Express 4 x16" /* 0xBD */ }; xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "SlotType", NULL); assert( data_n != NULL ); dmixml_AddAttribute(data_n, "dmispec", "7.10.1"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x13) { + if(code >= 0x01 && code <= 0x23) { dmixml_AddTextContent(data_n, "%s", type[code - 0x01]); - } else if(code >= 0xA0 && code <= 0xB6) { + } else if (code == 0x30){ + dmixml_AddTextContent(data_n, "%s", type_0x30[code - 0x30]); + } else if (code >= 0xA0 && code <= 0xB6) { dmixml_AddTextContent(data_n, "%s", type_0xA0[code - 0xA0]); + } else if (code >= 0xB8 && code <= 0xBD) { + dmixml_AddTextContent(data_n, "%s", type_0xA0[code - 0xB8]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -2078,7 +2221,7 @@ void dmi_slot_bus_width(xmlNode *node, u8 code) if( (code >= 0x01) && (code <= 0x0E) ) { dmixml_AddTextContent(data_n, "%s", width[code - 0x01]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -2089,7 +2232,8 @@ void dmi_slot_current_usage(xmlNode *node, u8 code) "Other", /* 0x01 */ "Unknown", "Available", - "In Use" /* 0x04 */ + "In Use", /* 0x04 */ + "Unavailable" /* 0x05 */ }; xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "CurrentUsage", NULL); @@ -2098,10 +2242,10 @@ void dmi_slot_current_usage(xmlNode *node, u8 code) dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x04) { + if(code >= 0x01 && code <= 0x05) { dmixml_AddTextContent(data_n, usage[code - 0x01]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -2112,7 +2256,9 @@ void dmi_slot_length(xmlNode *node, u8 code) "Other", /* 0x01 */ "Unknown", "Short", - "Long" /* 0x04 */ + "Long", /* 0x04 */ + "2.5\" drive form factor", + "3.5\" drive form factor" /* 0x06 */ }; xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "SlotLength", NULL); @@ -2120,15 +2266,15 @@ void dmi_slot_length(xmlNode *node, u8 code) dmixml_AddAttribute(data_n, "dmispec", "7.10.4"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x04) { + if(code >= 0x01 && code <= 0x06) { dmixml_AddTextContent(data_n, length[code - 0x01]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } /* 7.10.5 */ -void inline set_slottype(xmlNode *node, u8 type) { +void set_slottype(xmlNode *node, u8 type) { switch (type) { case 0x04: /* MCA */ dmixml_AddAttribute(node, "slottype", "MCA"); @@ -2149,6 +2295,11 @@ void inline set_slottype(xmlNode *node, u8 type) { case 0x12: /* PCI-X */ dmixml_AddAttribute(node, "slottype", "PCI-X"); break; + case 0x21: /* PCI Express Mini */ + case 0x22: /* PCI Express Mini */ + case 0x23: /* PCI Express Mini */ + dmixml_AddAttribute(node, "slottype", "PCI Express Mini"); + break; case 0xA5: /* PCI Express */ case 0xA6: /* PCI Express */ case 0xA7: /* PCI Express */ @@ -2157,6 +2308,7 @@ void inline set_slottype(xmlNode *node, u8 type) { case 0xAA: /* PCI Express */ dmixml_AddAttribute(node, "slottype", "PCI Express"); break; + case 0x1F: /* PCI Express 2*/ case 0xAB: /* PCI Express 2*/ case 0xAC: /* PCI Express 2*/ case 0xAD: /* PCI Express 2*/ @@ -2165,6 +2317,23 @@ void inline set_slottype(xmlNode *node, u8 type) { case 0xB0: /* PCI Express 2*/ dmixml_AddAttribute(node, "slottype", "PCI Express 2"); break; + case 0x20: /* PCI Express 3 */ + case 0xB1: /* PCI Express 3 */ + case 0xB2: /* PCI Express 3 */ + case 0xB3: /* PCI Express 3 */ + case 0xB4: /* PCI Express 3 */ + case 0xB5: /* PCI Express 3 */ + case 0xB6: /* PCI Express 3 */ + dmixml_AddAttribute(node, "slottype", "PCI Express 3"); + break; + case 0xB8: /* PCI Express 4 */ + case 0xB9: /* PCI Express 4 */ + case 0xBA: /* PCI Express 4 */ + case 0xBB: /* PCI Express 4 */ + case 0xBC: /* PCI Express 4 */ + case 0xBD: /* PCI Express 4 */ + dmixml_AddAttribute(node, "slottype", "PCI Express 4"); + break; case 0x07: /* PCMCIA */ dmixml_AddAttribute(node, "slottype", "PCMCIA"); break; @@ -2187,30 +2356,47 @@ void dmi_slot_id(xmlNode *node, u8 code1, u8 code2, u8 type) 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 */ - case 0xA6: /* PCI Express */ - case 0xA7: /* PCI Express */ - case 0xA8: /* PCI Express */ - case 0xA9: /* PCI Express */ - case 0xAA: /* PCI Express */ - case 0xAB: /* PCI Express 2 */ - case 0xAC: /* PCI Express 2 */ - case 0xAD: /* PCI Express 2 */ - case 0xAE: /* PCI Express 2 */ - case 0xAF: /* PCI Express 2 */ - case 0xB0: /* PCI Express 2 */ + case 0x06: /* PCI */ + case 0x0E: /* PCI */ + case 0x0F: /* AGP */ + case 0x10: /* AGP */ + case 0x11: /* AGP */ + case 0x12: /* PCI-X */ + case 0x13: /* AGP */ + case 0x1F: /* PCI Express 2 */ + case 0x20: /* PCI Express 3 */ + case 0x21: /* PCI Express Mini */ + case 0x22: /* PCI Express Mini */ + case 0x23: /* PCI Express Mini */ + case 0xA5: /* PCI Express */ + case 0xA6: /* PCI Express */ + case 0xA7: /* PCI Express */ + case 0xA8: /* PCI Express */ + case 0xA9: /* PCI Express */ + case 0xAA: /* PCI Express */ + case 0xAB: /* PCI Express 2 */ + case 0xAC: /* PCI Express 2 */ + case 0xAD: /* PCI Express 2 */ + case 0xAE: /* PCI Express 2 */ + case 0xAF: /* PCI Express 2 */ + case 0xB0: /* PCI Express 2 */ + case 0xB1: /* PCI Express 3 */ + case 0xB2: /* PCI Express 3 */ + case 0xB3: /* PCI Express 3 */ + case 0xB4: /* PCI Express 3 */ + case 0xB5: /* PCI Express 3 */ + case 0xB6: /* PCI Express 3 */ + case 0xB8: /* PCI Express 4 */ + case 0xB9: /* PCI Express 4 */ + case 0xBA: /* PCI Express 4 */ + case 0xBB: /* PCI Express 4 */ + case 0xBC: /* PCI Express 4 */ + case 0xBD: /* PCI Express 4 */ 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); + dmixml_AddAttribute(slotid_n, "socket", "%i", code2); break; default: break; @@ -2235,8 +2421,10 @@ void dmi_slot_characteristics(xmlNode *node, u8 code1, u8 code2) static const char *characteristics2[] = { "PME signal is supported", /* 0 */ "Hot-plug devices are supported", - "SMBus signal is supported" /* 2 */ + "SMBus signal is supported", /* 2 */ + "PCIe slot bifurcation is supported" /* 3 */ }; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "SlotCharacteristics", NULL); assert( data_n != NULL ); dmixml_AddAttribute(data_n, "dmispec", "7.10.6, 7.10.7"); @@ -2258,7 +2446,7 @@ void dmi_slot_characteristics(xmlNode *node, u8 code1, u8 code2) c_n = NULL; } } - for(i = 0; i <= 2; i++) { + for(i = 0; i <= 3; i++) { if(code2 & (1 << i)) { xmlNode *c_n = dmixml_AddTextChild(data_n, "Characteristic", "%s", characteristics2[i]); @@ -2281,6 +2469,23 @@ void dmi_slot_segment_bus_func(xmlNode *node, u16 code1, u8 code2, u8 code3) } } +void dmi_slot_peers(xmlNode *node, u8 n, const u8 *data, struct dmi_header *h) +{ + xmlNode *sp_n = xmlNewChild(node, NULL, (xmlChar *)"Peerdevices", NULL); + assert(sp_n != NULL); + + int i; + for (i = 1; i <= n; i++, data += 5){ + xmlNode *dev_n = dmixml_AddDMIstring(sp_n, "device", h, i); + + dmixml_AddAttribute(dev_n, "index", "%i", i); + dmixml_AddTextContent(dev_n, "%04x:%02x:%02x.%x (Width %u)", + WORD(data), data[2], data[3] >> 3, data[3] & 0x07, data[4]); + dev_n = NULL; + } +} + + /******************************************************************************* ** 7.11 On Board Devices Information (Type 10) */ @@ -2307,7 +2512,7 @@ void dmi_on_board_devices_type(xmlNode *node, u8 code) if(code >= 0x01 && code <= 0x0A) { dmixml_AddTextChild(node, "Type", "%s", type[code - 0x01]); } else { - dmixml_AddAttribute(node, "outofspec", "1"); + dmixml_AddAttribute(node, OUT_OF_SPEC, "1"); } } @@ -2402,6 +2607,14 @@ void dmi_bios_languages(xmlNode *node, struct dmi_header *h, u8 brevity_code) } } +static const char *dmi_bios_language_format(u8 code) +{ + if (code & 0x01) + return "Abbreviated"; + else + return "Long"; +} + /******************************************************************************* ** 7.15 Group Associations (Type 14) */ @@ -2446,7 +2659,7 @@ void dmi_event_log_method(xmlNode *node, u8 code) dmixml_AddTextContent(data_n, "OEM-specific"); dmixml_AddAttribute(data_n, "unknown", "1"); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -2513,7 +2726,7 @@ void dmi_event_log_header_type(xmlNode *node, u8 code) } else if(code >= 0x80) { dmixml_AddTextContent(data_n, "OEM-specific"); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -2559,7 +2772,7 @@ void dmi_event_log_descriptor_type(xmlNode *node, u8 code) } else if(code == 0xFF) { dmixml_AddTextContent(data_n, "End of log"); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -2586,7 +2799,7 @@ void dmi_event_log_descriptor_format(xmlNode *node, u8 code) } else if(code >= 0x80) { dmixml_AddTextContent(data_n, "OEM-specific"); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -2628,11 +2841,12 @@ void dmi_memory_array_location(xmlNode *node, u8 code) "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 */ + "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", + "CXL Flexbus 1.0" /* 0xA4, from master.mif */ }; xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Location", NULL); @@ -2642,10 +2856,10 @@ void dmi_memory_array_location(xmlNode *node, u8 code) if(code >= 0x01 && code <= 0x0A) { dmixml_AddTextContent(data_n, location[code - 0x01]); - } else if(code >= 0xA0 && code <= 0xA3) { + } else if(code >= 0xA0 && code <= 0xA4) { dmixml_AddTextContent(data_n, location_0xA0[code - 0xA0]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -2669,7 +2883,7 @@ void dmi_memory_array_use(xmlNode *node, u8 code) if(code >= 0x01 && code <= 0x07) { dmixml_AddTextContent(data_n, use[code - 0x01]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -2694,7 +2908,7 @@ void dmi_memory_array_ec_type(xmlNode *node, u8 code) if(code >= 0x01 && code <= 0x07) { dmixml_AddTextContent(data_n, type[code - 0x01]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -2766,6 +2980,7 @@ void dmi_memory_device_size(xmlNode *node, u16 code) //. 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)); + //dmi_add_memory_size(data_n, code, 1); } } @@ -2793,35 +3008,51 @@ static void dmi_memory_device_extended_size(xmlNode *node, u32 code) } +void dmi_memory_voltage_value(xmlNode *node, const char *tag, u16 code) +{ + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *)tag, NULL); + assert(data_n != NULL); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); + + if (code == 0) { + dmixml_AddAttribute(data_n, "unknown", "1"); + } else { + dmixml_AddAttribute(data_n, "unit", "V"); + dmixml_AddTextContent(data_n, "%.3f", (float)(i16)code / 1000); + } +} + + void dmi_memory_device_form_factor(xmlNode *node, u8 code) { /* 7.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 */ + "Other", /* 0x01 */ + "Unknown", + "SIMM", + "SIP", + "Chip", + "DIP", + "ZIP", + "Proprietary Card", + "DIMM", + "TSOP", + "Row Of Chips", + "RIMM", + "SODIMM", + "SRIMM", + "FB-DIMM", /* 0x0F */ + "Die" /* 0x10 */ }; xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "FormFactor", NULL); assert( data_n != NULL ); dmixml_AddAttribute(data_n, "dmispec", "7.18.1"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x0F) { + if(code >= 0x01 && code <= 0x10) { dmixml_AddTextContent(data_n, "%s", form_factor[code - 0x01]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -2831,9 +3062,11 @@ void dmi_memory_device_set(xmlNode *node, u8 code) 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 ) { + if (code == 0) { + // empty tag + } else if (code == 0xFF) { + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); + } else { dmixml_AddTextContent(data_n, "%ld", code); } } @@ -2842,41 +3075,51 @@ void dmi_memory_device_type(xmlNode *node, u8 code) { /* 7.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 */ - "Reserved", - "Reserved", - "Reserved", - "DDR3", - "FBD2" /* 0x19 */ + "Other", /* 0x01 */ + "Unknown", + "DRAM", + "EDRAM", + "VRAM", + "SRAM", + "RAM", + "ROM", + "Flash", + "EEPROM", + "FEPROM", + "EPROM", + "CDRAM", + "3DRAM", + "SDRAM", + "SGRAM", + "RDRAM", + "DDR", + "DDR2", + "DDR2 FB-DIMM", /* 0x14 */ + "Reserved", + "Reserved", + "Reserved", + "DDR3", + "FBD2", /* 0x19 */ + "DDR4", + "LPDDR", + "LPDDR2", + "LPDDR3", + "LPDDR4", + "Logical non-volatile device", + "HBM", + "HBM2", /* 0x21 */ + "DDR5", + "LPDDR5" /* 0x23 */ }; xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Type", NULL); assert( data_n != NULL ); dmixml_AddAttribute(data_n, "dmispec", "7.18.2"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if(code >= 0x01 && code <= 0x19) { + if(code >= 0x01 && code <= 0x23) { dmixml_AddTextContent(data_n, "%s", type[code - 0x01]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -2917,6 +3160,7 @@ void dmi_memory_device_type_detail(xmlNode *node, u16 code) } } + void dmi_memory_device_speed(xmlNode *node, const char *tag, u16 code) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tag, NULL); @@ -2926,24 +3170,121 @@ void dmi_memory_device_speed(xmlNode *node, const char *tag, u16 code) if(code == 0) { dmixml_AddAttribute(data_n, "unknown", "1"); } else { - dmixml_AddAttribute(data_n, "unit", "MHz"); + dmixml_AddAttribute(data_n, "unit", "MT/s"); dmixml_AddTextContent(data_n, "%i", code); } } -void dmi_memory_voltage_value(xmlNode *node, const char *tag, u16 code) { - xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tag, NULL); - assert( data_n != NULL ); + +void dmi_memory_technology(xmlNode *node, u8 code) +{ + /* 7.18.6 */ + static const char *const technology[] = { + "Other", /* 0x01 */ + "Unknown", + "DRAM", + "NVDIMM-N", + "NVDIMM-F", + "NVDIMM-P", + "Intel Optane DC persistent memory" /* 0x07 */ + }; + + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *)"MemoryTechnology", NULL); + assert(data_n != NULL); + dmixml_AddAttribute(data_n, "dmispec", "7.18.6"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); - if (code == 0) { - dmixml_AddAttribute(data_n, "unknown", "1"); - } else { - dmixml_AddAttribute(data_n, "unit", "V"); - dmixml_AddTextContent(data_n, "%.3f", (float)(i16)code / 1000); + if (code >= 0x01 && code <= 0x07) + dmixml_AddTextContent(data_n, "%s", technology[code - 0x01]); + else + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); +} + +void dmi_memory_operating_mode_capability(xmlNode *node, u16 code) +{ + /* 7.18.7 */ + static const char *const mode[] = { + "Other", /* 1 */ + "Unknown", + "Volatile memory", + "Byte-accessible persistent memory", + "Block-accessible persistent memory" /* 5 */ + }; + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *)"Memory Operating Mode Capability", NULL); + assert(data_n != NULL); + dmixml_AddAttribute(data_n, "dmispec", "7.18.7"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); + + char list[99]; /* Update length if you touch the array above */ + if ((code & 0xFFFE) != 0) { + int i, off = 0; + list[0] = '\0'; + for (i = 1; i <= 5; i++) { + if (code & (1 << i)) + off += sprintf(list + off, off ? " %s" : "%s", mode[i - 1]); + } + dmixml_AddTextContent(data_n, "%s", list); } } +void dmi_memory_manufacturer_id(xmlNode *node, u16 code) +{ + /* 7.18.8 */ + /* 7.18.10 */ + /* LSB is 7-bit Odd Parity number of continuation codes */ + + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *)"Memory Manufacturer Id", NULL); + assert(data_n != NULL); + dmixml_AddAttribute(data_n, "dmispec", "7.18.8/7.18.10"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); + + if (code != 0) { + dmixml_AddAttribute(data_n, "%s", "Bank"); + dmixml_AddTextContent(data_n, "%u", (code & 0x7F) + 1); + dmixml_AddAttribute(data_n, "%s", "Hex"); + dmixml_AddTextContent(data_n, "%u", code >> 8); + } else { + dmixml_AddAttribute(data_n, "unknown", "1"); + } +} + + +void dmi_memory_product_id(xmlNode *node, u16 code) +{ + /* 7.18.9 */ + /* 7.18.11 */ + + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *)"Memory Product Id", NULL); + assert(data_n != NULL); + dmixml_AddAttribute(data_n, "dmispec", "7.18.9/7.18.11"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); + + if (code != 0){ + dmixml_AddTextContent(data_n, "%u", code); + } else { + dmixml_AddAttribute(data_n, "unknown", "1"); + } +} + + +void dmi_memory_size(xmlNode *node, u64 code) +{ + /* 7.18.12 */ + /* 7.18.13 */ + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *)"Memory Size", NULL); + assert(data_n != NULL); + dmixml_AddAttribute(data_n, "dmispec", "7.18.12/7.18.13"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); + + if (code.h == 0xFFFFFFFF && code.l == 0xFFFFFFFF) { + dmixml_AddAttribute(data_n, "unknown", "1"); + } else if (code.h == 0x0 && code.l == 0x0) { + // empty tag + } else { + dmi_add_memory_size(data_n, code, 0); + } +} + /******************************************************************************* * 7.19 32-bit Memory Error Information (Type 18) */ @@ -2975,7 +3316,7 @@ void dmi_memory_error_type(xmlNode *node, u8 code) if(code >= 0x01 && code <= 0x0E) { dmixml_AddTextContent(data_n, "%s", type[code - 0x01]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -2996,7 +3337,7 @@ void dmi_memory_error_granularity(xmlNode *node, u8 code) if(code >= 0x01 && code <= 0x04) { dmixml_AddTextContent(data_n, "%s", granularity[code - 0x01]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -3018,7 +3359,7 @@ void dmi_memory_error_operation(xmlNode *node, u8 code) if(code >= 0x01 && code <= 0x05) { dmixml_AddTextContent(data_n, "%s", operation[code - 0x01]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -3094,7 +3435,7 @@ void dmi_mapped_address_row_position(xmlNode *node, u8 code) assert( data_n != NULL ); if(code == 0) { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } else if(code == 0xFF) { dmixml_AddAttribute(data_n, "unknown", "1"); } else { @@ -3152,7 +3493,7 @@ void dmi_pointing_device_type(xmlNode *node, u8 code) if(code >= 0x01 && code <= 0x09) { dmixml_AddTextContent(data_n, "%s", type[code - 0x01]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -3184,7 +3525,7 @@ void dmi_pointing_device_interface(xmlNode *node, u8 code) } else if(code >= 0xA0 && code <= 0xA2) { dmixml_AddTextContent(data_n, interface_0xA0[code - 0xA0]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -3213,7 +3554,7 @@ void dmi_battery_chemistry(xmlNode *node, u8 code) if(code >= 0x01 && code <= 0x08) { dmixml_AddTextContent(data_n, "%s", chemistry[code - 0x01]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -3273,7 +3614,7 @@ void dmi_system_reset_boot_option(xmlNode *node, const char *tagname, u8 code) if( (code > 0) && (code < 4) ) { dmixml_AddTextContent(data_n, option[code - 0x1]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -3378,7 +3719,7 @@ void dmi_voltage_probe_location(xmlNode *node, u8 code) if(code >= 0x01 && code <= 0x0B) { dmixml_AddTextContent(data_n, "%s", location[code - 0x01]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -3401,7 +3742,7 @@ void dmi_probe_status(xmlNode *node, u8 code) if(code >= 0x01 && code <= 0x06) { dmixml_AddTextContent(data_n, "%s", status[code - 0x01]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -3479,7 +3820,7 @@ void dmi_cooling_device_type(xmlNode *node, u8 code) } else if(code >= 0x10 && code <= 0x11) { dmixml_AddTextContent(data_n, "%s", type_0x10[code - 0x10]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -3529,7 +3870,7 @@ void dmi_temperature_probe_location(xmlNode *node, u8 code) if(code >= 0x01 && code <= 0x0F) { dmixml_AddTextContent(data_n, "%s", location[code - 0x01]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -3621,7 +3962,7 @@ void dmi_system_boot_status(xmlNode *node, u8 code) } else if(code >= 192) { dmixml_AddTextContent(data_n, "Product-specific"); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -3645,6 +3986,21 @@ void dmi_64bit_memory_error_address(xmlNode *node, const char *tagname, u64 code ** 7.35 Management Device (Type 34) */ +/* + * Several boards have a bug where some type 34 structures have their + * length incorrectly set to 0x10 instead of 0x0B. This causes the + * first 5 characters of the device name to be trimmed. It's easy to + * check and fix, so do it, but warn. + */ +void dmi_fixup_type_34(struct dmi_header *h) +{ + u8 *p = h->data; + + if (h->length == 0x10 && is_printable(p + 0x0B, 0x10 - 0x0B)) { + h->length = 0x0B; + } +} + void dmi_management_device_type(xmlNode *node, u8 code) { /* 7.35.1 */ @@ -3671,7 +4027,7 @@ void dmi_management_device_type(xmlNode *node, u8 code) if(code >= 0x01 && code <= 0x0D) { dmixml_AddTextContent(data_n, "%s", type[code - 0x01]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -3693,7 +4049,7 @@ void dmi_management_device_address_type(xmlNode *node, u8 code) if(code >= 0x01 && code <= 0x05) { dmixml_AddTextContent(data_n, "%s", type[code - 0x01]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -3718,7 +4074,7 @@ void dmi_memory_channel_type(xmlNode *node, u8 code) if(code >= 0x01 && code <= 0x04) { dmixml_AddTextContent(data_n, "%s", type[code - 0x01]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -3757,7 +4113,7 @@ void dmi_ipmi_interface_type(xmlNode *node, u8 code) if(code <= 0x04) { dmixml_AddTextContent(data_n, "%s", type[code]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -3793,7 +4149,7 @@ void dmi_ipmi_register_spacing(xmlNode *node, u8 code) if(code <= 0x02) { dmixml_AddTextContent(data_n, "%s", spacing[code]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -3836,7 +4192,7 @@ void dmi_power_supply_type(xmlNode *node, u8 code) if(code >= 0x01 && code <= 0x08) { dmixml_AddTextContent(data_n, "%s", type[code - 0x01]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -3859,7 +4215,7 @@ void dmi_power_supply_status(xmlNode *node, u8 code) if(code >= 0x01 && code <= 0x05) { dmixml_AddTextContent(data_n, "%s", status[code - 0x01]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -3882,7 +4238,7 @@ void dmi_power_supply_range_switching(xmlNode *node, u8 code) if(code >= 0x01 && code <= 0x06) { dmixml_AddTextContent(data_n, "%s", switching[code - 0x01]); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } } @@ -3961,22 +4317,486 @@ xmlNode * dmi_management_controller_host_type(xmlNode *node, u8 code) "16750/16750A UART Register Compatible", "16850/16850A UART Register Compatible" /* 0x08 */ }; - xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "ManagementControllerHost", NULL); + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "ManagementControllerHost", NULL); assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "dmispec", "7.43"); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if (code >= 0x02 && code <= 0x08) { - dmixml_AddTextChild(data_n, "Type", "%s", type[code - 0x01]); + dmixml_AddTextChild(data_n, "Type", "%s", type[code - 0x02]); + } else if (code == 0x40) { + dmixml_AddTextChild(data_n, "Type", "Network"); } else if (code == 0xF0) { dmixml_AddTextChild(data_n, "Type", "OEM"); } else { - dmixml_AddAttribute(data_n, "outofspec", "1"); + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); } return data_n; } +//===================below should be checked========================== + +/* + * 7.43.2: Protocol Record Types + */ +void dmi_protocol_record_type(xmlNode *node, u8 code) +{ + const char *protocol[] = { + "Reserved", /* 0x0 */ + "Reserved", + "IPMI", + "MCTP", + "Redfish over IP" /* 0x4 */ + }; + + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *)"ProtocolRecordType", NULL); + assert(data_n != NULL); + + dmixml_AddAttribute(data_n, "dmispec", "7.43.2"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", code); + + if (code <= 0x4) { + dmixml_AddTextContent(data_n, "%s", protocol[code]); + } else if (code == 0xF0) { + dmixml_AddTextContent(data_n, "OEM"); + } else { + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); + } +} + +/* + * DSP0270: 8.6: Protocol IP Assignment types + */ +void dmi_protocol_assignment_type(xmlNode *node, u8 type) +{ + const char *assignment[] = { + "Unknown", /* 0x0 */ + "Static", + "DHCP", + "AutoConf", + "Host Selected" /* 0x4 */ + }; + + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *)"ProtocolAssignmentType", NULL); + assert(data_n != NULL); + + if (type <= 0x4){ + dmixml_AddTextContent(data_n, "%s", assignment[type]); + } else { + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); + } +} + +/* + * DSP0270: 8.6: Protocol IP Address type + */ +void dmi_address_type(xmlNode *node, u8 type) +{ + const char *addressformat[] = { + "Unknown", /* 0x0 */ + "IPv4", + "IPv6" /* 0x2 */ + }; + + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *)"AddressType", NULL); + assert(data_n != NULL); + + if (type <= 0x2) { + dmixml_AddTextContent(data_n, "Type", "%s", addressformat[type]); + } else { + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); + } +} + +/* + * DSP0270: 8.6 Protocol Address decode + */ +void dmi_address_decode(xmlNode *node, u8 *data, char *storage, u8 addrtype) +{ + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *)"AdressDecode", NULL); + assert(data_n != NULL); + + if (addrtype == 0x1) {/* IPv4 */ + dmixml_AddAttribute(data_n, "Type", "ipv4"); + dmixml_AddTextContent(data_n, "%s", inet_ntop(AF_INET, data, storage, 64)); + } else if (addrtype == 0x2) {/* IPv6 */ + dmixml_AddAttribute(data_n, "Type", "ipv6"); + dmixml_AddTextContent(data_n, "%s", inet_ntop(AF_INET6, data, storage, 64)); + } else { + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); + } +} + +/* + * DSP0270: 8.5: Parse the protocol record format + */ +void dmi_parse_protocol_record(xmlNode *node, u8 *rec) +{ + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *)"ParseProtocolRecord", NULL); + assert(data_n != NULL); + + u8 rid; + u8 rlen; + u8 *rdata; + char buf[64]; + u8 assign_val; + u8 addrtype; + u8 hlen; + const char *addrstr; + const char *hname; + char attr[38]; + + /* DSP0270: 8.5: Protocol Identifier */ + rid = rec[0x0]; + /* DSP0270: 8.5: Protocol Record Length */ + rlen = rec[0x1]; + /* DSP0270: 8.5: Protocol Record Data */ + rdata = &rec[0x2]; + + dmixml_AddAttribute(data_n, "ProtocolID", "%02x", rid); + dmi_protocol_record_type(data_n, rid); + + /* + * Don't decode anything other than Redfish for now + * Note 0x4 is Redfish over IP in 7.43.2 + * and DSP0270: 8.5 + */ + if (rid != 0x4) { + return; + } + + /* + * Ensure that the protocol record is of sufficient length + * For RedFish that means rlen must be at least 91 bytes + * other protcols will need different length checks + */ + if (rlen < 91) { + return; + } + + /* + * DSP0270: 8.6: Redfish Over IP Service UUID + * Note: ver is hardcoded to 0x311 here just for + * convenience. It could get passed from the SMBIOS + * header, but that's a lot of passing of pointers just + * to get that info, and the only thing it is used for is + * to determine the endianess of the field. Since we only + * do this parsing on versions of SMBIOS after 3.1.1, and the + * endianess of the field is always little after version 2.6.0 + * we can just pick a sufficiently recent version here. + */ + xmlNode *subdev_n = dmixml_AddTextChild(data_n, "SubAttr", "%s", "ServiceUUID"); + dmi_system_uuid(subdev_n, &rdata[0], 0x311); + subdev_n = NULL; + + /* + * DSP0270: 8.6: Redfish Over IP Host IP Assignment Type + * Note, using decimal indicies here, as the DSP0270 + * uses decimal, so as to make it more comparable + */ + assign_val = rdata[16]; + subdev_n = dmixml_AddTextChild(data_n, "SubAttr", "%s", "HostIPAssignmentType"); + dmi_protocol_assignment_type(subdev_n, assign_val); + subdev_n = NULL; + + /* DSP0270: 8.6: Redfish Over IP Host Address format */ + addrtype = rdata[17]; + subdev_n = dmixml_AddTextChild(data_n, "SubAttr", "%s", "HostIPAddressFormat"); + dmi_address_type(subdev_n, addrtype); + subdev_n = NULL; + + /* DSP0270: 8.6 IP Assignment types */ + /* We only use the Host IP Address and Mask if the assignment type is static */ + if (assign_val == 0x1 || assign_val == 0x3) { + /* DSP0270: 8.6: the Host IPv[4|6] Address */ + subdev_n = dmixml_AddTextChild(data_n, "SubAttr", "%s", "Address"); + dmi_address_decode(subdev_n, &rdata[18], buf, addrtype); + subdev_n = NULL; + + /* DSP0270: 8.6: Prints the Host IPv[4|6] Mask */ + subdev_n = dmixml_AddTextChild(data_n, "SubAttr", "%s", "Mask"); + dmi_address_decode(subdev_n, &rdata[34], buf, addrtype); + subdev_n = NULL; + } + + /* DSP0270: 8.6: Get the Redfish Service IP Discovery Type */ + assign_val = rdata[50]; + + /* Redfish Service IP Discovery type mirrors Host IP Assignment type */ + subdev_n = dmixml_AddTextChild(data_n, "SubAttr", "%s", "RedfishServiceIPAddressType"); + dmi_protocol_assignment_type(subdev_n, assign_val); + subdev_n = NULL; + + /* DSP0270: 8.6: Get the Redfish Service IP Address Format */ + addrtype = rdata[51]; + subdev_n = dmixml_AddTextChild(data_n, "SubAttr", "%s", "RedfishServiceIPAddressFormat"); + dmi_address_type(subdev_n, addrtype); + subdev_n = NULL; + + if (assign_val == 0x1 || assign_val == 0x3) { + u16 port; + u32 vlan; + + /* DSP0270: 8.6: Prints the Redfish IPv[4|6] Service Address */ + subdev_n = dmixml_AddTextChild(data_n, "SubAttr", "%s", "RedfishServiceAddress"); + dmi_address_decode(subdev_n, &rdata[52], buf, addrtype); + subdev_n = NULL; + + /* DSP0270: 8.6: Prints the Redfish IPv[4|6] Service Mask */ + xmlNode *subdev_n = dmixml_AddTextChild(data_n, "SubAttr", "%s", "RedfishServiceMask"); + dmi_address_decode(subdev_n, &rdata[68], buf, addrtype); + subdev_n = NULL; + + /* DSP0270: 8.6: Redfish vlan and port info */ + port = WORD(&rdata[84]); + vlan = DWORD(&rdata[86]); + subdev_n = dmixml_AddTextChild(data_n, "SubAttr", "%s", "RedfishServicePort"); + dmixml_AddAttribute(subdev_n, "RedfishServicePort", "%hu", port); + subdev_n = NULL; + + subdev_n = dmixml_AddTextChild(data_n, "SubAttr", "%s", "RedfishServiceVlan"); + dmixml_AddAttribute(subdev_n, "RedfishServiceVlan", "%u", vlan); + subdev_n = NULL; + } + + /* DSP0270: 8.6: Redfish host length and name */ + hlen = rdata[90]; + + /* + * DSP0270: 8.6: The length of the host string + 91 (the minimum + * size of a protocol record) cannot exceed the record length + * (rec[0x1]) + */ + hname = (const char *)&rdata[91]; + if (hlen + 91 > rlen) { + hname = OUT_OF_SPEC; + hlen = strlen(OUT_OF_SPEC); + } + subdev_n = dmixml_AddTextChild(data_n, "SubAttr", "%s", "RedfishServiceHostname"); + dmixml_AddTextContent(subdev_n, "%.*s", hlen, hname); + subdev_n = NULL; +} + +/* + * DSP0270: 8.3: Device type ennumeration + */ +void dmi_parse_device_type(xmlNode *node, u8 type) +{ + const char *devname[] = { + "USB", /* 0x2 */ + "PCI/PCIe" /* 0x3 */ + }; + + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *)"ParseDeviceType", NULL); + assert(data_n != NULL); + + if (type >= 0x2 && type <= 0x3) { + dmixml_AddTextContent(data_n, "Type", "%s", devname[type - 0x2]); + } else if (type >= 0x80) { + dmixml_AddTextContent(data_n, "Type", "OEM"); + } else { + dmixml_AddAttribute(data_n, OUT_OF_SPEC, "1"); + } +} + +void dmi_parse_controller_structure(xmlNode *node, struct dmi_header *h) +{ + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "ControllerStructure", NULL); + assert(data_n != NULL); + + int i; + u8 *data = h->data; + /* Host interface type */ + u8 type; + /* Host Interface specific data length */ + u8 len; + u8 count; + u32 total_read; + + /* + * Minimum length of this struct is 0xB bytes + */ + if (h->length < 0xB) + return; + + /* + * Also need to ensure that the interface specific data length + * plus the size of the structure to that point don't exceed + * the defined length of the structure, or we will overrun its + * bounds + */ + len = data[0x5]; + total_read = len + 0x6; + + if (total_read > h->length) { + return; + } + type = data[0x4]; + + dmixml_AddAttribute(data_n, "Type", "%s", "HostInterfaceType"); + dmi_management_controller_host_type(data_n, type); + + /* + * The following decodes are code for Network interface host types only + * As defined in DSP0270 + */ + if (type != 0x40) { + return; + } + + if (len != 0) { + /* DSP0270: 8.3 Table 2: Device Type */ + type = data[0x6]; + + dmi_parse_device_type(data_n, type); + + if (type == 0x2 && len >= 5) { + /* USB Device Type - need at least 6 bytes */ + u8 *usbdata = &data[0x7]; + + /* USB Device Descriptor: idVendor */ + dmixml_AddTextContent(data_n, "idVendor", "0x%04x", WORD(&usbdata[0x0])); + + /* USB Device Descriptor: idProduct */ + dmixml_AddTextContent(data_n, "idProduct", "0x%04x", WORD(&usbdata[0x2])); + + /* + * USB Serial number is here, but its useless, don't + * bother decoding it + */ + } else if (type == 0x3 && len >= 9) { + /* PCI Device Type - Need at least 8 bytes */ + u8 *pcidata = &data[0x7]; + + /* PCI Device Descriptor: VendorID */ + dmixml_AddTextContent(data_n, "VendorID", "0x%04x", WORD(&pcidata[0x0])); + + /* PCI Device Descriptor: DeviceID */ + dmixml_AddTextContent(data_n, "DeviceID", "0x%04x", WORD(&pcidata[0x2])); + + /* PCI Device Descriptor: PCI SubvendorID */ + dmixml_AddTextContent(data_n, "SubVendorID", "0x%04x", WORD(&pcidata[0x4])); + + /* PCI Device Descriptor: PCI SubdeviceID */ + dmixml_AddTextContent(data_n, "SubDeviceID", "0x%04x", WORD(&pcidata[0x6])); + } else if (type == 0x4 && len >= 5) { + /* OEM Device Type - Need at least 4 bytes */ + u8 *oemdata = &data[0x7]; + + /* OEM Device Descriptor: IANA */ + dmixml_AddTextContent(data_n, "VendorID", "0x%02x:0x%02x:0x%02x:0x%02x", oemdata[0x0], oemdata[0x1], oemdata[0x2], oemdata[0x3]); + } + /* Don't mess with unknown types for now */ + } + + /* + * DSP0270: 8.2 and 8.5: Protocol record count and protocol records + * Move to the Protocol Count. + */ + data = &data[total_read]; + + /* + * We've validated up to 0x6 + len bytes, but we need to validate + * the next byte below, the count value. + */ + total_read++; + if (total_read > h->length) { + fprintf(stderr, "Total read length %d exceeds total structure length %d (handle 0x%04hx)\n", total_read, h->length, h->handle); + return; + } + + /* Get the protocol records count */ + count = data[0x0]; + if (count) { + u8 *rec = &data[0x1]; + for (i = 0; i < count; i++) { + /* + * Need to ensure that this record doesn't overrun + * the total length of the type 42 struct. Note the +2 + * is added for the two leading bytes of a protocol + * record representing the type and length bytes. + */ + total_read += rec[1] + 2; + if (total_read > h->length) { + fprintf(stderr, "Total read length %d exceeds total structure length %d (handle 0x%04hx, record %d)\n", total_read, h->length, h->handle, i + 1); + return; + } + + dmi_parse_protocol_record(data_n, rec); + + /* + * DSP0270: 8.6 + * Each record is rec[1] bytes long, starting at the + * data byte immediately following the length field. + * That means we need to add the byte for the rec id, + * the byte for the length field, and the value of the + * length field itself. + */ + rec += rec[1] + 2; + } + } +} + +/* + * 7.44 TPM Device (Type 43) + */ +void dmi_tpm_vendor_id(xmlNode *node, const u8 *p) +{ + + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *)"TpmVendorId", NULL); + assert(data_n != NULL); + dmixml_AddAttribute(data_n, "dmispec", "7.44"); + dmixml_AddAttribute(data_n, "flags", "0x%04x", p); + + char vendor_id[5]; + int i; + + /* ASCII filtering */ + for (i = 0; i < 4 && p[i] != 0; i++) { + if (p[i] < 32 || p[i] >= 127) + vendor_id[i] = '.'; + else + vendor_id[i] = p[i]; + } + + /* Terminate the string */ + vendor_id[i] = '\0'; + + dmixml_AddTextContent(data_n, "VendorId", "%s", vendor_id); +} + +void dmi_tpm_characteristics(xmlNode *node, u64 code) +{ + xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "TpmCharacteristics", NULL); + assert(data_n != NULL); + + /* 7.1.1 */ + static const char *characteristics[] = { + "TPM Device characteristics not supported", /* 2 */ + "Family configurable via firmware update", + "Family configurable via platform software support", + "Family configurable via OEM proprietary mechanism" /* 5 */ + }; + int i; + + /* + * This isn't very clear what this bit is supposed to mean + */ + if (code.l & (1 << 2)) { + dmixml_AddTextContent(data_n, "%s", characteristics[0]); + return data_n; + } + + for (i = 3; i <= 5; i++) + if (code.l & (1 << i)) { + xmlNode *dev_n = xmlNewChild(data_n, NULL, (xmlChar *) "Device", NULL); + dmixml_AddAttribute(dev_n, "index", "%i", i); + dmixml_AddTextContent(dev_n, "%s", characteristics[i - 2]); + dev_n = NULL; + } +} /******************************************************************************* ** Main @@ -4017,8 +4837,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmi_bios_runtime_size(sect_n, (0x10000 - WORD(data + 0x06)) << 4); } - sub_n = dmixml_AddTextChild(sect_n, "ROMsize", "%i", (data[0x09] + 1) << 6); - dmixml_AddAttribute(sub_n, "unit", "KB"); + dmi_bios_rom_size(sub_n, data[0x09], h->length < 0x1A ? 16 : WORD(data + 0x18)); sub_n = NULL; sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Characteristics", NULL); @@ -4352,8 +5171,16 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade 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)); + + if (h->length >= 0x1B) + dmi_cache_size_2(sect_n, "InstalledSize", DWORD(data + 0x17)); + else + dmi_cache_size(sect_n, "InstalledSize", WORD(data + 0x09)); + + if (h->length >= 0x17) + dmi_cache_size_2(sect_n, "Maximumsize", DWORD(data + 0x13)); + else + 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)); @@ -4407,6 +5234,19 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade } else { dmi_slot_characteristics(sect_n, data[0x0B], data[0x0C]); } + + if(h->length < 0x11){ + break; + } + dmi_slot_segment_bus_func(sub_n, WORD(data + 0x0D), data[0x0F], data[0x10]); + + if (h->length < 0x13){ + break; + } + dmixml_AddAttribute(sect_n, "Databuswidth", "%i", data[0x11]); + + if( h->length - 0x13 >= data[0x12] * 5) + dmi_slot_peers(sect_n, data[0x12], h, data+0x13); break; case 10: /* 7.11 On Board Devices Information */ @@ -4434,9 +5274,17 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade break; } + if (ver >= 0x0201){ + dmixml_AddAttribute(sect_n, "Language_description_format", "%s", + dmi_bios_language_format(data[0x05])); + } + dmixml_AddAttribute(sect_n, "installable_languages", "%i", data[0x04]); dmi_bios_languages(sect_n, h, data[0x05]); + + dmixml_AddAttribute(sect_n, "currently_installed_language", "%s", dmi_string(h, data[0x15])); + break; case 14: /* 7.15 Group Associations */ @@ -4487,7 +5335,6 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade // SysEventLog/Access/Header/Format - sub2_n dmi_event_log_header_type(sub2_n, data[0x14]); - sub2_n = NULL; sub_n = NULL; @@ -4519,7 +5366,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmi_memory_array_use(sect_n, data[0x05]); dmi_memory_array_ec_type(sect_n, data[0x06]); dmi_memory_array_capacity(sect_n, h, data); - dmi_memory_array_error_handle(sect_n, WORD(data + 0x0B)); + dmi_memory_array_error_handle(sect_n, WORD(data + 0x0D)); break; case 17: /* 7.18 Memory Device */ @@ -4646,16 +5493,28 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade break; } - dmixml_AddTextChild(sect_n, "StartAddress", "0x%08x%03x", - (DWORD(data + 0x04) >> 2), - (DWORD(data + 0x04) & 0x3) << 10); + if (h->length >= 0x23 && DWORD(data + 0x04) == 0xFFFFFFFF){ + u64 start, end; - dmixml_AddTextChild(sect_n, "EndAddress", "0x%08x%03x", - (DWORD(data + 0x08) >> 2), - ((DWORD(data + 0x08) & 0x3) << 10) + 0x3FF); + start = QWORD(data + 0x13); + end = QWORD(data + 0x1B); - dmi_mapped_address_size(sect_n, DWORD(data + 0x08) - DWORD(data + 0x04) + 1); + dmixml_AddTextChild(sect_n, "StartAddress", "0x%08X%08Xk", + start.h, start.l); + dmixml_AddTextChild(sect_n, "StartAddress", "0x%08X%08Xk", + end.h, end.l); + dmi_mapped_address_extended_size(sect_n, start, end); + } else { + 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)); @@ -4697,7 +5556,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmi_battery_chemistry(sect_n, data[0x09]); } - dmi_battery_capacity(sect_n, WORD(data + 0x0A), (h->length < 0x1A ? 1 : data[0x15])); + dmi_battery_capacity(sect_n, WORD(data + 0x0A), (h->length < 0x16 ? 1 : data[0x15])); dmi_battery_voltage(sect_n, WORD(data + 0x0C)); dmixml_AddDMIstring(sect_n, "SBDSversion", h, data[0x0E]); @@ -4889,7 +5748,14 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade break; case 31: /* 7.32 Boot Integrity Services Entry Point */ - dmixml_AddAttribute(sect_n, "NOT_IMPLEMENTED", "1"); + if(h->length < 0x1C){ + break; + } + + dmixml_AddAttribute(sect_n, "Checksum", "%s", checksum(data, h->length) ? "OK" : "Invalid"); + dmixml_AddAttribute(sect_n, "16BitEntryPointAddress", "%04X:%04X", + DWORD(data + 0x08) >> 16, DWORD(data + 0x08) & 0xFFFF); + dmixml_AddAttribute(sect_n, "32BitEntryPointAddress", "0x%08X", DWORD(data + 0x0C)); break; case 32: /* 7.33 System Boot Information */ @@ -5135,26 +6001,63 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade break; case 42: /* 7.43 Management Controller Host Interface */ - if (h->length < 0x05) { + if (ver < 0x0302){ + if (h->length < 0x05){ + break; + } + dmixml_AddAttribute(sect_n, "subtype", "InterfaceType"); + dmi_management_controller_host_type(sect_n, data[0x04]); + /* + * There you have a type-dependent, variable-length + * part in the middle of the structure, with no + * length specifier, so no easy way to decode the + * common, final part of the structure. What a pity. + */ + if (h->length < 0x09) { + break; + } + if (data[0x04] == 0xF0) { /* OEM */ + dmixml_AddAttribute(sect_n, "subtype", "VendorID"); + dmixml_AddTextContent(sect_n, "0x%02X%02X%02X%02X\n", + data[0x05], data[0x06], data[0x07], + data[0x08]); + } + sub_n = NULL; + } else { + dmi_parse_controller_structure(sect_n, h); + } + break; + case 43: + if (h->length < 0x1B){ break; } - - sub_n = dmi_management_controller_host_type(sect_n, data[0x04]); - /* - * There you have a type-dependent, variable-length - * part in the middle of the structure, with no - * length specifier, so no easy way to decode the - * common, final part of the structure. What a pity. - */ - if (h->length < 0x09) { + dmi_tpm_vendor_id(sect_n, data[0x04]); + switch (data[0x08]) { + case 0x01: + /* + * We skip the first 2 bytes, which are + * redundant with the above, and uncoded + * in a silly way. + */ + dmixml_AddTextContent(sect_n, "FirmwareRevision", "%u", data[0x0C]); + dmixml_AddTextContent(sect_n, "FirmwareRevision", "%u", data[0x0D]); + break; + case 0x02: + /* + * We skip the next 4 bytes, as their + * format is not standardized and their + * usefulness seems limited anyway. + */ + dmixml_AddTextContent(sect_n, "FirmwareRevision", "%i", DWORD(data + 0x0A) >> 16); + dmixml_AddTextContent(sect_n, "FirmwareRevision", "%i", DWORD(data + 0x0A) & 0xFFFF); break; } - if (data[0x04] == 0xF0) { /* OEM */ - dmixml_AddTextChild(sub_n, "VendorID", "0x%02X%02X%02X%02X\n", - data[0x05], data[0x06], data[0x07], - data[0x08]); + dmixml_AddDMIstring(sect_n, "Description", h, data[0x12]); + dmi_tpm_characteristics(sect_n, QWORD(data + 0x13)); + if (h->length < 0x1F){ + break; } - sub_n = NULL; + dmixml_AddAttribute(sect_n, "OEMSpecificInformation", "0x%08X", DWORD(data + 0x1B)); break; case 126: /* 7.43 Inactive */ case 127: /* 7.44 End Of Table */ @@ -5277,6 +6180,11 @@ static void dmi_table(Log_t *logp, int type, u32 base, u32 len, u16 num, u32 ver dmi_set_vendor(&h); } + /* Fixup a common mistake */ + if(h.type == 34){ + dmi_fixup_type_34(&h); + } + /* look for the next handle */ next = data + h.length; while(next - buf + 1 < len && (next[0] != 0 || next[1] != 0)) { diff --git a/src/dmidecode.h b/src/dmidecode.h index 22d70e1..8279b74 100644 --- a/src/dmidecode.h +++ b/src/dmidecode.h @@ -37,7 +37,8 @@ struct dmi_header { u8 *data; }; -void dmi_dump(xmlNode *node, struct dmi_header * h); +int is_printable(const u8 *data, int len); +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); diff --git a/src/pymap.xml b/src/pymap.xml index 7325a85..5ecc7eb 100644 --- a/src/pymap.xml +++ b/src/pymap.xml @@ -786,6 +786,9 @@ + + + From 2f4d895c32e7de1e1fba680aebdfc091c4ff835a Mon Sep 17 00:00:00 2001 From: Zhongze Hu Date: Sat, 22 Oct 2022 17:21:12 +0800 Subject: [PATCH 125/146] fix warning argument 1 null where non-null expected src/dmidecodemodule.c:154:27: Warning argument 1 null where non-null expected [-Wnonnull] 154 | } else if(memcmp(buf, "_SM_", 4) == 0) { | ^~~~~~~~~~~~~~~~~~~~~~ src/dmidecodemodule.c:158:27: Warning argument 1 null where non-null expected [-Wnonnull] 158 | } else if(memcmp(buf, "_DMI_", 5) == 0) { | ^~~~~~~~~~~~~~~~~~~~~~~ --- src/dmidecodemodule.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index d3ac7ff..7d3ba71 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -144,22 +144,24 @@ xmlNode *dmidecode_get_version(options *opt) if(opt->dumpfile != NULL) { //. printf("Reading SMBIOS/DMI data from file %s.\n", dumpfile); if((buf = mem_chunk(opt->logdata, 0, 0x20, opt->dumpfile)) != NULL) { - ver_n = NULL; - goto exit_free; - } - if(memcmp(buf, "_SM3_", 5) == 0){ - ver_n = smbios3_decode_get_version(buf, opt->dumpfile); - if ( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) - found++; - } else 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++; + if (memcmp(buf, "_SM3_", 5) == 0) { + ver_n = smbios3_decode_get_version(buf, opt->dumpfile); + if (dmixml_GetAttrValue(ver_n, "unknown") == NULL) + found++; + } else 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 { + ver_n = NULL; + goto exit_free; } + } /* From 5c2d56c901c86a27f6e86913892da17c983fda46 Mon Sep 17 00:00:00 2001 From: Zhongze Hu Date: Sat, 22 Oct 2022 17:25:59 +0800 Subject: [PATCH 126/146] fix warning: ignoring return value of 'legacy_decode' src/dmidump.c:157:1:warning: ignoring return value of 'legacy_decode' [-Wreturn-type] 157 | } | ^ --- src/dmidump.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dmidump.c b/src/dmidump.c index da0d676..07f24e9 100644 --- a/src/dmidump.c +++ b/src/dmidump.c @@ -154,6 +154,8 @@ static int legacy_decode(u8 *buf, const char *devmem, u32 flags, const char *du memcpy(crafted, buf, 16); overwrite_smbios3_address(crafted); write_dump(0, 0x0F, crafted, dumpfile, 1); + + return 1; } int dump(const char *memdev, const char *dumpfile) From 163fe6edce3d1c94ddbd1008325e634c9abf53ee Mon Sep 17 00:00:00 2001 From: Zhongze Hu Date: Sat, 22 Oct 2022 17:43:20 +0800 Subject: [PATCH 127/146] fix warning: comparison of integer expressions of different signedness src/util.c:225:76: warning: comparison of integer expressions of different signedness: 'long unsigned int' and '__off_t' {aka 'long int'} [-Wsign-compare] 225 | if (sigill_error || S_ISREG(statbuf.st_mode) && base + (off_t)len > statbuf.st_size ) | ^ src/util.c:225:55: warning: suggest parentheses around '&&' within '||' [-Wparentheses] 225 | if (sigill_error || S_ISREG(statbuf.st_mode) && base + (off_t)len > statbuf.st_size ) | --- src/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util.c b/src/util.c index 465376e..aabeafc 100644 --- a/src/util.c +++ b/src/util.c @@ -222,7 +222,7 @@ void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem) * mmap() will fail with SIGBUS if trying to map beyond the end of * the file. */ - if (sigill_error || S_ISREG(statbuf.st_mode) && base + (off_t)len > statbuf.st_size ) + if (sigill_error || S_ISREG(statbuf.st_mode) && (__off_t)(base + (off_t)len) > statbuf.st_size ) { log_append(logp, LOGFL_NORMAL, LOG_WARNING, "mmap: Can't map beyond end of file %s: %s", From 4b3d528afccdf5c64b5dccc2d3d488f7cfc75c0f Mon Sep 17 00:00:00 2001 From: Zhongze Hu Date: Sat, 22 Oct 2022 17:46:54 +0800 Subject: [PATCH 128/146] fix warning: suggest parentheses around '&&' within '||' src/util.c:225:55: warning: suggest parentheses around '&&' within '||' [-Wparentheses] 225 | if (sigill_error || S_ISREG(statbuf.st_mode) && (__off_t)(base + (off_t)len) > statbuf.st_size ) | --- src/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util.c b/src/util.c index aabeafc..7f61e55 100644 --- a/src/util.c +++ b/src/util.c @@ -222,7 +222,7 @@ void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem) * mmap() will fail with SIGBUS if trying to map beyond the end of * the file. */ - if (sigill_error || S_ISREG(statbuf.st_mode) && (__off_t)(base + (off_t)len) > statbuf.st_size ) + if ((sigill_error || S_ISREG(statbuf.st_mode)) && (__off_t)(base + (off_t)len) > statbuf.st_size ) { log_append(logp, LOGFL_NORMAL, LOG_WARNING, "mmap: Can't map beyond end of file %s: %s", From b9d8101a01ec629109e0da0574f6c91bad09ecf1 Mon Sep 17 00:00:00 2001 From: Zhongze Hu Date: Sat, 22 Oct 2022 17:50:53 +0800 Subject: [PATCH 129/146] fix warning: variable 'eptype' set but not used src/efi.c:52:21: warning: variable 'eptype' set but not used [-Wunused-but-set-variable] 52 | const char *eptype; | --- src/efi.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/efi.c b/src/efi.c index 362e2f9..901803e 100644 --- a/src/efi.c +++ b/src/efi.c @@ -83,6 +83,10 @@ int address_from_efi(Log_t *logp, size_t * address) log_append(logp, LOGFL_NODUPS, LOG_WARNING, "%s: SMBIOS entry point missing", filename); } + if(ret == 0){ + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "%s: entry point at 0x%08llx", eptype, (unsigned long long)*address); + } + return ret; } From 168cc81eb24f650959c28388397cfdb3f6864fc0 Mon Sep 17 00:00:00 2001 From: Zhongze Hu Date: Sat, 22 Oct 2022 17:59:45 +0800 Subject: [PATCH 130/146] fix warning: unused variable 'ver' src/dmidecode.c:6274:21: warning: unused variable 'ver' [-Wunused-variable] 6274 | u32 ver = (buf[0x07] << 16) + (buf[0x08] << 8) + buf[0x09]; | ^~~ --- src/dmidecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index 9d755a5..ce105f6 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -6271,7 +6271,7 @@ xmlNode *smbios3_decode_get_version(u8 * buf, const char *devmem) dmixml_AddAttribute(data_n, "type", "SMBIOS"); if(check == 1) { - u32 ver = (buf[0x07] << 16) + (buf[0x08] << 8) + buf[0x09]; + // u32 ver = (buf[0x07] << 16) + (buf[0x08] << 8) + buf[0x09]; dmixml_AddTextContent(data_n, "SMBIOS %i.%i.%i present", buf[0x07], buf[0x08], buf[0x09]); dmixml_AddAttribute(data_n, "version", "%i.%i.%i", buf[0x07], buf[0x08],buf[0x09]); } else if(check == 0) { From 369c9be943ea9427b61fc712034bc57b591687a5 Mon Sep 17 00:00:00 2001 From: Zhongze Hu Date: Sat, 22 Oct 2022 18:04:34 +0800 Subject: [PATCH 131/146] fix warning: passing argument 3 of 'dmi_slot_peers' from incompatible pointer type src/dmidecode.c:5248:60: warning: passing argument 3 of 'dmi_slot_peers' from incompatible pointer type [-Wincompatible-pointer-types] 5248 | dmi_slot_peers(sect_n, data[0x12], h, data+0x13); | ^ | | | struct dmi_header * src/dmidecode.c:2471:52: note: expected 'const u8 *' {aka 'const unsigned char *'} but argument is of type 'struct dmi_header *' 2471 | void dmi_slot_peers(xmlNode *node, u8 n, const u8 *data, struct dmi_header *h) | ~~~~~~~~~~^~~~ src/dmidecode.c:5248:67: warning: passing argument 4 of 'dmi_slot_peers' from incompatible pointer type [-Wincompatible-pointer-types] 5248 | dmi_slot_peers(sect_n, data[0x12], h, data+0x13); | ~~~~^~~~~ | | | const u8 * {aka const unsigned char *} src/dmidecode.c:2471:77: note: expected 'struct dmi_header *' but argument is of type 'const u8 *' {aka 'const unsigned char *'} 2471 | void dmi_slot_peers(xmlNode *node, u8 n, const u8 *data, struct dmi_header *h) --- src/dmidecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index ce105f6..2c1f45e 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -5245,7 +5245,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmixml_AddAttribute(sect_n, "Databuswidth", "%i", data[0x11]); if( h->length - 0x13 >= data[0x12] * 5) - dmi_slot_peers(sect_n, data[0x12], h, data+0x13); + dmi_slot_peers(sect_n, data[0x12], data+0x13, h); break; case 10: /* 7.11 On Board Devices Information */ From e438d9134450ebcdf4359a2bf17bf3ddad45d78e Mon Sep 17 00:00:00 2001 From: Zhongze Hu Date: Sat, 22 Oct 2022 18:10:57 +0800 Subject: [PATCH 132/146] src/dmidecode.c: In function 'dmi_tpm_characteristics': src/dmidecode.c:4788:24: warning: 'return' with a value, in function returning void [-Wreturn-type] 4788 | return data_n; | ^~~~~~ --- src/dmidecode.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index 2c1f45e..555dc7a 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -4785,7 +4785,6 @@ void dmi_tpm_characteristics(xmlNode *node, u64 code) */ if (code.l & (1 << 2)) { dmixml_AddTextContent(data_n, "%s", characteristics[0]); - return data_n; } for (i = 3; i <= 5; i++) From 2e29bf2aa195b58c5a6e5e9cdbaaf2b27dd9e5da Mon Sep 17 00:00:00 2001 From: Zhongze Hu Date: Sat, 22 Oct 2022 18:15:06 +0800 Subject: [PATCH 133/146] fix warning: suggest parentheses around assignment used as truth value src/dmidecodemodule.c:350:12: warning: suggest parentheses around assignment used as truth value [-Wparentheses] 350 | if(buf = mem_chunk(opt->logdata, fp, 0x20, opt->devmem) == NULL ){ | ^~~ --- src/dmidecodemodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 7d3ba71..932e5a5 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -347,7 +347,7 @@ int dmidecode_get_xml(options *opt, xmlNode* dmixml_n) goto exit_free; } - if(buf = mem_chunk(opt->logdata, fp, 0x20, opt->devmem) == NULL ){ + if((buf = mem_chunk(opt->logdata, fp, 0x20, opt->devmem)) == NULL ){ ret = 1; goto exit_free; } From ddc6e0da1d2da885e3b918f74ffebc05393b9631 Mon Sep 17 00:00:00 2001 From: Zhongze Hu Date: Sat, 22 Oct 2022 18:16:21 +0800 Subject: [PATCH 134/146] fix warning: suggest parentheses around assignment used as truth value src/dmidecodemodule.c:206:12: warning: suggest parentheses around assignment used as truth value [-Wparentheses] 206 | if(buf = mem_chunk(opt->logdata, fp, 0x20, opt->devmem) == NULL){ | ^~~ --- src/dmidecodemodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 932e5a5..0da3baf 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -203,7 +203,7 @@ xmlNode *dmidecode_get_version(options *opt) goto exit_free; } - if(buf = mem_chunk(opt->logdata, fp, 0x20, opt->devmem) == NULL){ + if((buf = mem_chunk(opt->logdata, fp, 0x20, opt->devmem)) == NULL){ ver_n = NULL; goto exit_free; } From 4c547ef8b025cb48eef5267c3381fe1a702756b1 Mon Sep 17 00:00:00 2001 From: Zhongze Hu Date: Sat, 22 Oct 2022 18:26:46 +0800 Subject: [PATCH 135/146] fix warning: unused variable 'addrstr' src/dmidecode.c:4446:21: warning: unused variable 'addrstr' [-Wunused-variable] 4446 | const char *addrstr; | ^~~~~~~ --- src/dmidecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index 555dc7a..ebcd608 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -4443,7 +4443,7 @@ void dmi_parse_protocol_record(xmlNode *node, u8 *rec) u8 assign_val; u8 addrtype; u8 hlen; - const char *addrstr; + // const char *addrstr; const char *hname; char attr[38]; From 6e24d9be5b93201cf09fa8a78a8f8d05ec4ee8cd Mon Sep 17 00:00:00 2001 From: Zhongze Hu Date: Sat, 22 Oct 2022 18:33:39 +0800 Subject: [PATCH 136/146] fix warning: unused variable 'attr' src/dmidecode.c: In function 'dmi_parse_protocol_record': src/dmidecode.c:4448:14: warning: unused variable 'attr' [-Wunused-variable] 4448 | char attr[38]; | ^~~~ --- src/dmidecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index ebcd608..49313f8 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -4445,7 +4445,7 @@ void dmi_parse_protocol_record(xmlNode *node, u8 *rec) u8 hlen; // const char *addrstr; const char *hname; - char attr[38]; + // char attr[38]; /* DSP0270: 8.5: Protocol Identifier */ rid = rec[0x0]; From d52d234893ac6a8587ce0711a2c9d33d14bdd2f1 Mon Sep 17 00:00:00 2001 From: Zhongze Hu Date: Sat, 22 Oct 2022 18:35:58 +0800 Subject: [PATCH 137/146] fix warning: passing argument 2 of 'dmi_tpm_vendor_id' makes pointer from integer without a cast src/dmidecode.c: In function 'dmi_decode': src/dmidecode.c:6032:47: warning: passing argument 2 of 'dmi_tpm_vendor_id' makes pointer from integer without a cast [-Wint-conversion] 6032 | dmi_tpm_vendor_id(sect_n, data[0x04]); | ~~~~^~~~~~ | | | u8 {aka unsigned char} --- src/dmidecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index 49313f8..64680e2 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -6029,7 +6029,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade if (h->length < 0x1B){ break; } - dmi_tpm_vendor_id(sect_n, data[0x04]); + dmi_tpm_vendor_id(sect_n, data + 0x04); switch (data[0x08]) { case 0x01: /* From a8755eaa5bf3e0d240aa2247570b1d08763768b3 Mon Sep 17 00:00:00 2001 From: Zhongze Hu Date: Sat, 22 Oct 2022 18:40:23 +0800 Subject: [PATCH 138/146] fix warning: variable 'str_n' set but not used src/dmidecode.c: In function 'dmi_additional_info': src/dmidecode.c:4262:42: warning: variable 'str_n' set but not used [-Wunused-but-set-variable] 4262 | xmlNode *data_n = NULL, *str_n = NULL, *val_n = NULL; | ^~~~~ --- src/dmidecode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index 64680e2..d297bb6 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -4259,7 +4259,7 @@ void dmi_additional_info(xmlNode *node, const struct dmi_header *h) assert( node != NULL ); for(i = 0; i < count; i++) { - xmlNode *data_n = NULL, *str_n = NULL, *val_n = NULL; + xmlNode *data_n = NULL, *val_n = NULL; /* Check for short entries */ if(h->length < offset + 1) { @@ -4277,7 +4277,7 @@ void dmi_additional_info(xmlNode *node, const struct dmi_header *h) dmixml_AddAttribute(data_n, "ReferenceHandle", "0x%04x", WORD(p + 0x01)); dmixml_AddAttribute(data_n, "ReferenceOffset", "0x%02x", p[0x03]); - str_n = dmixml_AddDMIstring(data_n, "String", h, p[0x04]); + dmixml_AddDMIstring(data_n, "String", h, p[0x04]); switch (length - 0x05) { case 1: From b76eadfc067a9a2fea9d7425de96e758c0b16111 Mon Sep 17 00:00:00 2001 From: Zhongze Hu Date: Sat, 22 Oct 2022 18:41:44 +0800 Subject: [PATCH 139/146] fix warning: this 'if' clause does not guard src/dmidecodemodule.c: In function 'dmidecode_get_xml': src/dmidecodemodule.c:394:25: warning: this 'if' clause does not guard... [-Wmisleading-indentation] 394 | if(legacy_decode(opt->logdata, opt->type, | ^~ src/dmidecodemodule.c:397:33: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if' 397 | goto done; | ^~~~ --- src/dmidecodemodule.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 0da3baf..efa730b 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -392,9 +392,10 @@ int dmidecode_get_xml(options *opt, xmlNode* dmixml_n) } } else if(memcmp(buf + fp, "_DMI_", 5) == 0) { if(legacy_decode(opt->logdata, opt->type, - buf + fp, opt->devmem, 0, dmixml_n)) + buf + fp, opt->devmem, 0, dmixml_n)) { found++; goto done; + } } } #endif From d682a1226e1d0ba60ac4a528dd888ba3db2eb3b9 Mon Sep 17 00:00:00 2001 From: Zhongze Hu Date: Mon, 24 Oct 2022 14:29:39 +0800 Subject: [PATCH 140/146] fix function dmi_slot_segment_bus_func null point error in system slot Case 13(System Slot): function dmi_slot_segment_bus_func may cause core dump error by null point sub_n. --- src/dmidecode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index d297bb6..7fb1c89 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -5236,7 +5236,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade if(h->length < 0x11){ break; } - dmi_slot_segment_bus_func(sub_n, WORD(data + 0x0D), data[0x0F], data[0x10]); + dmi_slot_segment_bus_func(sect_n, WORD(data + 0x0D), data[0x0F], data[0x10]); if (h->length < 0x13){ break; From 5fdcb2b432d812ffdd4a9c8d60087561b4e305f8 Mon Sep 17 00:00:00 2001 From: Zhongze Hu Date: Wed, 26 Oct 2022 11:30:46 +0800 Subject: [PATCH 141/146] fix address_from_efi ret=0 message change LOG_WARNING level into LOG_DEBUG --- src/efi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/efi.c b/src/efi.c index 901803e..e519257 100644 --- a/src/efi.c +++ b/src/efi.c @@ -84,7 +84,7 @@ int address_from_efi(Log_t *logp, size_t * address) } if(ret == 0){ - log_append(logp, LOGFL_NODUPS, LOG_WARNING, "%s: entry point at 0x%08llx", eptype, (unsigned long long)*address); + log_append(logp, LOGFL_NODUPS, LOG_DEBUG, "%s: entry point at 0x%08llx", eptype, (unsigned long long)*address); } return ret; From 50e959317d627ed3b6bfa762d3f558e70bd19058 Mon Sep 17 00:00:00 2001 From: Zhongze Hu Date: Wed, 16 Nov 2022 23:59:20 +0800 Subject: [PATCH 142/146] Add bus address for type 09 in pymap.xml The bus address should be added to pymap.xml, otherwise the python interface will not know about it. Signed-off-by: Zhongze Hu --- src/pymap.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pymap.xml b/src/pymap.xml index 5ecc7eb..d021d00 100644 --- a/src/pymap.xml +++ b/src/pymap.xml @@ -304,6 +304,7 @@ + From a6c522c4b5a88b6053e5ef0e429a1c7df5bc1bde Mon Sep 17 00:00:00 2001 From: Zhongze Hu Date: Thu, 17 Nov 2022 00:02:27 +0800 Subject: [PATCH 143/146] Solve dmi_memory_device_extended_size WORD issue In case 17: dmi_memory_device_extended_size(sect_n, WORD(data + 0x1C)); may cause memory capcity read error. This because WORD and DWORD have different byte size, the DWORD is double long of WORD. After SMBIOS v2.8.0, the structures assume to be little-endian order. So redefine the WORD and DWORD in types.h. Signed-off-by: Zhongze Hu --- src/dmidecode.c | 2 +- src/types.h | 22 ++++++++++------------ 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index 7fb1c89..d1a10c1 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -5378,7 +5378,7 @@ xmlNode *dmi_decode(xmlNode *prnt_n, dmi_codes_major *dmiMajor, struct dmi_heade dmi_memory_device_width(sect_n, "TotalWidth", WORD(data + 0x08)); dmi_memory_device_width(sect_n, "DataWidth", WORD(data + 0x0A)); if (h->length >= 0x20 && WORD(data + 0x0C) == 0x7FFF) { - dmi_memory_device_extended_size(sect_n, WORD(data + 0x1C)); + dmi_memory_device_extended_size(sect_n, DWORD(data + 0x1C)); } else { dmi_memory_device_size(sect_n, WORD(data + 0x0C)); } diff --git a/src/types.h b/src/types.h index 5f3dcd4..2570c7c 100644 --- a/src/types.h +++ b/src/types.h @@ -69,20 +69,18 @@ static inline u64 U64(u32 low, u32 high) } #endif -#ifdef ALIGNMENT_WORKAROUND -# ifdef BIGENDIAN -# define WORD(x) (u16)((x)[1]+((x)[0]<<8)) -# define DWORD(x) (u32)((x)[3]+((x)[2]<<8)+((x)[1]<<16)+((x)[0]<<24)) -# define QWORD(x) (U64(DWORD(x+4), DWORD(x))) -# else /* BIGENDIAN */ -# define WORD(x) (u16)((x)[0]+((x)[1]<<8)) -# define DWORD(x) (u32)((x)[0]+((x)[1]<<8)+((x)[2]<<16)+((x)[3]<<24)) -# define QWORD(x) (U64(DWORD(x), DWORD(x+4))) -# endif /* BIGENDIAN */ -#else /* ALIGNMENT_WORKAROUND */ +/* + * Per SMBIOS v2.8.0 and later, all structures assume a little-endian + * ordering convention. + */ +#if defined(ALIGNMENT_WORKAROUND) || defined(BIGENDIAN) +#define WORD(x) (u16)((x)[0] + ((x)[1] << 8)) +#define DWORD(x) (u32)((x)[0] + ((x)[1] << 8) + ((x)[2] << 16) + ((x)[3] << 24)) +#define QWORD(x) (U64(DWORD(x), DWORD(x + 4))) +#else /* ALIGNMENT_WORKAROUND || BIGENDIAN */ #define WORD(x) (u16)(*(const u16 *)(x)) #define DWORD(x) (u32)(*(const u32 *)(x)) #define QWORD(x) (*(const u64 *)(x)) -#endif /* ALIGNMENT_WORKAROUND */ +#endif /* ALIGNMENT_WORKAROUND || BIGENDIAN */ #endif From 9456ca94685e5666569feba02fabc4711550ee3b Mon Sep 17 00:00:00 2001 From: Zhongze Hu Date: Thu, 17 Nov 2022 12:58:22 +0800 Subject: [PATCH 144/146] Add defined BIGENDIAN in types.h Since ALIGNMENT_WORKAROUND and BIGENDIAN are merged into one if macro in the new line 76, BIGENDIAN should also be added in line 60's ifdef macro, otherwise U64 will be undefined when only BIGENDIAN is defined. Signed-off-by: Zhongze Hu --- src/types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types.h b/src/types.h index 2570c7c..218f31a 100644 --- a/src/types.h +++ b/src/types.h @@ -57,7 +57,7 @@ typedef struct { } u64; #endif -#ifdef ALIGNMENT_WORKAROUND +#if defined(ALIGNMENT_WORKAROUND) || defined(BIGENDIAN) static inline u64 U64(u32 low, u32 high) { u64 self; From 48618016d85d0890e1675b9e7bee18ee0bc63712 Mon Sep 17 00:00:00 2001 From: Lianbo Jiang Date: Fri, 18 Nov 2022 10:12:42 +0800 Subject: [PATCH 145/146] v3.12.3 Signed-off-by: Lianbo Jiang --- contrib/python-dmidecode.spec | 5 ++++- src/version.h | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/contrib/python-dmidecode.spec b/contrib/python-dmidecode.spec index 2c74597..2c7f942 100644 --- a/contrib/python-dmidecode.spec +++ b/contrib/python-dmidecode.spec @@ -3,7 +3,7 @@ Summary: Python module to access DMI data Name: python-dmidecode -Version: 3.12.2 +Version: 3.12.3 Release: 1%{?dist} License: GPLv2 Group: System Environment/Libraries @@ -49,6 +49,9 @@ rm -rf $RPM_BUILD_ROOT %{_datadir}/python-dmidecode/ %changelog +* Thu Nov 17 2022 Lianbo Jiang - 3.12.3-1 +- Update to new release + * Mon Jun 08 2015 Nima Talebi - 3.12.2-1 - Update to new release diff --git a/src/version.h b/src/version.h index 9938205..68d060d 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define VERSION "3.12.2" +#define VERSION "3.12.3" From c217e2bd9dfbd23c04dac19759a2d59845fcd6f6 Mon Sep 17 00:00:00 2001 From: Lichen Liu Date: Mon, 6 Feb 2023 14:46:47 +0800 Subject: [PATCH 146/146] Fix dmi_cache_size_2 will add unit twice. Signed-off-by: Lichen Liu --- src/dmidecode.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index d1a10c1..d40f0ee 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -1843,8 +1843,6 @@ void dmi_cache_size_2(xmlNode *node, const char *tagname, u32 code) size.l = code << 6; size.h = code >> 26; } else { - dmixml_AddAttribute(caches_n, "unit", "KB"); - dmixml_AddTextContent(caches_n, "%i", code); size.l = code; size.h = 0; }