diff options
-rw-r--r-- | src/dmidecode.c | 11 | ||||
-rw-r--r-- | src/dmidecode.h | 4 | ||||
-rw-r--r-- | src/dmidecodemodule.c | 198 | ||||
-rw-r--r-- | src/dmidecodemodule.h | 31 | ||||
-rw-r--r-- | src/dmihelper.h | 2 |
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; |