diff options
Diffstat (limited to 'src/dmidecodemodule.c')
-rw-r--r-- | src/dmidecodemodule.c | 574 |
1 files changed, 323 insertions, 251 deletions
diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 345b151..1870e86 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -2,261 +2,326 @@ #include <mcheck.h> options opt; -static void init(void) { - /* sanity check */ - if(sizeof(u8)!=1 || sizeof(u16)!=2 || sizeof(u32)!=4 || '\0'!=0) - fprintf(stderr, "%s: compiler incompatibility\n", "dmidecodemodule"); - - opt.devmem = DEFAULT_MEM_DEV; - opt.dumpfile = NULL; - opt.flags=0; - opt.type = NULL; +static void init(void) +{ + /* sanity check */ + if(sizeof(u8) != 1 || sizeof(u16) != 2 || sizeof(u32) != 4 || '\0' != 0) + fprintf(stderr, "%s: compiler incompatibility\n", "dmidecodemodule"); + + opt.devmem = DEFAULT_MEM_DEV; + opt.dumpfile = NULL; + opt.flags = 0; + opt.type = NULL; } +u8 *parse_opt_type(u8 * p, const char *arg) +{ -u8 *parse_opt_type(u8 *p, 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; - char *next; - - val = strtoul(arg, &next, 0); - if(next == arg) { - fprintf(stderr, "Invalid type keyword: %s\n", arg); - free(p); - return NULL; - } - if (val > 0xff) { - fprintf(stderr, "Invalid type number: %lu\n", val); - free(p); - return NULL; - } - - p[val] = 1; - arg = next; - while(*arg == ',' || *arg == ' ') - arg++; - } - - return p; -} + /* Allocate memory on first call only */ + if(p == NULL) { + if(!(p = (u8 *) calloc(256, sizeof(u8)))) { + perror("calloc"); + return NULL; + } + } + unsigned int i, j; -static int dmidecode_set_version(PyObject** pydata) { - int ret=0; - int found=0; - size_t fp; - int efi; - u8 *buf; + /* 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; + char *next; + + val = strtoul(arg, &next, 0); + if(next == arg) { + fprintf(stderr, "Invalid type keyword: %s\n", arg); + free(p); + return NULL; + } + if(val > 0xff) { + fprintf(stderr, "Invalid type number: %lu\n", val); + free(p); + return NULL; + } + + p[val] = 1; + arg = next; + while(*arg == ',' || *arg == ' ') + arg++; + } + + return p; +} - /* Set default option values */ - opt.devmem = DEFAULT_MEM_DEV; +static int dmidecode_set_version(PyObject ** pydata) +{ + int ret = 0; + int found = 0; + size_t fp; + int efi; + u8 *buf; + + /* 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); - //. 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)) found++; - } else if (memcmp(buf, "_DMI_", 5)==0) { - if(legacy_decode_set_version(buf, dumpfile, pydata)) found++; - } - } else ret = 1; - } else { /* Read from /dev/mem */ - /* First try EFI (ia64, Intel-based Mac) */ - efi = address_from_efi(&fp); - if(efi == EFI_NOT_FOUND) { - /* Fallback to memory scan (x86, x86_64) */ - 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)) found++; - fp+=16; - } else if(memcmp(buf+fp, "_DMI_", 5)==0) { - if(legacy_decode_set_version(buf+fp, opt.devmem, pydata)) found++; - } + /* 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); + if((buf = mem_chunk(0, 0x20, dumpfile)) != NULL) { + if(memcmp(buf, "_SM_", 4) == 0) { + if(smbios_decode_set_version(buf, dumpfile, pydata)) + found++; + } else if(memcmp(buf, "_DMI_", 5) == 0) { + if(legacy_decode_set_version(buf, dumpfile, pydata)) + found++; + } + } else + ret = 1; + } else { /* Read from /dev/mem */ + /* First try EFI (ia64, Intel-based Mac) */ + efi = address_from_efi(&fp); + if(efi == EFI_NOT_FOUND) { + /* Fallback to memory scan (x86, x86_64) */ + 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)) + found++; + fp += 16; + } else if(memcmp(buf + fp, "_DMI_", 5) == 0) { + if(legacy_decode_set_version + (buf + fp, opt.devmem, pydata)) + found++; + } + } + } else + ret = 1; + } else if(efi == EFI_NO_SMBIOS) { + ret = 1; + } else { + if((buf = mem_chunk(fp, 0x20, opt.devmem)) == NULL) + ret = 1; + else if(smbios_decode_set_version(buf, opt.devmem, pydata)) + found++; + //. TODO: dmiSetItem(pydata, "efi_address", efiAddress); + } + } + + if(ret == 0) { + free(buf); + if(!found) { + fprintf(stderr, "No SMBIOS nor DMI entry point found, sorry G."); + } } - } else ret = 1; - } else if(efi == EFI_NO_SMBIOS) { - ret = 1; - } else { - if((buf=mem_chunk(fp, 0x20, opt.devmem))==NULL) ret = 1; - else if(smbios_decode_set_version(buf, opt.devmem, pydata)) found++; - //. TODO: dmiSetItem(pydata, "efi_address", efiAddress); - } - } - - if(ret==0) { - free(buf); - if(!found) { - fprintf(stderr, "No SMBIOS nor DMI entry point found, sorry G."); - } - } - free(opt.type); - return ret; + free(opt.type); + return ret; } +static PyObject *dmidecode_get(PyObject * self, const char *section) +{ + //mtrace(); -static PyObject* dmidecode_get(PyObject *self, const char* section) { - //mtrace(); + int ret = 0; + int found = 0; + size_t fp; + int efi; + u8 *buf; - int ret=0; - int found=0; - size_t fp; - 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; - /* 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; + const char *f = opt.dumpfile ? PyString_AsString(opt.dumpfile) : opt.devmem; - 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"); + if(access(f, R_OK) < 0) + PyErr_SetString(PyExc_IOError, "Permission denied to memory file/device"); - PyObject* pydata = PyDict_New(); + PyObject *pydata = PyDict_New(); /***********************************/ - /* 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); - if((buf = mem_chunk(0, 0x20, dumpfile))!=NULL) { - if(memcmp(buf, "_SM_", 4)==0) { - if(smbios_decode(buf, dumpfile, pydata)) found++; - } else if (memcmp(buf, "_DMI_", 5)==0) { - if(legacy_decode(buf, dumpfile, pydata)) found++; - } - } else ret = 1; - } else { /* Read from /dev/mem */ - /* First try EFI (ia64, Intel-based Mac) */ - efi = address_from_efi(&fp); - if(efi == EFI_NOT_FOUND) { - /* Fallback to memory scan (x86, x86_64) */ - 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(buf+fp, opt.devmem, pydata)) { - found++; - fp+=16; - } - } else if(memcmp(buf+fp, "_DMI_", 5)==0) { - if(legacy_decode(buf+fp, opt.devmem, pydata)) found++; - } + /* 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); + if((buf = mem_chunk(0, 0x20, dumpfile)) != NULL) { + if(memcmp(buf, "_SM_", 4) == 0) { + if(smbios_decode(buf, dumpfile, pydata)) + found++; + } else if(memcmp(buf, "_DMI_", 5) == 0) { + if(legacy_decode(buf, dumpfile, pydata)) + found++; + } + } else + ret = 1; + } else { /* Read from /dev/mem */ + /* First try EFI (ia64, Intel-based Mac) */ + efi = address_from_efi(&fp); + if(efi == EFI_NOT_FOUND) { + /* Fallback to memory scan (x86, x86_64) */ + 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(buf + fp, opt.devmem, pydata)) { + found++; + fp += 16; + } + } else if(memcmp(buf + fp, "_DMI_", 5) == 0) { + if(legacy_decode(buf + fp, opt.devmem, pydata)) + found++; + } + } + } else + ret = 1; + } else if(efi == EFI_NO_SMBIOS) { + ret = 1; + } else { + if((buf = mem_chunk(fp, 0x20, opt.devmem)) == NULL) + ret = 1; + else if(smbios_decode(buf, opt.devmem, pydata)) + found++; + //. TODO: dmiSetItem(pydata, "efi_address", efiAddress); + } + } + + free(opt.type); + if(ret == 0) { + free(buf); + } else { + Py_DECREF(pydata); + pydata = NULL; } - } else ret = 1; - } else if(efi == EFI_NO_SMBIOS) { - ret = 1; - } else { - if((buf=mem_chunk(fp, 0x20, opt.devmem))==NULL) ret = 1; - else if(smbios_decode(buf, opt.devmem, pydata)) found++; - //. TODO: dmiSetItem(pydata, "efi_address", efiAddress); - } - } - - free(opt.type); - if(ret==0) { - free(buf); - } else { - Py_DECREF(pydata); - pydata = NULL; - } - - //muntrace(); - return pydata; + + //muntrace(); + return pydata; } -static PyObject* dmidecode_get_bios(PyObject *self, PyObject *args) { return dmidecode_get(self, "bios"); } -static PyObject* dmidecode_get_system(PyObject *self, PyObject *args) { return dmidecode_get(self, "system"); } -static PyObject* dmidecode_get_baseboard(PyObject *self, PyObject *args) { return dmidecode_get(self, "baseboard"); } -static PyObject* dmidecode_get_chassis(PyObject *self, PyObject *args) { return dmidecode_get(self, "chassis"); } -static PyObject* dmidecode_get_processor(PyObject *self, PyObject *args) { return dmidecode_get(self, "processor"); } -static PyObject* dmidecode_get_memory(PyObject *self, PyObject *args) { return dmidecode_get(self, "memory"); } -static PyObject* dmidecode_get_cache(PyObject *self, PyObject *args) { return dmidecode_get(self, "cache"); } -static PyObject* dmidecode_get_connector(PyObject *self, PyObject *args) { return dmidecode_get(self, "connector"); } -static PyObject* dmidecode_get_slot(PyObject *self, PyObject *args) { return dmidecode_get(self, "slot"); } -static PyObject* dmidecode_get_type(PyObject *self, PyObject *args) { - long unsigned int lu; - if(PyArg_ParseTuple(args, (char *)"i", &lu)) { - if(lu < 256) { - char s[8]; - sprintf(s, "%lu", lu); - return dmidecode_get(self, s); - } - return Py_False; - } - return Py_None; +static PyObject *dmidecode_get_bios(PyObject * self, PyObject * args) +{ + return dmidecode_get(self, "bios"); +} +static PyObject *dmidecode_get_system(PyObject * self, PyObject * args) +{ + return dmidecode_get(self, "system"); +} +static PyObject *dmidecode_get_baseboard(PyObject * self, PyObject * args) +{ + return dmidecode_get(self, "baseboard"); +} +static PyObject *dmidecode_get_chassis(PyObject * self, PyObject * args) +{ + return dmidecode_get(self, "chassis"); +} +static PyObject *dmidecode_get_processor(PyObject * self, PyObject * args) +{ + return dmidecode_get(self, "processor"); +} +static PyObject *dmidecode_get_memory(PyObject * self, PyObject * args) +{ + return dmidecode_get(self, "memory"); +} +static PyObject *dmidecode_get_cache(PyObject * self, PyObject * args) +{ + return dmidecode_get(self, "cache"); +} +static PyObject *dmidecode_get_connector(PyObject * self, PyObject * args) +{ + return dmidecode_get(self, "connector"); +} +static PyObject *dmidecode_get_slot(PyObject * self, PyObject * args) +{ + return dmidecode_get(self, "slot"); +} +static PyObject *dmidecode_get_type(PyObject * self, PyObject * args) +{ + long unsigned int lu; + + if(PyArg_ParseTuple(args, (char *)"i", &lu)) { + if(lu < 256) { + char s[8]; + + sprintf(s, "%lu", lu); + return dmidecode_get(self, s); + } + return Py_False; + } + return Py_None; } -static PyObject* dmidecode_dump(PyObject *self, PyObject *null) { - const char *f; - f = opt.dumpfile ? PyString_AsString(opt.dumpfile) : opt.devmem; - struct stat _buf; - stat(f, &_buf); +static PyObject *dmidecode_dump(PyObject * self, PyObject * null) +{ + const char *f; - if((access(f, F_OK) != 0) || ((access(f, W_OK) == 0) && S_ISREG(_buf.st_mode))) - if(dump(PyString_AS_STRING(opt.dumpfile))) - Py_RETURN_TRUE; - Py_RETURN_FALSE; -} + f = opt.dumpfile ? PyString_AsString(opt.dumpfile) : opt.devmem; + struct stat _buf; + + stat(f, &_buf); -static PyObject* dmidecode_get_dev(PyObject *self, PyObject *null) { - PyObject *dev; - if(opt.dumpfile != NULL) dev = opt.dumpfile; - else dev = PyString_FromString(opt.devmem); - Py_INCREF(dev); - return dev; + if((access(f, F_OK) != 0) || ((access(f, W_OK) == 0) && S_ISREG(_buf.st_mode))) + if(dump(PyString_AS_STRING(opt.dumpfile))) + Py_RETURN_TRUE; + Py_RETURN_FALSE; } -static PyObject* dmidecode_set_dev(PyObject *self, PyObject *arg) { - if(PyString_Check(arg)) { - if(opt.dumpfile == arg) Py_RETURN_TRUE; +static PyObject *dmidecode_get_dev(PyObject * self, PyObject * null) +{ + PyObject *dev; - struct stat buf; - char *f = PyString_AsString(arg); - stat(f, &buf); - if(opt.dumpfile) { Py_DECREF(opt.dumpfile); } + if(opt.dumpfile != NULL) + dev = opt.dumpfile; + else + dev = PyString_FromString(opt.devmem); + Py_INCREF(dev); + return dev; +} - if(S_ISCHR(buf.st_mode)) { - if(memcmp(PyString_AsString(arg), "/dev/mem", 8)==0) { - opt.dumpfile = NULL; - Py_RETURN_TRUE; - } else { +static PyObject *dmidecode_set_dev(PyObject * self, PyObject * arg) +{ + if(PyString_Check(arg)) { + if(opt.dumpfile == arg) + Py_RETURN_TRUE; + + struct stat buf; + char *f = PyString_AsString(arg); + + stat(f, &buf); + if(opt.dumpfile) { + Py_DECREF(opt.dumpfile); + } + + if(S_ISCHR(buf.st_mode)) { + if(memcmp(PyString_AsString(arg), "/dev/mem", 8) == 0) { + opt.dumpfile = NULL; + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } + } else if(!S_ISDIR(buf.st_mode)) { + opt.dumpfile = arg; + Py_INCREF(opt.dumpfile); + Py_RETURN_TRUE; + } + } Py_RETURN_FALSE; - } - } else if(!S_ISDIR(buf.st_mode)) { - opt.dumpfile = arg; - Py_INCREF(opt.dumpfile); - Py_RETURN_TRUE; - } - } - Py_RETURN_FALSE; - //PyErr_Occurred(); + //PyErr_Occurred(); } /* @@ -271,35 +336,42 @@ static PyMemberDef DMIDataMembers[] = { */ static PyMethodDef DMIDataMethods[] = { - { (char *)"dump", dmidecode_dump, METH_NOARGS, (char *)"Dump dmidata to set file" }, - { (char *)"get_dev", dmidecode_get_dev, METH_NOARGS, (char *)"Get an alternative memory device file" }, - { (char *)"set_dev", dmidecode_set_dev, METH_O, (char *)"Set an alternative memory device file" }, - - { (char *)"bios", dmidecode_get_bios, METH_VARARGS, (char *)"BIOS Data" }, - { (char *)"system", dmidecode_get_system, METH_VARARGS, (char *)"System Data" }, - { (char *)"baseboard", dmidecode_get_baseboard, METH_VARARGS, (char *)"Baseboard Data" }, - { (char *)"chassis", dmidecode_get_chassis, METH_VARARGS, (char *)"Chassis Data" }, - { (char *)"processor", dmidecode_get_processor, METH_VARARGS, (char *)"Processor Data" }, - { (char *)"memory", dmidecode_get_memory, METH_VARARGS, (char *)"Memory Data" }, - { (char *)"cache", dmidecode_get_cache, METH_VARARGS, (char *)"Cache Data" }, - { (char *)"connector", dmidecode_get_connector, METH_VARARGS, (char *)"Connector Data" }, - { (char *)"slot", dmidecode_get_slot, METH_VARARGS, (char *)"Slot Data" }, - - { (char *)"type", dmidecode_get_type, METH_VARARGS, (char *)"By Type" }, - - { NULL, NULL, 0, NULL } + {(char *)"dump", dmidecode_dump, METH_NOARGS, (char *)"Dump dmidata to set file"}, + {(char *)"get_dev", dmidecode_get_dev, METH_NOARGS, + (char *)"Get an alternative memory device file"}, + {(char *)"set_dev", dmidecode_set_dev, METH_O, + (char *)"Set an alternative memory device file"}, + + {(char *)"bios", dmidecode_get_bios, METH_VARARGS, (char *)"BIOS Data"}, + {(char *)"system", dmidecode_get_system, METH_VARARGS, (char *)"System Data"}, + {(char *)"baseboard", dmidecode_get_baseboard, METH_VARARGS, (char *)"Baseboard Data"}, + {(char *)"chassis", dmidecode_get_chassis, METH_VARARGS, (char *)"Chassis Data"}, + {(char *)"processor", dmidecode_get_processor, METH_VARARGS, (char *)"Processor Data"}, + {(char *)"memory", dmidecode_get_memory, METH_VARARGS, (char *)"Memory Data"}, + {(char *)"cache", dmidecode_get_cache, METH_VARARGS, (char *)"Cache Data"}, + {(char *)"connector", dmidecode_get_connector, METH_VARARGS, (char *)"Connector Data"}, + {(char *)"slot", dmidecode_get_slot, METH_VARARGS, (char *)"Slot Data"}, + + {(char *)"type", dmidecode_get_type, METH_VARARGS, (char *)"By Type"}, + + {NULL, NULL, 0, NULL} }; -PyMODINIT_FUNC initdmidecode(void) { - init(); +PyMODINIT_FUNC initdmidecode(void) +{ + init(); + + PyObject *module = + Py_InitModule3((char *)"dmidecode", DMIDataMethods, + "Python extension module for dmidecode"); + + PyObject *version = PyString_FromString("2.10"); - PyObject *module = Py_InitModule3((char *)"dmidecode", DMIDataMethods, "Python extension module for dmidecode"); + Py_INCREF(version); + PyModule_AddObject(module, "version", version); - PyObject *version = PyString_FromString("2.10"); - Py_INCREF(version); - PyModule_AddObject(module, "version", version); + PyObject *dmi_version = NULL; - PyObject *dmi_version = NULL; - dmidecode_set_version(&dmi_version); - PyModule_AddObject(module, "dmi", dmi_version?dmi_version:Py_None); + dmidecode_set_version(&dmi_version); + PyModule_AddObject(module, "dmi", dmi_version ? dmi_version : Py_None); } |