diff options
author | David Sommerseth <davids@redhat.com> | 2009-06-09 16:48:15 +0200 |
---|---|---|
committer | David Sommerseth <davids@redhat.com> | 2009-06-09 16:48:15 +0200 |
commit | bfbac44bd8c0fcddcdcfade6a15313560c9cc6eb (patch) | |
tree | 23aa1bd8c8012429c00bf4f0f2210bf5d2a98675 /src | |
parent | 4b22254e56bfdbec884a7f1cf634e340eff813c5 (diff) | |
download | python-dmidecode-bfbac44bd8c0fcddcdcfade6a15313560c9cc6eb.tar.gz python-dmidecode-bfbac44bd8c0fcddcdcfade6a15313560c9cc6eb.tar.xz python-dmidecode-bfbac44bd8c0fcddcdcfade6a15313560c9cc6eb.zip |
Big rewrite again, simplified the usage of opt->type
Instead of building up an u8 array with 255 cells where we only use one
cell at the time now, just pass the type id value as an int the whole way
through.
Diffstat (limited to 'src')
-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; |