summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornima <nima@abc39116-655e-4be6-ad55-d661dc543056>2008-12-20 15:32:30 +0000
committernima <nima@abc39116-655e-4be6-ad55-d661dc543056>2008-12-20 15:32:30 +0000
commit0e2598266442b8f1015c75833034ac0f26857820 (patch)
treef4fb3cb9a3ad6e0fb9f61cd437a0933623ac820b
parent6d5ebf5d39e419e2f83960223bf840275426dc87 (diff)
downloadpython-dmidecode-0e2598266442b8f1015c75833034ac0f26857820.tar.gz
python-dmidecode-0e2598266442b8f1015c75833034ac0f26857820.tar.xz
python-dmidecode-0e2598266442b8f1015c75833034ac0f26857820.zip
Version information now set once during init().
Bettered test cases. Case 127 magically fixed. git-svn-id: svn://svn.autonomy.net.au/python-dmidecode@135 abc39116-655e-4be6-ad55-d661dc543056
-rw-r--r--src/dmidecode.c213
-rw-r--r--src/dmidecode.h6
-rw-r--r--src/dmidecodemodule.c105
-rw-r--r--src/dmidecodemodule.h6
-rwxr-xr-xtest.py126
5 files changed, 224 insertions, 232 deletions
diff --git a/src/dmidecode.c b/src/dmidecode.c
index 564cd28..874720d 100644
--- a/src/dmidecode.c
+++ b/src/dmidecode.c
@@ -4658,33 +4658,78 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, P
}
-int smbios_decode(u8 *buf, const char *devmem, PyObject* pydata, PyObject* pydata_ver) {
- if(pydata == NULL) return -1; //. TODO: Raise Exception
-
- if(!checksum(buf, buf[0x05]) || !memcmp(buf+0x10, "_DMI_", 5)==0 || !checksum(buf+0x10, 0x0F)) return 0;
-
- u16 ver = (buf[0x06] << 8) + buf[0x07];
- /* Some BIOS attempt to encode version 2.3.1 as 2.31, fix it up */
- if(ver == 0x021F) { fprintf(stderr, "SMBIOS version fixup (2.31 -> 2.3).\n"); ver = 0x0203; }
- if(pydata_ver) { Py_DECREF(pydata_ver); }
- pydata_ver = PyString_FromFormat("SMBIOS %i.%i present.", ver>>8, ver&0xFF);
- Py_INCREF(pydata_ver);
- dmi_table(DWORD(buf+0x18), WORD(buf+0x16), WORD(buf+0x1C), ver, devmem, pydata);
- return 1;
+
+
+int _smbios_decode_check(u8 *buf, const char *devmem, PyObject** pydata) {
+ int check;
+ if(!checksum(buf, buf[0x05]) || !memcmp(buf+0x10, "_DMI_", 5)==0 || !checksum(buf+0x10, 0x0F)) check = 0; //. Bad
+ else check = 1; //. Good
+ return check;
+}
+int smbios_decode_set_version(u8 *buf, const char *devmem, PyObject** pydata) {
+ int check = _smbios_decode_check(buf, devmem, pydata);
+ char vbuf[64]; bzero(vbuf, 64);
+ if(check == 1) {
+ u16 ver = (buf[0x06] << 8) + buf[0x07];
+ /* Some BIOS attempt to encode version 2.3.1 as 2.31, fix it up */
+ if(ver == 0x021F) {
+ sprintf(vbuf, "SMBIOS 2.3 present. (Version fixup 2.31 -> 2.3).");
+ ver = 0x0203;
+ } else {
+ sprintf(vbuf, "SMBIOS %i.%i present.", ver>>8, ver&0xFF);
+ }
+ } else if(check == 0) {
+ sprintf(vbuf, "No SMBIOS nor DMI entry point found, sorry G.");
+ }
+ if(check == 1) {
+ if(*pydata) { Py_DECREF(*pydata); }
+ *pydata = PyString_FromString(vbuf);
+ Py_INCREF(*pydata);
+ }
+ return check;
+}
+int smbios_decode(u8 *buf, const char *devmem, PyObject* pydata) {
+ int check = _smbios_decode_check(buf, devmem, &pydata);
+ if(check == 1) {
+ u16 ver = (buf[0x06] << 8) + buf[0x07];
+ dmi_table(DWORD(buf+0x18), WORD(buf+0x16), WORD(buf+0x1C), ver, devmem, pydata);
+ }
+ return check;
}
-int legacy_decode(u8 *buf, const char *devmem, PyObject* pydata, PyObject* pydata_ver) {
- if(pydata == NULL) return -1; //. TODO: Raise Exception
- if(!checksum(buf, 0x0F)) return 0;
- if(pydata_ver) { Py_DECREF(pydata_ver); }
- pydata_ver = PyString_FromFormat("Legacy DMI %i.%i present.", buf[0x0E]>>4, buf[0x0E]&0x0F);
- Py_INCREF(pydata_ver);
- dmi_table(DWORD(buf+0x08), WORD(buf+0x06), WORD(buf+0x0C), ((buf[0x0E]&0xF0)<<4)+(buf[0x0E]&0x0F), devmem, pydata);
- return 1;
+int _legacy_decode_check(u8 *buf, const char *devmem, PyObject** pydata) {
+ int check;
+ if(!checksum(buf, 0x0F)) check = 0; //. Bad
+ else check = 1; //. Good
+ return check;
}
+int legacy_decode_set_version(u8 *buf, const char *devmem, PyObject** pydata) {
+ int check = _legacy_decode_check(buf, devmem, pydata);
+ char vbuf[64]; bzero(vbuf, 64);
+ if(check == 1) {
+ sprintf(vbuf, "Legacy DMI %i.%i present.", buf[0x0E]>>4, buf[0x0E]&0x0F);
+ } else if(check == 0) {
+ sprintf(vbuf, "No SMBIOS nor DMI entry point found, sorry G.");
+ }
+ if(check == 1) {
+ if(*pydata) { Py_DECREF(*pydata); }
+ *pydata = PyString_FromString(vbuf);
+ Py_INCREF(*pydata);
+ }
+ return check;
+}
+int legacy_decode(u8 *buf, const char *devmem, PyObject* pydata) {
+ int check = _legacy_decode_check(buf, devmem, &pydata);
+ if(check == 1)
+ dmi_table(DWORD(buf+0x08), WORD(buf+0x06), WORD(buf+0x0C), ((buf[0x0E]&0xF0)<<4)+(buf[0x0E]&0x0F), devmem, pydata);
+ return check;
+}
+
+
+
/*******************************************************************************
** Probe for EFI interface
@@ -4725,129 +4770,3 @@ int address_from_efi(size_t *address) {
return ret;
}
-
-/*
-int submain(int argc, char * const argv[])
-{
- int ret=0; / * Returned value * /
- int found=0;
- size_t fp;
- int efi;
- u8 *buf;
-
- char _[2048]; bzero(_, 2048);
-
- if(sizeof(u8)!=1 || sizeof(u16)!=2 || sizeof(u32)!=4 || '\0'!=0)
- {
- fprintf(stderr, "%s: compiler incompatibility\n", argv[0]);
- exit(255);
- }
-
- / * Set default option values * /
- //. opt.devmem=DEFAULT_MEM_DEV;
- //. opt.flags=0;
-
- if(parse_command_line(argc, argv)<0)
- {
- ret=2;
- goto exit_free;
- }
-
- if(opt.flags & FLAG_HELP)
- {
- print_help();
- goto exit_free;
- }
-
- if(opt.flags & FLAG_VERSION)
- {
- sprintf(_, "%s\n", VERSION);
- goto exit_free;
- }
-
- if(!(opt.flags & FLAG_QUIET))
- sprintf(_, "# dmidecode %s\n", VERSION);
-
-
- / * Read from dump if so instructed * /
- if (opt.flags & FLAG_FROM_DUMP)
- {
- if (!(opt.flags & FLAG_QUIET))
- printf("Reading SMBIOS/DMI data from file %s.\n",
- opt.dumpfile);
- if ((buf = mem_chunk(0, 0x20, opt.dumpfile)) == NULL)
- {
- ret = 1;
- goto exit_free;
- }
-
- if (memcmp(buf, "_SM_", 4)==0)
- {
- if (smbios_decode(buf, opt.dumpfile, NULL))
- found++;
- }
- else if (memcmp(buf, "_DMI_", 5)==0)
- {
- if (legacy_decode(buf, opt.dumpfile, NULL))
- found++;
- }
- goto done;
- }
-
-
- / * First try EFI (ia64, Intel-based Mac) * /
- efi=address_from_efi(&fp, _);
- switch(efi)
- {
- case EFI_NOT_FOUND:
- goto memory_scan;
- case EFI_NO_SMBIOS:
- ret=1;
- goto exit_free;
- }
-
- if((buf=mem_chunk(fp, 0x20, opt.devmem))==NULL)
- {
- ret=1;
- goto exit_free;
- }
-
- if(smbios_decode(buf, opt.devmem, NULL))
- found++;
- goto done;
-
-memory_scan:
- / * Fallback to memory scan (x86, x86_64) * /
- if((buf=mem_chunk(0xF0000, 0x10000, opt.devmem))==NULL)
- {
- ret=1;
- goto exit_free;
- }
-
- for(fp=0; fp<=0xFFF0; fp+=16)
- {
- if(memcmp(buf+fp, "_SM_", 4)==0 && fp<=0xFFE0)
- {
- if(smbios_decode(buf+fp, opt.devmem, NULL))
- found++;
- fp+=16;
- }
- else if(memcmp(buf+fp, "_DMI_", 5)==0)
- {
- if (legacy_decode(buf+fp, opt.devmem, NULL))
- found++;
- }
- }
-
-done:
- free(buf);
-
- if(!found && !(opt.flags & FLAG_QUIET))
- fprintf(stderr, "# No SMBIOS nor DMI entry point found, sorry.\n");
-
-exit_free:
- //. free(opt.type);
-
- return ret;
-}
-*/
diff --git a/src/dmidecode.h b/src/dmidecode.h
index 1673394..7e99faa 100644
--- a/src/dmidecode.h
+++ b/src/dmidecode.h
@@ -30,8 +30,10 @@ PyObject *dmi_dump(struct dmi_header *h);
PyObject* dmi_decode(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(u8 *buf, const char *devmem, PyObject* pydata, PyObject* pydata_ver);
-int legacy_decode(u8 *buf, const char *devmem, PyObject* pydata, PyObject* pydata_ver);
+int smbios_decode_set_version(u8 *buf, const char *devmem, PyObject** pydata);
+int smbios_decode(u8 *buf, const char *devmem, PyObject* pydata);
+int legacy_decode_set_version(u8 *buf, const char *devmem, PyObject** pydata);
+int legacy_decode(u8 *buf, const char *devmem, PyObject* pydata);
const char *dmi_string(const struct dmi_header *dm, u8 s);
const char *dmi_system_uuid(u8 *p);
diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c
index 06e5cf0..03001a8 100644
--- a/src/dmidecodemodule.c
+++ b/src/dmidecodemodule.c
@@ -62,19 +62,66 @@ u8 *parse_opt_type(u8 *p, const char *arg) {
}
+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++;
+ }
+ }
+ } 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;
+}
+
+
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;
@@ -83,13 +130,12 @@ static PyObject* dmidecode_get(PyObject *self, const char* section) {
/* Set default option values */
opt.devmem = DEFAULT_MEM_DEV;
- opt.flags=0;
+ opt.flags = 0;
opt.type = NULL;
- opt.type=parse_opt_type(opt.type, section);
+ opt.type = parse_opt_type(opt.type, section);
if(opt.type==NULL) return NULL;
PyObject* pydata = PyDict_New();
- PyObject* pydata_ver;
/***********************************/
/* Read from dump if so instructed */
@@ -98,9 +144,9 @@ static PyObject* dmidecode_get(PyObject *self, const char* section) {
//. 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, pydata_ver)) found++;
+ if(smbios_decode(buf, dumpfile, pydata)) found++;
} else if (memcmp(buf, "_DMI_", 5)==0) {
- if(legacy_decode(buf, dumpfile, pydata, pydata_ver)) found++;
+ if(legacy_decode(buf, dumpfile, pydata)) found++;
}
} else ret = 1;
} else { /* Read from /dev/mem */
@@ -111,10 +157,10 @@ static PyObject* dmidecode_get(PyObject *self, const char* section) {
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, pydata_ver)) found++;
+ 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, pydata_ver)) found++;
+ if(legacy_decode(buf+fp, opt.devmem, pydata)) found++;
}
}
} else ret = 1;
@@ -122,20 +168,12 @@ static PyObject* dmidecode_get(PyObject *self, const char* section) {
ret = 1;
} else {
if((buf=mem_chunk(fp, 0x20, opt.devmem))==NULL) ret = 1;
- else if(smbios_decode(buf, opt.devmem, pydata, pydata_ver)) found++;
+ else if(smbios_decode(buf, opt.devmem, pydata)) found++;
//. TODO: dmiSetItem(pydata, "efi_address", efiAddress);
}
}
- if(ret==0) {
- free(buf);
- if(!found) {
- if(!pydata_ver) {
- pydata_ver = PyString_FromString("No SMBIOS nor DMI entry point found, sorry G.");
- Py_INCREF(pydata_ver);
- }
- }
- }
+ if(ret==0) free(buf);
free(opt.type);
//muntrace();
@@ -207,7 +245,7 @@ static PyObject* dmidecode_set_dev(PyObject *self, PyObject *arg) {
//PyErr_Occurred();
}
-/* TODO
+/*
typedef struct {
PyObject_HEAD char *version;
} ivars;
@@ -240,5 +278,14 @@ static PyMethodDef DMIDataMethods[] = {
PyMODINIT_FUNC initdmidecode(void) {
init();
- (void)Py_InitModule((char *)"dmidecode", DMIDataMethods);
+
+ PyObject *module = Py_InitModule3((char *)"dmidecode", DMIDataMethods, "Testing");
+
+ PyObject *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);
}
diff --git a/src/dmidecodemodule.h b/src/dmidecodemodule.h
index 00532bd..cf1e5f4 100644
--- a/src/dmidecodemodule.h
+++ b/src/dmidecodemodule.h
@@ -27,8 +27,10 @@ extern PyObject* dmi_decode(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, PyObject* pydata, PyObject* pydata_ver);
-extern int legacy_decode(u8 *buf, const char *devmem, PyObject* pydata, PyObject* pydata_ver);
+extern int smbios_decode(u8 *buf, const char *devmem, PyObject* pydata);
+extern int legacy_decode(u8 *buf, const char *devmem, PyObject* pydata);
+extern int smbios_decode_set_version(u8 *buf, const char *devmem, PyObject** pydata);
+extern int legacy_decode_set_version(u8 *buf, const char *devmem, PyObject** pydata);
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/test.py b/test.py
index 59608a8..23b83f2 100755
--- a/test.py
+++ b/test.py
@@ -1,66 +1,88 @@
#!/usr/bin/env python
-#.awk '$0 ~ /case [0-9]+: .. 3/ { print $2 }' src/dmidecode.c|tr ':\n' ', '
+#.awk '$0 ~ /case [0-9]+: .. 3/ { sys.stdout.write($2 }' src/dmidecode.c|tr ':\n' ', '
from pprint import pprint
-import os, sys, random
+import os, sys, random, tempfile, time
-print "Importing module...",
-import dmidecode
-print "Done"
+FH, DUMP = tempfile.mkstemp()
+os.unlink(DUMP)
+os.close(FH)
-print "Testing check for write permission on dump...",
-print not dmidecode.dump() and "Good" or "Bad"
+total = 0
+success = 0
-print "Testing that default device is /dev/mem",
-print dmidecode.get_dev() == "/dev/mem" and "Good" or "Bad"
+def test(r):
+ global total
+ global success
-print "Testing ability to change device to /tmp/foo...",
-print dmidecode.set_dev("/tmp/foo") and "Good" or "Bad"
+ total += 1
+ if r:
+ sys.stdout.write("Good\n")
+ success += 1
+ else:
+ sys.stdout.write("Bad\n")
-print "Testing that device has changed to /tmp/foo...",
-print dmidecode.get_dev() == "/tmp/foo" and "Good" or "Bad"
+total += 1
+sys.stdout.write("Importing module...")
+try:
+ import dmidecode
+ sys.stdout.write("Done\n")
+ success += 1
+ sys.stdout.write(" * Version: %s\n"%dmidecode.version)
+ sys.stdout.write(" * DMI Version String: %s\n"%dmidecode.dmi)
-print "Testing that write on new file is ok...",
-print dmidecode.dump() and "Good" or "Bad"
+ sys.stdout.write("Testing that default device is /dev/mem...")
+ test(dmidecode.get_dev() == "/dev/mem")
-print "Testing that file was actually written...",
-if os.path.exists("/tmp/foo"):
- sys.stdout.write("Good\n")
- os.unlink("/tmp/foo")
-else:
- sys.stdout.write("FAILED\n")
+ sys.stdout.write("Testing that write-lock will not break on dump()...")
+ test(not dmidecode.dump())
-types = range(0, 42)+range(126, 128)
-types = range(0, 42)+[126, 127]
-sections = ["bios", "system", "baseboard", "chassis", "processor", "memory", "cache", "connector", "slot"]
-devices = [os.path.join("private", _) for _ in os.listdir("private")]
-devices.remove('private/.svn')
-devices.append("/dev/mem")
-random.shuffle(types)
-random.shuffle(devices)
-random.shuffle(sections)
+ sys.stdout.write("Testing ability to change device to %s..."%DUMP)
+ test(dmidecode.set_dev(DUMP))
-total = 0
-success = 0
-for dev in devices:
- sys.stdout.write(" * Testing %s..."%dev); sys.stdout.flush()
- total += 1
- if dmidecode.set_dev(dev) and dmidecode.get_dev() == dev:
- success += 1
- sys.stdout.write("...\n")
- for i in types:
- sys.stdout.write(" * Testing type %i..."%i); sys.stdout.flush()
- output = dmidecode.type(i).keys()
- total += 1
- sys.stdout.write("Done (%s)\n"%output)
- success += 1
- for section in sections:
- total += 1
- sys.stdout.write(" * Testing %s..."%section); sys.stdout.flush()
- output = getattr(dmidecode, section)().keys()
- sys.stdout.write("Done (%s)\n"%output)
+ sys.stdout.write("Testing that device has changed to %s..."%DUMP)
+ test(dmidecode.get_dev() == DUMP)
+
+ sys.stdout.write("Testing that write on new file is ok...")
+ test(dmidecode.dump())
+
+ sys.stdout.write("Testing that file was actually written...")
+ time.sleep(0.1)
+ test(os.path.exists(DUMP))
+ os.unlink(DUMP)
+
+ types = range(0, 42)+range(126, 128)
+ types = range(0, 42)+[126, 127]
+ sections = ["bios", "system", "baseboard", "chassis", "processor", "memory", "cache", "connector", "slot"]
+ devices = [os.path.join("private", _) for _ in os.listdir("private")]
+ devices.remove('private/.svn')
+ devices.append("/dev/mem")
+ random.shuffle(types)
+ random.shuffle(devices)
+ random.shuffle(sections)
+
+ for dev in devices:
+ sys.stdout.write(" * Testing %s..."%dev); sys.stdout.flush()
+ total += 1
+ if dmidecode.set_dev(dev) and dmidecode.get_dev() == dev:
success += 1
- else:
- sys.stdout.write("FAILED\n")
+ sys.stdout.write("...\n")
+ for i in types:
+ total += 1
+ sys.stdout.write(" * Testing type %i..."%i); sys.stdout.flush()
+ output = dmidecode.type(i).keys()
+ sys.stdout.write("Done (%s)\n"%output)
+ success += 1
+ for section in sections:
+ total += 1
+ sys.stdout.write(" * Testing %s..."%section); sys.stdout.flush()
+ output = getattr(dmidecode, section)().keys()
+ sys.stdout.write("Done (%s)\n"%output)
+ success += 1
+ else:
+ sys.stdout.write("FAILED\n")
+
+except ImportError:
+ sys.stdout.write("FAILED\n")
-print "Score: %d/%d"%(success, total)
+sys.stdout.write("Score: %d/%d\n"%(success, total))