| #include <stdlib.h> |
| #include <string.h> |
| |
| #define ldmilib_c /* Define the library */ |
| |
| /* Include the Lua API header files */ |
| #include "lua.h" |
| #include "lauxlib.h" |
| #include "lualib.h" |
| #include "dmi/dmi.h" |
| |
| static void add_string_item(lua_State *L, const char *item, const char *value_str) { |
| lua_pushstring(L,item); |
| lua_pushstring(L,value_str); |
| lua_settable(L,-3); |
| } |
| |
| static void add_int_item(lua_State *L, const char *item, int value_int) { |
| lua_pushstring(L,item); |
| lua_pushnumber(L,value_int); |
| lua_settable(L,-3); |
| } |
| |
| typedef int (*table_fn)(lua_State*, s_dmi*); |
| |
| /* Add a Lua_String entry to the table on stack |
| xxx_P is the poiter version (i.e., pBase is a pointer) |
| xxx_S is the staic version (i.e., Base is the struct) |
| */ |
| #define LUA_ADD_STR_P(pLua_state, pBase, Field) \ |
| add_string_item(pLua_state, #Field, pBase->Field); |
| #define LUA_ADD_STR_S(pLua_state, Base, Field) \ |
| add_string_item(pLua_state, #Field, Base.Field); |
| |
| /* Add a Lua_Number entry to the table on stack |
| xxx_P is the poiter version (i.e., pBase is a pointer) |
| xxx_S is the staic version (i.e., Base is the struct) |
| */ |
| #define LUA_ADD_NUM_P(pLua_state, pBase, Field) \ |
| add_int_item(pLua_state, #Field, pBase->Field); |
| #define LUA_ADD_NUM_S(pLua_state, Base, Field) \ |
| add_int_item(pLua_state, #Field, Base.Field); |
| |
| /* Add a sub-DMI table to the table on stack |
| All (*table_fn)() have to be named as get_<tabel_name>_table() for this |
| macro to work. For example, for the bios subtable, the table_fn is |
| get_bios_table() and the subtable name is "bios". |
| All (*table_fn)() have to return 1 if a subtable is created on the stack |
| or 0 if the subtable is not created (no corresponding dim subtable found). |
| */ |
| #define LUA_ADD_TABLE(pLua_state, pDmi, tb_name) \ |
| add_dmi_sub_table(pLua_state, pDmi, #tb_name, get_ ## tb_name ## _table); |
| |
| |
| static void add_dmi_sub_table(lua_State *L, s_dmi *dmi_ptr, char *table_name, |
| table_fn get_table_fn) |
| { |
| if (get_table_fn(L, dmi_ptr)) { /* only adding it when it is there */ |
| lua_pushstring(L, table_name); |
| lua_insert(L, -2); |
| lua_settable(L,-3); |
| } |
| } |
| |
| |
| void get_bool_table(lua_State *L, const char *str_table[], int n_elem, |
| bool *bool_table) |
| { |
| int i; |
| for (i = 0; i < n_elem; i++) { |
| if (!str_table[i] || !*str_table[i]) /* aviod NULL/empty string */ |
| continue; |
| |
| lua_pushstring(L, str_table[i]); |
| lua_pushboolean(L, bool_table[i]); |
| lua_settable(L,-3); |
| } |
| } |
| |
| |
| /* |
| ** {====================================================== |
| ** DMI subtables |
| ** ======================================================= |
| */ |
| static int get_bios_table(lua_State *L, s_dmi *dmi_ptr) |
| { |
| s_bios *bios = &dmi_ptr->bios; |
| |
| if (!bios->filled) |
| return 0; |
| /* bios */ |
| lua_newtable(L); |
| LUA_ADD_STR_P(L, bios, vendor) |
| LUA_ADD_STR_P(L, bios, version) |
| LUA_ADD_STR_P(L, bios, release_date) |
| LUA_ADD_STR_P(L, bios, bios_revision) |
| LUA_ADD_STR_P(L, bios, firmware_revision) |
| LUA_ADD_NUM_P(L, bios, address) |
| LUA_ADD_NUM_P(L, bios, runtime_size) |
| LUA_ADD_STR_P(L, bios, runtime_size_unit) |
| LUA_ADD_NUM_P(L, bios, rom_size) |
| LUA_ADD_STR_P(L, bios, rom_size_unit) |
| |
| /* bios characteristics */ |
| lua_pushstring(L, "chars"); |
| lua_newtable(L); |
| get_bool_table(L, bios_charac_strings, |
| sizeof(s_characteristics)/sizeof(bool), |
| (bool *)(&bios->characteristics)); |
| get_bool_table(L, bios_charac_x1_strings, |
| sizeof(s_characteristics_x1)/sizeof(bool), |
| (bool *)(&bios->characteristics_x1)); |
| get_bool_table(L, bios_charac_x2_strings, |
| sizeof(s_characteristics_x2)/sizeof(bool), |
| (bool *)(&bios->characteristics_x2)); |
| lua_settable(L,-3); |
| |
| return 1; |
| } |
| |
| |
| static int get_system_table(lua_State *L, s_dmi *dmi_ptr) |
| { |
| s_system *system = &dmi_ptr->system; |
| |
| if (!system->filled) |
| return 0; |
| /* system */ |
| lua_newtable(L); |
| LUA_ADD_STR_P(L, system, manufacturer) |
| LUA_ADD_STR_P(L, system, product_name) |
| LUA_ADD_STR_P(L, system, version) |
| LUA_ADD_STR_P(L, system, serial) |
| LUA_ADD_STR_P(L, system, uuid) |
| LUA_ADD_STR_P(L, system, wakeup_type) |
| LUA_ADD_STR_P(L, system, sku_number) |
| LUA_ADD_STR_P(L, system, family) |
| LUA_ADD_STR_P(L, system, system_boot_status) |
| LUA_ADD_STR_P(L, system, configuration_options) |
| |
| /* system reset */ |
| if (system->system_reset.filled) { |
| lua_pushstring(L, "reset"); |
| lua_newtable(L); |
| LUA_ADD_NUM_S(L, system->system_reset, status) |
| LUA_ADD_NUM_S(L, system->system_reset, watchdog) |
| LUA_ADD_STR_S(L, system->system_reset, boot_option) |
| LUA_ADD_STR_S(L, system->system_reset, boot_option_on_limit) |
| LUA_ADD_STR_S(L, system->system_reset, reset_count) |
| LUA_ADD_STR_S(L, system->system_reset, reset_limit) |
| LUA_ADD_STR_S(L, system->system_reset, timer_interval) |
| LUA_ADD_STR_S(L, system->system_reset, timeout) |
| lua_settable(L,-3); |
| } |
| |
| return 1; |
| } |
| |
| |
| static int get_base_board_table(lua_State *L, s_dmi *dmi_ptr) |
| { |
| s_base_board *base_board = &dmi_ptr->base_board; |
| int n_dev = sizeof(base_board->devices_information) / |
| sizeof(base_board->devices_information[0]); |
| int i, j, has_dev; |
| |
| if (!base_board->filled) |
| return 0; |
| /* base_board */ |
| lua_newtable(L); |
| LUA_ADD_STR_P(L, base_board, manufacturer) |
| LUA_ADD_STR_P(L, base_board, product_name) |
| LUA_ADD_STR_P(L, base_board, version) |
| LUA_ADD_STR_P(L, base_board, serial) |
| LUA_ADD_STR_P(L, base_board, asset_tag) |
| LUA_ADD_STR_P(L, base_board, location) |
| LUA_ADD_STR_P(L, base_board, type) |
| |
| /* base board features */ |
| lua_pushstring(L, "features"); |
| lua_newtable(L); |
| get_bool_table(L, base_board_features_strings, |
| sizeof(s_base_board_features)/sizeof(bool), |
| (bool *)(&base_board->features)); |
| lua_settable(L,-3); |
| |
| /* on-board devices */ |
| for (has_dev = 0, i = 0; i < n_dev; i++) |
| if (*base_board->devices_information[i].type) |
| has_dev++; |
| |
| if (has_dev) { |
| lua_pushstring(L, "devices"); |
| lua_newtable(L); |
| for (i = 0, j = 1; i < n_dev; i++) { |
| if (!*base_board->devices_information[i].type) /* empty device */ |
| continue; |
| |
| lua_pushinteger(L, j++); |
| lua_newtable(L); |
| LUA_ADD_STR_S(L, base_board->devices_information[i], type) |
| LUA_ADD_STR_S(L, base_board->devices_information[i], description) |
| LUA_ADD_NUM_S(L, base_board->devices_information[i], status) |
| lua_settable(L,-3); |
| } |
| lua_settable(L,-3); |
| } |
| |
| return 1; |
| } |
| |
| |
| static int get_chassis_table(lua_State *L, s_dmi *dmi_ptr) |
| { |
| s_chassis *chassis = &dmi_ptr->chassis; |
| |
| if (!chassis->filled) |
| return 0; |
| /* chassis */ |
| lua_newtable(L); |
| LUA_ADD_STR_P(L, chassis, manufacturer) |
| LUA_ADD_STR_P(L, chassis, type) |
| LUA_ADD_STR_P(L, chassis, lock) |
| LUA_ADD_STR_P(L, chassis, version) |
| LUA_ADD_STR_P(L, chassis, serial) |
| LUA_ADD_STR_P(L, chassis, asset_tag) |
| LUA_ADD_STR_P(L, chassis, boot_up_state) |
| LUA_ADD_STR_P(L, chassis, power_supply_state) |
| LUA_ADD_STR_P(L, chassis, thermal_state) |
| LUA_ADD_STR_P(L, chassis, security_status) |
| LUA_ADD_STR_P(L, chassis, oem_information) |
| LUA_ADD_NUM_P(L, chassis, height) |
| LUA_ADD_NUM_P(L, chassis, nb_power_cords) |
| |
| return 1; |
| } |
| |
| |
| static int get_processor_table(lua_State *L, s_dmi *dmi_ptr) |
| { |
| s_processor *processor = &dmi_ptr->processor; |
| s_signature *signature = &processor->signature; |
| |
| if (!processor->filled) |
| return 0; |
| /* processor */ |
| lua_newtable(L); |
| LUA_ADD_STR_P(L, processor, socket_designation) |
| LUA_ADD_STR_P(L, processor, type) |
| LUA_ADD_STR_P(L, processor, family) |
| LUA_ADD_STR_P(L, processor, manufacturer) |
| LUA_ADD_STR_P(L, processor, version) |
| LUA_ADD_NUM_P(L, processor, external_clock) |
| LUA_ADD_NUM_P(L, processor, max_speed) |
| LUA_ADD_NUM_P(L, processor, current_speed) |
| LUA_ADD_NUM_P(L, processor, voltage_mv) |
| LUA_ADD_STR_P(L, processor, status) |
| LUA_ADD_STR_P(L, processor, upgrade) |
| LUA_ADD_STR_P(L, processor, cache1) |
| LUA_ADD_STR_P(L, processor, cache2) |
| LUA_ADD_STR_P(L, processor, cache3) |
| LUA_ADD_STR_P(L, processor, serial) |
| LUA_ADD_STR_P(L, processor, part_number) |
| LUA_ADD_STR_P(L, processor, id) |
| LUA_ADD_NUM_P(L, processor, core_count) |
| LUA_ADD_NUM_P(L, processor, core_enabled) |
| LUA_ADD_NUM_P(L, processor, thread_count) |
| |
| /* processor signature */ |
| lua_pushstring(L, "signature"); |
| lua_newtable(L); |
| LUA_ADD_NUM_P(L, signature, type) |
| LUA_ADD_NUM_P(L, signature, family) |
| LUA_ADD_NUM_P(L, signature, model) |
| LUA_ADD_NUM_P(L, signature, stepping) |
| LUA_ADD_NUM_P(L, signature, minor_stepping) |
| lua_settable(L,-3); |
| |
| /* processor flags */ |
| lua_pushstring(L, "flags"); |
| lua_newtable(L); |
| get_bool_table(L, cpu_flags_strings, |
| sizeof(s_dmi_cpu_flags)/sizeof(bool), |
| (bool *)(&processor->cpu_flags)); |
| lua_settable(L,-3); |
| |
| return 1; |
| } |
| |
| |
| static int get_battery_table(lua_State *L, s_dmi *dmi_ptr) |
| { |
| s_battery *battery = &dmi_ptr->battery; |
| |
| if (!battery->filled) |
| return 0; |
| /* battery */ |
| lua_newtable(L); |
| LUA_ADD_STR_P(L, battery, location) |
| LUA_ADD_STR_P(L, battery, manufacturer) |
| LUA_ADD_STR_P(L, battery, manufacture_date) |
| LUA_ADD_STR_P(L, battery, serial) |
| LUA_ADD_STR_P(L, battery, name) |
| LUA_ADD_STR_P(L, battery, chemistry) |
| LUA_ADD_STR_P(L, battery, design_capacity) |
| LUA_ADD_STR_P(L, battery, design_voltage) |
| LUA_ADD_STR_P(L, battery, sbds) |
| LUA_ADD_STR_P(L, battery, sbds_serial) |
| LUA_ADD_STR_P(L, battery, maximum_error) |
| LUA_ADD_STR_P(L, battery, sbds_manufacture_date) |
| LUA_ADD_STR_P(L, battery, sbds_chemistry) |
| LUA_ADD_STR_P(L, battery, oem_info) |
| |
| return 1; |
| } |
| |
| |
| static int get_memory_table(lua_State *L, s_dmi *dmi_ptr) |
| { |
| s_memory *memory = dmi_ptr->memory; |
| int i, j, n_mem = dmi_ptr->memory_count; |
| |
| if (n_mem <= 0) /* no memory info */ |
| return 0; |
| |
| /* memory */ |
| lua_newtable(L); |
| for (j = 1, i = 0; i < n_mem; i++) { |
| if (!memory[i].filled) |
| continue; |
| |
| lua_pushinteger(L, j++); |
| lua_newtable(L); |
| LUA_ADD_STR_S(L, memory[i], manufacturer) |
| LUA_ADD_STR_S(L, memory[i], error) |
| LUA_ADD_STR_S(L, memory[i], total_width) |
| LUA_ADD_STR_S(L, memory[i], data_width) |
| LUA_ADD_STR_S(L, memory[i], size) |
| LUA_ADD_STR_S(L, memory[i], form_factor) |
| LUA_ADD_STR_S(L, memory[i], device_set) |
| LUA_ADD_STR_S(L, memory[i], device_locator) |
| LUA_ADD_STR_S(L, memory[i], bank_locator) |
| LUA_ADD_STR_S(L, memory[i], type) |
| LUA_ADD_STR_S(L, memory[i], type_detail) |
| LUA_ADD_STR_S(L, memory[i], speed) |
| LUA_ADD_STR_S(L, memory[i], serial) |
| LUA_ADD_STR_S(L, memory[i], asset_tag) |
| LUA_ADD_STR_S(L, memory[i], part_number) |
| lua_settable(L,-3); |
| } |
| return 1; |
| } |
| |
| |
| static int get_memory_module_table(lua_State *L, s_dmi *dmi_ptr) |
| { |
| s_memory_module *memory_module = dmi_ptr->memory_module; |
| int i, j, n_mem = dmi_ptr->memory_module_count; |
| |
| if (n_mem <= 0) /* no memory module info */ |
| return 0; |
| |
| /* memory module */ |
| lua_newtable(L); |
| for (j = 1, i = 0; i < n_mem; i++) { |
| if (!memory_module[i].filled) |
| continue; |
| |
| lua_pushinteger(L, j++); |
| lua_newtable(L); |
| LUA_ADD_STR_S(L, memory_module[i], socket_designation) |
| LUA_ADD_STR_S(L, memory_module[i], bank_connections) |
| LUA_ADD_STR_S(L, memory_module[i], speed) |
| LUA_ADD_STR_S(L, memory_module[i], type) |
| LUA_ADD_STR_S(L, memory_module[i], installed_size) |
| LUA_ADD_STR_S(L, memory_module[i], enabled_size) |
| LUA_ADD_STR_S(L, memory_module[i], error_status) |
| lua_settable(L,-3); |
| } |
| return 1; |
| } |
| |
| |
| static int get_cache_table(lua_State *L, s_dmi *dmi_ptr) |
| { |
| s_cache *cache = dmi_ptr->cache; |
| int i, n_cache = dmi_ptr->cache_count; |
| |
| if (n_cache <= 0) /* no cache info */ |
| return 0; |
| |
| /* memory */ |
| lua_newtable(L); |
| for (i = 0; i < n_cache; i++) { |
| lua_pushinteger(L, i + 1); |
| lua_newtable(L); |
| LUA_ADD_STR_S(L, cache[i], socket_designation) |
| LUA_ADD_STR_S(L, cache[i], configuration) |
| LUA_ADD_STR_S(L, cache[i], mode) |
| LUA_ADD_STR_S(L, cache[i], location) |
| LUA_ADD_NUM_S(L, cache[i], installed_size) |
| LUA_ADD_NUM_S(L, cache[i], max_size) |
| LUA_ADD_STR_S(L, cache[i], supported_sram_types) |
| LUA_ADD_STR_S(L, cache[i], installed_sram_types) |
| LUA_ADD_NUM_S(L, cache[i], speed) |
| LUA_ADD_STR_S(L, cache[i], error_correction_type) |
| LUA_ADD_STR_S(L, cache[i], system_type) |
| LUA_ADD_STR_S(L, cache[i], associativity) |
| lua_settable(L,-3); |
| } |
| return 1; |
| } |
| |
| |
| static int get_hardware_security_table(lua_State *L, s_dmi *dmi_ptr) |
| { |
| if (!dmi_ptr->hardware_security.filled) |
| return 0; |
| /* hardware_security */ |
| lua_newtable(L); |
| LUA_ADD_STR_S(L, dmi_ptr->hardware_security, power_on_passwd_status) |
| LUA_ADD_STR_S(L, dmi_ptr->hardware_security, keyboard_passwd_status) |
| LUA_ADD_STR_S(L, dmi_ptr->hardware_security, administrator_passwd_status) |
| LUA_ADD_STR_S(L, dmi_ptr->hardware_security, front_panel_reset_status) |
| |
| return 1; |
| } |
| |
| |
| static int get_dmi_info_table(lua_State *L, s_dmi *dmi_ptr) |
| { |
| dmi_table *dmitable = &dmi_ptr->dmitable; |
| |
| /* dmi info */ |
| lua_newtable(L); |
| LUA_ADD_NUM_P(L, dmitable, num) |
| LUA_ADD_NUM_P(L, dmitable, len) |
| LUA_ADD_NUM_P(L, dmitable, ver) |
| LUA_ADD_NUM_P(L, dmitable, base) |
| LUA_ADD_NUM_P(L, dmitable, major_version) |
| LUA_ADD_NUM_P(L, dmitable, minor_version) |
| |
| return 1; |
| } |
| |
| |
| static int get_ipmi_table(lua_State *L, s_dmi *dmi_ptr) |
| { |
| s_ipmi *ipmi = &dmi_ptr->ipmi; |
| |
| if (!ipmi->filled) |
| return 0; |
| /* ipmi */ |
| lua_newtable(L); |
| LUA_ADD_STR_P(L, ipmi, interface_type) |
| LUA_ADD_NUM_P(L, ipmi, major_specification_version) |
| LUA_ADD_NUM_P(L, ipmi, minor_specification_version) |
| LUA_ADD_NUM_P(L, ipmi, I2C_slave_address) |
| LUA_ADD_NUM_P(L, ipmi, nv_address) |
| LUA_ADD_NUM_P(L, ipmi, base_address) |
| LUA_ADD_NUM_P(L, ipmi, irq) |
| |
| return 1; |
| } |
| /* |
| ** {====================================================== |
| ** End of DMI subtables |
| ** ======================================================= |
| */ |
| |
| |
| static int dmi_gettable(lua_State *L) |
| { |
| s_dmi dmi; |
| |
| lua_newtable(L); |
| |
| if ( ! dmi_iterate(&dmi) ) { |
| printf("No DMI Structure found\n"); |
| return -1; |
| } |
| |
| parse_dmitable(&dmi); |
| |
| LUA_ADD_NUM_S(L, dmi, memory_module_count) |
| LUA_ADD_NUM_S(L, dmi, memory_count) |
| LUA_ADD_NUM_S(L, dmi, cache_count) |
| LUA_ADD_STR_S(L, dmi, oem_strings) |
| |
| LUA_ADD_TABLE(L, &dmi, bios) |
| LUA_ADD_TABLE(L, &dmi, system) |
| LUA_ADD_TABLE(L, &dmi, base_board) |
| LUA_ADD_TABLE(L, &dmi, chassis) |
| LUA_ADD_TABLE(L, &dmi, processor) |
| LUA_ADD_TABLE(L, &dmi, battery) |
| LUA_ADD_TABLE(L, &dmi, memory) |
| LUA_ADD_TABLE(L, &dmi, memory_module) |
| LUA_ADD_TABLE(L, &dmi, cache) |
| LUA_ADD_TABLE(L, &dmi, ipmi) |
| LUA_ADD_TABLE(L, &dmi, hardware_security) |
| LUA_ADD_TABLE(L, &dmi, dmi_info) |
| |
| /* set global variable: lua_setglobal(L, "dmitable"); */ |
| |
| /* return number of return values on stack */ |
| return 1; |
| } |
| |
| |
| static int dmi_supported(lua_State *L) |
| { |
| s_dmi dmi; |
| |
| if ( dmi_iterate(&dmi) ) { |
| lua_pushboolean(L, 1); |
| } else { |
| lua_pushboolean(L, 0); |
| } |
| return 1; |
| } |
| |
| |
| static const luaL_Reg dmilib[] = { |
| {"gettable", dmi_gettable}, |
| {"supported", dmi_supported}, |
| {NULL, NULL} |
| }; |
| |
| |
| LUALIB_API int luaopen_dmi (lua_State *L) { |
| luaL_newlib(L, dmilib); |
| return 1; |
| } |
| |