summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/dmidecode.c11
-rw-r--r--src/dmidecode.h4
-rw-r--r--src/dmidecodemodule.c198
-rw-r--r--src/dmidecodemodule.h31
-rw-r--r--src/dmihelper.h2
5 files changed, 135 insertions, 111 deletions
diff --git a/src/dmidecode.c b/src/dmidecode.c
index d55a697..0fca9c9 100644
--- a/src/dmidecode.c
+++ b/src/dmidecode.c
@@ -90,6 +90,7 @@
#define EFI_NOT_FOUND (-1)
#define EFI_NO_SMBIOS (-2)
+
/*******************************************************************************
** Type-independant Stuff
*/
@@ -4950,13 +4951,13 @@ int dump(const char *dumpfile)
return ret == 0 ? found : ret;
}
-static void dmi_table(u8 *type, u32 base, u16 len, u16 num, u16 ver, const char *devmem, xmlNode *xmlnode)
+static void dmi_table(int type, u32 base, u16 len, u16 num, u16 ver, const char *devmem, xmlNode *xmlnode)
{
u8 *buf;
u8 *data;
int i = 0;
- if(type == NULL) {
+ if( type == -1 ) {
xmlNode *info_n = NULL;
info_n = dmixml_AddTextChild(xmlnode, "DMIinfo", "%i structures occupying %i bytes", num, len);
@@ -5018,7 +5019,7 @@ static void dmi_table(u8 *type, u32 base, u16 len, u16 num, u16 ver, const char
next += 2;
xmlNode *handle_n = NULL;
- if( type == NULL || type[h.type] ) { // FIXME: Is this check correct?
+ if( h.type == type ) {
if(next - buf <= len) {
/* TODO: ...
* if(opt->flags & FLAG_DUMP) {
@@ -5106,7 +5107,7 @@ xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem)
return data_n;
}
-int smbios_decode(u8 *type, u8 *buf, const char *devmem, xmlNode *xmlnode)
+int smbios_decode(int type, u8 *buf, const char *devmem, xmlNode *xmlnode)
{
int check = _smbios_decode_check(buf);
@@ -5161,7 +5162,7 @@ xmlNode *legacy_decode_get_version(u8 * buf, const char *devmem)
return data_n;
}
-int legacy_decode(u8 *type, u8 *buf, const char *devmem, xmlNode *xmlnode)
+int legacy_decode(int type, u8 *buf, const char *devmem, xmlNode *xmlnode)
{
int check = _legacy_decode_check(buf);
diff --git a/src/dmidecode.h b/src/dmidecode.h
index cd6b8a6..f0cb1ab 100644
--- a/src/dmidecode.h
+++ b/src/dmidecode.h
@@ -36,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(u8 *type, u8 *buf, const char *devmem, xmlNode *xmlnode);
-int legacy_decode(u8 *type, u8 *buf, const char *devmem, xmlNode *xmlnode);
+int smbios_decode(int type, u8 *buf, const char *devmem, xmlNode *xmlnode);
+int legacy_decode(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.c b/src/dmidecodemodule.c
index e551d67..161e1b7 100644
--- a/src/dmidecodemodule.c
+++ b/src/dmidecodemodule.c
@@ -57,59 +57,36 @@ static void init(options *opt)
opt->devmem = DEFAULT_MEM_DEV;
opt->dumpfile = NULL;
opt->flags = 0;
- opt->type = NULL;
+ opt->type = -1;
opt->dmiversion_n = NULL;
opt->mappingxml = NULL;
opt->python_xml_map = strdup(PYTHON_XML_MAP);
}
-u8 *parse_opt_type(u8 * p, const char *arg)
+int parse_opt_type(const char *arg)
{
-
- /* Allocate memory on first call only */
- if(p == NULL) {
- if(!(p = (u8 *) calloc(256, sizeof(u8)))) {
- perror("calloc");
- return NULL;
- }
- }
-
- unsigned int i, j;
-
- /* First try as a keyword */
- for(i = 0; i < ARRAY_SIZE(opt_type_keyword); i++) {
- if(!strcasecmp(arg, opt_type_keyword[i].keyword)) {
- j = 0;
- while(opt_type_keyword[i].type[j] != 255)
- p[opt_type_keyword[i].type[j++]] = 1;
- return p;
- }
- }
-
- /* Else try as a number */
while(*arg != '\0') {
- unsigned long val;
+ int val;
char *next;
val = strtoul(arg, &next, 0);
if(next == arg) {
fprintf(stderr, "Invalid type keyword: %s\n", arg);
- free(p);
- return NULL;
+ return -1;
}
if(val > 0xff) {
- fprintf(stderr, "Invalid type number: %lu\n", val);
- free(p);
- return NULL;
+ fprintf(stderr, "Invalid type number: %i\n", val);
+ return -1;
}
- p[val] = 1;
+ if( val >= 0 ) {
+ return val;
+ }
arg = next;
while(*arg == ',' || *arg == ' ')
arg++;
}
-
- return p;
+ return -1;
}
@@ -182,9 +159,6 @@ xmlNode *dmidecode_get_version(options *opt)
if( !found ) {
fprintf(stderr, "No SMBIOS nor DMI entry point found, sorry.");
}
- if( opt->type != NULL ) {
- free(opt->type);
- }
return ver_n;
}
@@ -249,9 +223,6 @@ int dmidecode_get_xml(options *opt, xmlNode* dmixml_n)
// TODO: dmixml_AddAttribute(dmixml_n, "efi_address", "0x%08x", efiAddress);
}
}
- if( opt->type != NULL ) {
- free(opt->type);
- }
if(ret == 0) {
free(buf);
}
@@ -259,22 +230,41 @@ int dmidecode_get_xml(options *opt, xmlNode* dmixml_n)
return ret;
}
-static PyObject *dmidecode_get(options *opt, const char *section)
+xmlNode* load_mappingxml(options *opt) {
+ xmlNode *group_n = NULL;
+
+ if( opt->mappingxml == NULL ) {
+ // Load mapping into memory
+ opt->mappingxml = xmlReadFile(opt->python_xml_map, NULL, 0);
+ if( opt->mappingxml == NULL ) {
+ PyErr_SetString(PyExc_SystemError, "Could not open XML mapping file\n");
+ assert( opt->mappingxml != NULL );
+ return 1;
+ }
+ }
+
+
+ if( (group_n = dmiMAP_GetRootElement(opt->mappingxml)) == NULL ) {
+ PyErr_SetString(PyExc_SystemError, "Invalid XML mapping file\n");
+ assert( group_n != NULL );
+ return NULL;
+ }
+
+ return group_n;
+}
+
+static PyObject *dmidecode_get_group(options *opt, const char *section)
{
PyObject *pydata = NULL;
xmlNode *dmixml_n = NULL;
+ xmlNode *group_n = NULL;
+ ptzMAP *mapping = NULL;
/* Set default option values */
if( opt->devmem == NULL ) {
opt->devmem = DEFAULT_MEM_DEV;
}
opt->flags = 0;
- opt->type = NULL;
- opt->type = parse_opt_type(opt->type, section);
-
- if(opt->type == NULL) {
- return NULL;
- }
dmixml_n = xmlNewNode(NULL, (xmlChar *) "dmidecode");
assert( dmixml_n != NULL );
@@ -283,79 +273,136 @@ static PyObject *dmidecode_get(options *opt, const char *section)
xmlAddChild(dmixml_n, xmlCopyNode(opt->dmiversion_n, 1));
}
- if(dmidecode_get_xml(opt, dmixml_n) == 0) {
- ptzMAP *mapping = NULL;
+ // Fetch the Mapping XML file
+ if( (group_n = load_mappingxml(opt)) == NULL) {
+ return NULL;
+ }
- // Convert the retrieved XML nodes to Python dicts
- if( opt->mappingxml == NULL ) {
- // Load mapping into memory
- opt->mappingxml = xmlReadFile(opt->python_xml_map, NULL, 0);
- assert( opt->mappingxml != NULL );
+ // Find the section in the XML containing the group mappings
+ if( (group_n = dmixml_FindNode(group_n, "GroupMapping")) == NULL ) {
+ PyErr_SetString(PyExc_SystemError,
+ "Could not find the GroupMapping section in the XML mapping\n");
+ assert( group_n != NULL );
+ return NULL;
+ }
+
+ // Find the XML node containing the Mapping section requested to be decoded
+ if( (group_n = dmixml_FindNodeByAttr(group_n, "Mapping", "name", section)) == NULL ) {
+ PyErr_SetString(PyExc_SystemError,
+ "Could not find the given Mapping section in the XML mapping\n");
+ assert( group_n != NULL );
+ return NULL;
+ }
+
+ if( group_n->children == NULL ) {
+ PyErr_SetString(PyExc_SystemError,
+ "Mapping is empty for the given section in the XML mapping\n");
+ assert( group_n->children != NULL );
+ return NULL;
+ }
+
+ // Go through all TypeMap's belonging to this Mapping section
+ foreach_xmlnode(dmixml_FindNode(group_n, "TypeMap"), group_n) {
+ char *typeid = dmixml_GetAttrValue(group_n, "id");
+
+ if( group_n->type != XML_ELEMENT_NODE ) {
+ continue;
}
- mapping = dmiMAP_ParseMappingXML_GroupName(opt->mappingxml, section);
- if( mapping == NULL ) {
+ // The children of <Mapping> tags must only be <TypeMap> and
+ // they must have an 'id' attribute
+ if( (typeid == NULL) || (xmlStrcmp(group_n->name, (xmlChar *) "TypeMap") != 0) ) {
+ PyErr_SetString(PyExc_SystemError,
+ "Invalid Mapping node in mapping XML\n");
return NULL;
}
- // Generate Python dict out of XML node
- pydata = pythonizeXMLnode(mapping, dmixml_n);
+ // Parse the typeid string to a an integer
+ opt->type = parse_opt_type(typeid);
+ if(opt->type == -1) {
+ PyErr_SetString(PyExc_SystemError, "Unexpected: opt->type is -1");
+ return NULL;
+ }
+ // Parse the DMI data and put the result into dmixml_n node chain.
+ if( dmidecode_get_xml(opt, dmixml_n) != 0 ) {
+ PyErr_SetString(PyExc_SystemError,
+ "Error decoding DMI data\n");
+ return NULL;
+ }
+ }
#if 0 // DEBUG - will dump generated XML to stdout
- xmlDoc *doc = xmlNewDoc((xmlChar *) "1.0");
- xmlDocSetRootElement(doc, xmlCopyNode(dmixml_n, 1));
- xmlSaveFormatFileEnc("-", doc, "UTF-8", 1);
- xmlFreeDoc(doc);
+ xmlDoc *doc = xmlNewDoc((xmlChar *) "1.0");
+ xmlDocSetRootElement(doc, xmlCopyNode(dmixml_n, 1));
+ xmlSaveFormatFileEnc("-", doc, "UTF-8", 1);
+ xmlFreeDoc(doc);
#endif
- ptzmap_Free(mapping);
- xmlFreeNode(dmixml_n);
- } else {
+
+ // Convert the retrieved XML nodes to a Python dictionary
+ mapping = dmiMAP_ParseMappingXML_GroupName(opt->mappingxml, section);
+ if( mapping == NULL ) {
return NULL;
}
+ // Generate Python dict out of XML node
+ pydata = pythonizeXMLnode(mapping, dmixml_n);
+ if( pydata == NULL ) {
+ PyErr_SetString(PyExc_SystemError,
+ "Error converting XML to Python data.\n");
+ }
+
+ // Clean up and return the resulting Python dictionary
+ ptzmap_Free(mapping);
+ xmlFreeNode(dmixml_n);
+
return pydata;
}
+static PyObject *dmidecode_get_typeid(options *opt, const char *section) {
+ return NULL;
+}
+
+
// This global variable should only be available for the "first-entry" functions
// which is defined in PyMethodDef DMIDataMethods[].
options *global_options = NULL;
static PyObject *dmidecode_get_bios(PyObject * self, PyObject * args)
{
- return dmidecode_get(global_options, "bios");
+ return dmidecode_get_group(global_options, "bios");
}
static PyObject *dmidecode_get_system(PyObject * self, PyObject * args)
{
- return dmidecode_get(global_options, "system");
+ return dmidecode_get_group(global_options, "system");
}
static PyObject *dmidecode_get_baseboard(PyObject * self, PyObject * args)
{
- return dmidecode_get(global_options, "baseboard");
+ return dmidecode_get_group(global_options, "baseboard");
}
static PyObject *dmidecode_get_chassis(PyObject * self, PyObject * args)
{
- return dmidecode_get(global_options, "chassis");
+ return dmidecode_get_group(global_options, "chassis");
}
static PyObject *dmidecode_get_processor(PyObject * self, PyObject * args)
{
- return dmidecode_get(global_options, "processor");
+ return dmidecode_get_group(global_options, "processor");
}
static PyObject *dmidecode_get_memory(PyObject * self, PyObject * args)
{
- return dmidecode_get(global_options, "memory");
+ return dmidecode_get_group(global_options, "memory");
}
static PyObject *dmidecode_get_cache(PyObject * self, PyObject * args)
{
- return dmidecode_get(global_options, "cache");
+ return dmidecode_get_group(global_options, "cache");
}
static PyObject *dmidecode_get_connector(PyObject * self, PyObject * args)
{
- return dmidecode_get(global_options, "connector");
+ return dmidecode_get_group(global_options, "connector");
}
static PyObject *dmidecode_get_slot(PyObject * self, PyObject * args)
{
- return dmidecode_get(global_options, "slot");
+ return dmidecode_get_group(global_options, "slot");
}
static PyObject *dmidecode_get_type(PyObject * self, PyObject * args)
{
@@ -367,7 +414,7 @@ static PyObject *dmidecode_get_type(PyObject * self, PyObject * args)
if(lu < 256) {
char s[8];
sprintf(s, "%lu", lu);
- return dmidecode_get(global_options, s);
+ return dmidecode_get_typeid(global_options, s);
}
e = 1;
//return Py_False;
@@ -516,6 +563,9 @@ PyMODINIT_FUNC initdmidecode(void)
PyObject *version = NULL;
options *opt;
+ xmlInitParser();
+ xmlXPathInit();
+
opt = (options *) malloc(sizeof(options)+2);
memset(opt, 0, sizeof(options)+2);
init(opt);
diff --git a/src/dmidecodemodule.h b/src/dmidecodemodule.h
index ea5e36e..9699e82 100644
--- a/src/dmidecodemodule.h
+++ b/src/dmidecodemodule.h
@@ -28,37 +28,10 @@ extern void dmi_dump(xmlNode *node, struct dmi_header *h);
extern xmlNode *dmi_decode(xmlNode *parent_n, struct dmi_header * h, u16 ver);
extern int address_from_efi(size_t * address);
extern void to_dmi_header(struct dmi_header *h, u8 * data);
-extern int smbios_decode(u8 *type, u8 *buf, const char *devmem, xmlNode *node);
-extern int legacy_decode(u8 *type, u8 *buf, const char *devmem, xmlNode *node);
+extern int smbios_decode(int type, u8 *buf, const char *devmem, xmlNode *node);
+extern int legacy_decode(int type, u8 *buf, const char *devmem, xmlNode *node);
extern xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem);
extern xmlNode *legacy_decode_get_version(u8 * buf, const char *devmem);
extern void *mem_chunk(size_t base, size_t len, const char *devmem);
-extern u8 *parse_opt_type(u8 * p, const char *arg);
-static const u8 opt_type_bios[] = { 0, 13, 255 };
-static const u8 opt_type_system[] = { 1, 12, 15, 23, 32, 255 };
-static const u8 opt_type_baseboard[] = { 2, 10, 255 };
-static const u8 opt_type_chassis[] = { 3, 255 };
-static const u8 opt_type_processor[] = { 4, 255 };
-static const u8 opt_type_memory[] = { 5, 6, 16, 17, 255 };
-static const u8 opt_type_cache[] = { 7, 255 };
-static const u8 opt_type_connector[] = { 8, 255 };
-static const u8 opt_type_slot[] = { 9, 255 };
-struct type_keyword {
- const char *keyword;
- const u8 *type;
-};
-
-static const struct type_keyword opt_type_keyword[] = {
- {"bios", opt_type_bios},
- {"system", opt_type_system},
- {"baseboard", opt_type_baseboard},
- {"chassis", opt_type_chassis},
- {"processor", opt_type_processor},
- {"memory", opt_type_memory},
- {"cache", opt_type_cache},
- {"connector", opt_type_connector},
- {"slot", opt_type_slot},
-};
-
PyMODINIT_FUNC initdmidecode(void);
diff --git a/src/dmihelper.h b/src/dmihelper.h
index b0816b7..6607dc5 100644
--- a/src/dmihelper.h
+++ b/src/dmihelper.h
@@ -82,7 +82,7 @@ typedef struct _dmi_minor {
typedef struct _options {
const char *devmem;
unsigned int flags;
- u8 *type;
+ int type;
xmlDoc *mappingxml;
char *python_xml_map;
xmlNode *dmiversion_n;