diff options
author | nima <nima@abc39116-655e-4be6-ad55-d661dc543056> | 2008-12-17 07:20:56 +0000 |
---|---|---|
committer | nima <nima@abc39116-655e-4be6-ad55-d661dc543056> | 2008-12-17 07:20:56 +0000 |
commit | 39378ee26e0d1d2ab4c76eed22514c6f986c5495 (patch) | |
tree | 3bb1c6a481d384dd41b085f7f3e06bafa802a7e4 /src/dmidecodemodule.c | |
parent | b0103d72736fdf47760049dbf880a859b52c88fa (diff) | |
download | python-dmidecode-39378ee26e0d1d2ab4c76eed22514c6f986c5495.tar.gz python-dmidecode-39378ee26e0d1d2ab4c76eed22514c6f986c5495.tar.xz python-dmidecode-39378ee26e0d1d2ab4c76eed22514c6f986c5495.zip |
Cleaning up source area, ready for debianizing, and rpm after that.
git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@108 abc39116-655e-4be6-ad55-d661dc543056
Diffstat (limited to 'src/dmidecodemodule.c')
-rw-r--r-- | src/dmidecodemodule.c | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c new file mode 100644 index 0000000..5ede36e --- /dev/null +++ b/src/dmidecodemodule.c @@ -0,0 +1,205 @@ +#include "dmidecodemodule.h" +#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; +} + + +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; +} + + +static PyObject* dmidecode_get(PyObject *self, const char* section) { + //mtrace(); + + /* This is `embedding API', not applicable to this dmidecode module which is `Extending' + Py_SetProgramName("dmidecode"); + int argc = 3; + char *argv[4]; + argv[0] = "dmidecode"; + argv[1] = "--type"; + argv[2] = section; + argv[3] = NULL; + */ + + 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; + + 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++; + } + } + } 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); + } + } + + if(ret==0) { + free(buf); + + if(!found) + dmiSetItem(pydata, "detect", "No SMBIOS nor DMI entry point found, sorry G."); + } + free(opt.type); + + //muntrace(); + return (ret != 1)?pydata:NULL; +} + +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) { + const char *s; + if(PyArg_ParseTuple(args, (char *)"s", &s)) + return dmidecode_get(self, s); + return Py_None; +} + +static PyObject* dmidecode_dump(PyObject *self, PyObject *args) { + if(dump(PyString_AS_STRING(opt.dumpfile))) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; +} + +static PyObject* dmidecode_get_dev(PyObject *self, PyObject *null) { + if(opt.dumpfile != NULL) return opt.dumpfile; + else return PyString_FromString(opt.devmem); +} + +static PyObject* dmidecode_set_dev(PyObject *self, PyObject *arg) { + if(PyString_Check(arg)) { + if(opt.dumpfile) { Py_DECREF(opt.dumpfile); } + opt.dumpfile = arg; + Py_INCREF(opt.dumpfile); + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } + //PyErr_Occurred() +} + + + +PyMethodDef DMIDataMethods[] = { + { (char *)"dump", dmidecode_dump, METH_NOARGS, (char *)"Dump dmidata to set file" }, + { (char *)"get_dev", dmidecode_get_dev, METH_NOARGS, (char *)"Set 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(); + (void)Py_InitModule((char *)"dmidecode", DMIDataMethods); +} |