diff options
Diffstat (limited to 'src/dmidecodemodule.c')
-rw-r--r-- | src/dmidecodemodule.c | 198 |
1 files changed, 124 insertions, 74 deletions
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); |