diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dmidecode.c | 55 | ||||
-rw-r--r-- | src/dmidecode.h | 6 | ||||
-rw-r--r-- | src/dmidecodemodule.c | 181 | ||||
-rw-r--r-- | src/dmidecodemodule.h | 6 | ||||
-rw-r--r-- | src/dmihelper.h | 4 |
5 files changed, 154 insertions, 98 deletions
diff --git a/src/dmidecode.c b/src/dmidecode.c index 491183d..bdb0758 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -3642,7 +3642,7 @@ void dmi_additional_info(xmlNode *node, const struct dmi_header *h) ** Main */ -xmlNode *dmi_decode(struct dmi_header * h, u16 ver) +xmlNode *dmi_decode(xmlNode *prnt_n, struct dmi_header * h, u16 ver) { const u8 *data = h->data; xmlNode *sect_n = NULL, *sub_n = NULL, *sub2_n = NULL; @@ -3652,8 +3652,7 @@ xmlNode *dmi_decode(struct dmi_header * h, u16 ver) //dmi_codes_major *dmiMajor = (dmi_codes_major *)&dmiCodesMajor[map_maj[h->type]]; dmi_codes_major *dmiMajor = (dmi_codes_major *) &dmiCodesMajor[h->type]; - - sect_n = xmlNewNode(NULL, (xmlChar *) dmiMajor->tagname); + sect_n = xmlNewChild(prnt_n, NULL, (xmlChar *) dmiMajor->tagname, NULL); assert( sect_n != NULL ); dmixml_AddAttribute(sect_n, "dmispec", "%s", dmiMajor->id); @@ -4799,45 +4798,50 @@ void to_dmi_header(struct dmi_header *h, u8 * data) h->data = data; } -void dmi_table_string(const struct dmi_header *h, const u8 *data, xmlNode *node, u16 ver) +xmlNode *dmi_table_string(xmlNode *prnt_n, const struct dmi_header *h, const u8 *data, u16 ver) { int key; u8 offset = opt.string->offset; - xmlNode *dmi_n = NULL; + xmlNode *handle_n = NULL, *dmi_n = NULL; if(offset >= h->length) - return; + return NULL; + + handle_n = xmlNewChild(prnt_n, NULL, (xmlChar *) "DMItable", NULL); + assert( handle_n != NULL ); //. TODO: These should have more meaningful dictionary names key = (opt.string->type << 8) | offset; switch (key) { case 0x108: - dmi_system_uuid(node, data + offset, ver); - dmixml_AddAttribute(node, "DMItype", "0x108"); + dmi_system_uuid(handle_n, data + offset, ver); + dmixml_AddAttribute(handle_n, "DMItype", "0x108"); break; case 0x305: - dmi_chassis_type(node, data[offset]); - dmixml_AddAttribute(node, "DMItype", "0x305"); + dmi_chassis_type(handle_n, data[offset]); + dmixml_AddAttribute(handle_n, "DMItype", "0x305"); // FIXME: Missing break? case 0x406: - dmi_processor_family(node, h); - dmixml_AddAttribute(node, "DMItype", "0x406"); + dmi_processor_family(handle_n, h); + dmixml_AddAttribute(handle_n, "DMItype", "0x406"); break; case 0x416: - dmi_n = dmixml_AddTextChild(node, "ProcessorFrequency", "%s", + dmi_n = dmixml_AddTextChild(handle_n, "ProcessorFrequency", "%s", dmi_processor_frequency((u8 *) data + offset)); dmixml_AddAttribute(dmi_n, "DMItype", "0x416"); dmi_n = NULL; break; default: - dmi_n = dmixml_AddTextChild(node, "Unknown", "%s", dmi_string(h, data[offset])); + dmi_n = dmixml_AddTextChild(handle_n, "Unknown", "%s", dmi_string(h, data[offset])); dmixml_AddAttribute(dmi_n, "DMItype", "0x%03x", key); } + + return handle_n; } /* @@ -5054,18 +5058,15 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, x * PyDict_SetItem(hDict, PyString_FromString("data"), dmi_decode(&h, ver)); * PyDict_SetItem(pydata, PyString_FromString(hid), hDict); * } */ - handle_n = dmi_decode(&h, ver); + handle_n = dmi_decode(xmlnode, &h, ver); } else fprintf(stderr, "<TRUNCATED>"); } else if(opt.string != NULL && opt.string->type == h.type) { - handle_n = xmlNewNode(NULL, (xmlChar *) "DMItable"); - assert( handle_n != NULL ); - dmi_table_string(&h, data, handle_n, ver); + handle_n = dmi_table_string(xmlnode, &h, data, ver); } if( handle_n != NULL ) { dmixml_AddAttribute(handle_n, "handle", "0x%04x", h.handle); dmixml_AddAttribute(handle_n, "size", "%d", h.length); - xmlAddChild(xmlnode, handle_n); } data = next; @@ -5090,13 +5091,15 @@ int _smbios_decode_check(u8 * buf) return check; } -int smbios_decode_set_version(u8 * buf, const char *devmem, xmlNode *node) +xmlNode *smbios_decode_set_version(u8 * buf, const char *devmem) { int check = _smbios_decode_check(buf); - xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "SMBIOSversion", NULL); + xmlNode *data_n = xmlNewNode(NULL, (xmlChar *) "DMIversion"); assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "type", "SMBIOS"); + if(check == 1) { u16 ver = (buf[0x06] << 8) + buf[0x07]; @@ -5130,7 +5133,7 @@ int smbios_decode_set_version(u8 * buf, const char *devmem, xmlNode *node) dmixml_AddTextContent(data_n, "No SMBIOS nor DMI entry point found"); dmixml_AddAttribute(data_n, "unknown", "1"); } - return check; + return data_n; } int smbios_decode(u8 * buf, const char *devmem, xmlNode *xmlnode) @@ -5166,13 +5169,15 @@ int _legacy_decode_check(u8 * buf) return check; } -int legacy_decode_set_version(u8 * buf, const char *devmem, xmlNode *node) +xmlNode *legacy_decode_set_version(u8 * buf, const char *devmem) { int check = _legacy_decode_check(buf); - xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "LegacyDMI", NULL); + xmlNode *data_n = xmlNewNode(NULL, (xmlChar *) "DMIversion"); assert( data_n != NULL ); + dmixml_AddAttribute(data_n, "type", "legacy"); + if(check == 1) { dmixml_AddTextContent(data_n, "Legacy DMI %i.%i present", buf[0x0E] >> 4, buf[0x0E] & 0x0F); @@ -5183,7 +5188,7 @@ int legacy_decode_set_version(u8 * buf, const char *devmem, xmlNode *node) dmixml_AddAttribute(data_n, "unknown", "1"); } - return check; + return data_n; } int legacy_decode(u8 * buf, const char *devmem, xmlNode *xmlnode) diff --git a/src/dmidecode.h b/src/dmidecode.h index ef13ce3..04d8f04 100644 --- a/src/dmidecode.h +++ b/src/dmidecode.h @@ -29,12 +29,12 @@ struct dmi_header { }; void dmi_dump(xmlNode *node, struct dmi_header * h); -xmlNode *dmi_decode(struct dmi_header * h, u16 ver); +xmlNode *dmi_decode(xmlNode *parent_n, struct dmi_header * h, u16 ver); int address_from_efi(size_t * address); void to_dmi_header(struct dmi_header *h, u8 * data); -int smbios_decode_set_version(u8 * buf, const char *devmem, xmlNode *node); +xmlNode *smbios_decode_set_version(u8 * buf, const char *devmem); int smbios_decode(u8 * buf, const char *devmem, xmlNode *xmlnode); -int legacy_decode_set_version(u8 * buf, const char *devmem, xmlNode *node); +xmlNode *legacy_decode_set_version(u8 * buf, const char *devmem); int legacy_decode(u8 * buf, const char *devmem, xmlNode *xmlnode); const char *dmi_string(const struct dmi_header *dm, u8 s); diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index e9e688c..8c3a2b9 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -1,8 +1,14 @@ #include <Python.h> + +#include <libxml/tree.h> + +#include "xmlpythonizer.h" #include "dmidecodemodule.h" +#include "dmixml.h" #include <mcheck.h> options opt; + static void init(void) { /* sanity check */ @@ -13,6 +19,8 @@ static void init(void) opt.dumpfile = NULL; opt.flags = 0; opt.type = NULL; + opt.mappingxml = NULL; + opt.dmiversion_n = NULL; } u8 *parse_opt_type(u8 * p, const char *arg) @@ -64,18 +72,18 @@ u8 *parse_opt_type(u8 * p, const char *arg) return p; } -static int dmidecode_set_version(PyObject ** pydata) + +xmlNode *dmidecode_set_version() { - int ret = 0; int found = 0; size_t fp; int efi; - u8 *buf; + u8 *buf = NULL; + xmlNode *ver_n = NULL; /* Set default option values */ opt.devmem = DEFAULT_MEM_DEV; - /***********************************/ /* Read from dump if so instructed */ if(opt.dumpfile != NULL) { const char *dumpfile = PyString_AS_STRING(opt.dumpfile); @@ -83,15 +91,18 @@ static int dmidecode_set_version(PyObject ** pydata) //. printf("Reading SMBIOS/DMI data from file %s.\n", dumpfile); if((buf = mem_chunk(0, 0x20, dumpfile)) != NULL) { if(memcmp(buf, "_SM_", 4) == 0) { - if(smbios_decode_set_version(buf, dumpfile, pydata)) + ver_n = smbios_decode_set_version(buf, dumpfile); + if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) { found++; + } } else if(memcmp(buf, "_DMI_", 5) == 0) { - if(legacy_decode_set_version(buf, dumpfile, pydata)) + ver_n = legacy_decode_set_version(buf, dumpfile); + if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) { found++; + } } - } else - ret = 1; - } else { /* Read from /dev/mem */ + } + } else { /* Read from /dev/mem */ /* First try EFI (ia64, Intel-based Mac) */ efi = address_from_efi(&fp); if(efi == EFI_NOT_FOUND) { @@ -99,40 +110,44 @@ static int dmidecode_set_version(PyObject ** pydata) if((buf = mem_chunk(0xF0000, 0x10000, opt.devmem)) != NULL) { for(fp = 0; fp <= 0xFFF0; fp += 16) { if(memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0) { - if(smbios_decode_set_version - (buf + fp, opt.devmem, pydata)) + ver_n = smbios_decode_set_version(buf + fp, opt.devmem); + if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) { found++; + } fp += 16; } else if(memcmp(buf + fp, "_DMI_", 5) == 0) { - if(legacy_decode_set_version - (buf + fp, opt.devmem, pydata)) + ver_n = legacy_decode_set_version (buf + fp, opt.devmem); + if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) { found++; + } } } - } else - ret = 1; + } } else if(efi == EFI_NO_SMBIOS) { - ret = 1; + ver_n = NULL; } else { - if((buf = mem_chunk(fp, 0x20, opt.devmem)) == NULL) - ret = 1; - else if(smbios_decode_set_version(buf, opt.devmem, pydata)) - found++; - //. TODO: dmixml_AddAttribute(dmixml_n, "efi_address", efiAddress); + // Process as EFI + if((buf = mem_chunk(fp, 0x20, opt.devmem)) != NULL) { + ver_n = smbios_decode_set_version(buf, opt.devmem); + if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) { + found++; + } + //. TODO: dmixml_AddAttribute(dmixml_n, "efi_address", efiAddress); + } } } - - if(ret == 0) { + if( buf != NULL ) { free(buf); - if(!found) { - fprintf(stderr, "No SMBIOS nor DMI entry point found, sorry G."); - } + } + + if( !found ) { + fprintf(stderr, "No SMBIOS nor DMI entry point found, sorry."); } free(opt.type); - return ret; + return ver_n; } -static PyObject *dmidecode_get(PyObject * self, const char *section) +xmlNode *dmidecode_get_xml(PyObject *self, const char *section) { //mtrace(); @@ -142,29 +157,24 @@ static PyObject *dmidecode_get(PyObject * self, const char *section) int efi; u8 *buf; - /* Set default option values */ - 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; + xmlNode *dmixml_n = xmlNewNode(NULL, (xmlChar *) "dmidecode"); + assert( dmixml != NULL ); + + // Append DMI version info + if( opt.dmiversion_n != NULL ) { + xmlAddChild(dmixml_n, opt.dmiversion_n); + } const char *f = opt.dumpfile ? PyString_AsString(opt.dumpfile) : opt.devmem; if(access(f, R_OK) < 0) PyErr_SetString(PyExc_IOError, "Permission denied to memory file/device"); - PyObject *pydata = NULL; - xmlNode *dmixml_n = xmlNewNode(NULL, (xmlChar *) "dmidecode"); - assert( dmixml != NULL ); - - /***********************************/ /* Read from dump if so instructed */ if(opt.dumpfile != NULL) { const char *dumpfile = PyString_AS_STRING(opt.dumpfile); - //. printf("Reading SMBIOS/DMI data from file %s.\n", dumpfile); + // printf("Reading SMBIOS/DMI data from file %s.\n", dumpfile); if((buf = mem_chunk(0, 0x20, dumpfile)) != NULL) { if(memcmp(buf, "_SM_", 4) == 0) { if(smbios_decode(buf, dumpfile, dmixml_n)) @@ -173,8 +183,9 @@ static PyObject *dmidecode_get(PyObject * self, const char *section) if(legacy_decode(buf, dumpfile, dmixml_n)) found++; } - } else + } else { ret = 1; + } } else { /* Read from /dev/mem */ /* First try EFI (ia64, Intel-based Mac) */ efi = address_from_efi(&fp); @@ -201,7 +212,7 @@ static PyObject *dmidecode_get(PyObject * self, const char *section) ret = 1; else if(smbios_decode(buf, opt.devmem, dmixml_n)) found++; - //. TODO: dmiSetItem(pydata, "efi_address", efiAddress); + // TODO: dmixml_AddAttribute(dmixml_n, "efi_address", "0x%08x", efiAddress); } } @@ -210,16 +221,62 @@ static PyObject *dmidecode_get(PyObject * self, const char *section) free(buf); } else { xmlFreeNode(dmixml_n); - if( pydata != NULL ) { - PyDECREF(pydata); - pydata = NULL; - } + dmixml_n = NULL; } //muntrace(); + return dmixml_n; +} + +static PyObject *dmidecode_get(PyObject *self, const char *section) +{ + PyObject *pydata = NULL; + xmlNode *dmixml_n = NULL; + + /* Set default option values */ + 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 = dmidecode_get_xml(self, section); + if( dmixml_n != NULL ) { + ptzMAP *mapping = NULL; + + // Convert the retrieved XML nodes to Python dicts + if( opt.mappingxml == NULL ) { + // Load mapping into memory + opt.mappingxml = xmlReadFile("pythonmap.xml", NULL, 0); + assert( opt.mappingxml != NULL ); + } + + mapping = dmiMAP_ParseMappingXML(opt.mappingxml, section); + assert( mapping != NULL ); + + // Generate Python dict out of XML node + pydata = pythonizeXMLnode(mapping, dmixml_n); + +#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); +#endif + ptzmap_Free(mapping); + xmlFreeNode(dmixml_n); + } else { + return NULL; + } + return pydata; } + + static PyObject *dmidecode_get_bios(PyObject * self, PyObject * args) { return dmidecode_get(self, "bios"); @@ -330,16 +387,6 @@ static PyObject *dmidecode_set_dev(PyObject * self, PyObject * arg) //PyErr_Occurred(); } -/* -typedef struct { - PyObject_HEAD char *version; -} ivars; - -static PyMemberDef DMIDataMembers[] = { - { (char *)"fred", T_STRING, offsetof(ivars, version), 0, "2.10" }, - { NULL } -}; -*/ static PyMethodDef DMIDataMethods[] = { {(char *)"dump", dmidecode_dump, METH_NOARGS, (char *)"Dump dmidata to set file"}, @@ -365,19 +412,19 @@ static PyMethodDef DMIDataMethods[] = { PyMODINIT_FUNC initdmidecode(void) { - init(); - - PyObject *module = - Py_InitModule3((char *)"dmidecode", DMIDataMethods, - "Python extension module for dmidecode"); + char *dmiver = NULL; + PyObject *module = NULL; + PyObject *version = NULL; - PyObject *version = PyString_FromString("2.10"); + init(); + module = Py_InitModule3((char *)"dmidecode", DMIDataMethods, + "Python extension module for dmidecode"); + version = PyString_FromString("2.10"); Py_INCREF(version); PyModule_AddObject(module, "version", version); - PyObject *dmi_version = NULL; - - dmidecode_set_version(&dmi_version); - PyModule_AddObject(module, "dmi", dmi_version ? dmi_version : Py_None); + opt.dmiversion_n = dmidecode_set_version(); + dmiver = dmixml_GetContent(opt.dmiversion_n); + PyModule_AddObject(module, "dmi", dmiver ? PyString_FromString(dmiver) : Py_None); } diff --git a/src/dmidecodemodule.h b/src/dmidecodemodule.h index 7583eb7..2ebc5d0 100644 --- a/src/dmidecodemodule.h +++ b/src/dmidecodemodule.h @@ -23,14 +23,14 @@ //extern void dmi_decode(struct dmi_header *h, u16 ver, PyObject* pydata); extern void dmi_dump(xmlNode *node, struct dmi_header *h); -extern xmlNode *dmi_decode(struct dmi_header * h, u16 ver); +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 void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem); extern int smbios_decode(u8 * buf, const char *devmem, xmlNode *node); extern int legacy_decode(u8 * buf, const char *devmem, xmlNode *node); -extern int smbios_decode_set_version(u8 * buf, const char *devmem, xmlNode *node); -extern int legacy_decode_set_version(u8 * buf, const char *devmem, xmlNode *node); +extern xmlNode *smbios_decode_set_version(u8 * buf, const char *devmem); +extern xmlNode *legacy_decode_set_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); diff --git a/src/dmihelper.h b/src/dmihelper.h index 6c0b854..50cb185 100644 --- a/src/dmihelper.h +++ b/src/dmihelper.h @@ -9,6 +9,8 @@ #include <stdlib.h> #include <assert.h> +#include <libxml/tree.h> + #include "types.h" #define MAXVAL 1024 @@ -110,6 +112,8 @@ typedef struct _options { unsigned int flags; u8 *type; const struct string_keyword *string; + xmlDoc *mappingxml; + xmlNode *dmiversion_n; PyObject *dumpfile; } options; extern options opt; |