Home | History | Annotate | Download | only in src
      1 #include <stdlib.h>
      2 #include <string.h>
      3 
      4 #define ldmilib_c       /* Define the library */
      5 
      6 /* Include the Lua API header files */
      7 #include "lua.h"
      8 #include "lauxlib.h"
      9 #include "lualib.h"
     10 #include "dmi/dmi.h"
     11 
     12 static void add_string_item(lua_State *L, const char *item, const char *value_str) {
     13  lua_pushstring(L,item);
     14  lua_pushstring(L,value_str);
     15  lua_settable(L,-3);
     16 }
     17 
     18 static void add_int_item(lua_State *L, const char *item, int value_int) {
     19  lua_pushstring(L,item);
     20  lua_pushnumber(L,value_int);
     21  lua_settable(L,-3);
     22 }
     23 
     24 typedef int (*table_fn)(lua_State*, s_dmi*);
     25 
     26 /* Add a Lua_String entry to the table on stack
     27    xxx_P is the poiter version (i.e., pBase is a pointer)
     28    xxx_S is the staic version (i.e., Base is the struct)
     29 */
     30 #define LUA_ADD_STR_P(pLua_state, pBase, Field) \
     31   add_string_item(pLua_state, #Field, pBase->Field);
     32 #define LUA_ADD_STR_S(pLua_state, Base, Field) \
     33   add_string_item(pLua_state, #Field, Base.Field);
     34 
     35 /* Add a Lua_Number entry to the table on stack
     36    xxx_P is the poiter version (i.e., pBase is a pointer)
     37    xxx_S is the staic version (i.e., Base is the struct)
     38 */
     39 #define LUA_ADD_NUM_P(pLua_state, pBase, Field) \
     40   add_int_item(pLua_state, #Field, pBase->Field);
     41 #define LUA_ADD_NUM_S(pLua_state, Base, Field) \
     42   add_int_item(pLua_state, #Field, Base.Field);
     43 
     44 /* Add a sub-DMI table to the table on stack
     45    All (*table_fn)() have to be named as get_<tabel_name>_table() for this
     46    macro to work. For example, for the bios subtable, the table_fn is
     47    get_bios_table() and the subtable name is "bios".
     48    All (*table_fn)() have to return 1 if a subtable is created on the stack
     49    or 0 if the subtable is not created (no corresponding dim subtable found).
     50 */
     51 #define LUA_ADD_TABLE(pLua_state, pDmi, tb_name) \
     52   add_dmi_sub_table(pLua_state, pDmi, #tb_name, get_ ## tb_name ## _table);
     53 
     54 
     55 static void add_dmi_sub_table(lua_State *L, s_dmi *dmi_ptr, char *table_name,
     56                               table_fn get_table_fn)
     57 {
     58   if (get_table_fn(L, dmi_ptr)) {  /* only adding it when it is there */
     59     lua_pushstring(L, table_name);
     60     lua_insert(L, -2);
     61     lua_settable(L,-3);
     62   }
     63 }
     64 
     65 
     66 void get_bool_table(lua_State *L, const char *str_table[], int n_elem,
     67                            bool *bool_table)
     68 {
     69   int i;
     70   for (i = 0; i < n_elem; i++) {
     71     if (!str_table[i] || !*str_table[i])  /* aviod NULL/empty string */
     72       continue;
     73 
     74     lua_pushstring(L, str_table[i]);
     75     lua_pushboolean(L, bool_table[i]);
     76     lua_settable(L,-3);
     77   }
     78 }
     79 
     80 
     81 /*
     82 ** {======================================================
     83 ** DMI subtables
     84 ** =======================================================
     85 */
     86 static int get_bios_table(lua_State *L, s_dmi *dmi_ptr)
     87 {
     88   s_bios *bios = &dmi_ptr->bios;
     89 
     90   if (!bios->filled)
     91     return 0;
     92   /* bios */
     93   lua_newtable(L);
     94   LUA_ADD_STR_P(L, bios, vendor)
     95   LUA_ADD_STR_P(L, bios, version)
     96   LUA_ADD_STR_P(L, bios, release_date)
     97   LUA_ADD_STR_P(L, bios, bios_revision)
     98   LUA_ADD_STR_P(L, bios, firmware_revision)
     99   LUA_ADD_NUM_P(L, bios, address)
    100   LUA_ADD_NUM_P(L, bios, runtime_size)
    101   LUA_ADD_STR_P(L, bios, runtime_size_unit)
    102   LUA_ADD_NUM_P(L, bios, rom_size)
    103   LUA_ADD_STR_P(L, bios, rom_size_unit)
    104 
    105   /* bios characteristics */
    106   lua_pushstring(L, "chars");
    107   lua_newtable(L);
    108   get_bool_table(L, bios_charac_strings,
    109                  sizeof(s_characteristics)/sizeof(bool),
    110                  (bool *)(&bios->characteristics));
    111   get_bool_table(L, bios_charac_x1_strings,
    112                  sizeof(s_characteristics_x1)/sizeof(bool),
    113                  (bool *)(&bios->characteristics_x1));
    114   get_bool_table(L, bios_charac_x2_strings,
    115                  sizeof(s_characteristics_x2)/sizeof(bool),
    116                  (bool *)(&bios->characteristics_x2));
    117   lua_settable(L,-3);
    118 
    119   return 1;
    120 }
    121 
    122 
    123 static int get_system_table(lua_State *L, s_dmi *dmi_ptr)
    124 {
    125   s_system *system = &dmi_ptr->system;
    126 
    127   if (!system->filled)
    128     return 0;
    129   /* system */
    130   lua_newtable(L);
    131   LUA_ADD_STR_P(L, system, manufacturer)
    132   LUA_ADD_STR_P(L, system, product_name)
    133   LUA_ADD_STR_P(L, system, version)
    134   LUA_ADD_STR_P(L, system, serial)
    135   LUA_ADD_STR_P(L, system, uuid)
    136   LUA_ADD_STR_P(L, system, wakeup_type)
    137   LUA_ADD_STR_P(L, system, sku_number)
    138   LUA_ADD_STR_P(L, system, family)
    139   LUA_ADD_STR_P(L, system, system_boot_status)
    140   LUA_ADD_STR_P(L, system, configuration_options)
    141 
    142   /* system reset */
    143   if (system->system_reset.filled) {
    144     lua_pushstring(L, "reset");
    145     lua_newtable(L);
    146     LUA_ADD_NUM_S(L, system->system_reset, status)
    147     LUA_ADD_NUM_S(L, system->system_reset, watchdog)
    148     LUA_ADD_STR_S(L, system->system_reset, boot_option)
    149     LUA_ADD_STR_S(L, system->system_reset, boot_option_on_limit)
    150 	  LUA_ADD_STR_S(L, system->system_reset, reset_count)
    151 	  LUA_ADD_STR_S(L, system->system_reset, reset_limit)
    152 	  LUA_ADD_STR_S(L, system->system_reset, timer_interval)
    153 	  LUA_ADD_STR_S(L, system->system_reset, timeout)
    154     lua_settable(L,-3);
    155   }
    156 
    157   return 1;
    158 }
    159 
    160 
    161 static int get_base_board_table(lua_State *L, s_dmi *dmi_ptr)
    162 {
    163   s_base_board *base_board = &dmi_ptr->base_board;
    164   int n_dev = sizeof(base_board->devices_information) /
    165               sizeof(base_board->devices_information[0]);
    166   int i, j, has_dev;
    167 
    168   if (!base_board->filled)
    169     return 0;
    170   /* base_board */
    171   lua_newtable(L);
    172   LUA_ADD_STR_P(L, base_board, manufacturer)
    173   LUA_ADD_STR_P(L, base_board, product_name)
    174   LUA_ADD_STR_P(L, base_board, version)
    175   LUA_ADD_STR_P(L, base_board, serial)
    176   LUA_ADD_STR_P(L, base_board, asset_tag)
    177   LUA_ADD_STR_P(L, base_board, location)
    178   LUA_ADD_STR_P(L, base_board, type)
    179 
    180   /* base board features */
    181   lua_pushstring(L, "features");
    182   lua_newtable(L);
    183   get_bool_table(L, base_board_features_strings,
    184                  sizeof(s_base_board_features)/sizeof(bool),
    185                  (bool *)(&base_board->features));
    186   lua_settable(L,-3);
    187 
    188   /* on-board devices */
    189   for (has_dev = 0, i = 0; i < n_dev; i++)
    190     if (*base_board->devices_information[i].type)
    191       has_dev++;
    192 
    193   if (has_dev) {
    194     lua_pushstring(L, "devices");
    195     lua_newtable(L);
    196     for (i = 0, j = 1; i < n_dev; i++) {
    197       if (!*base_board->devices_information[i].type)  /* empty device */
    198         continue;
    199 
    200       lua_pushinteger(L, j++);
    201       lua_newtable(L);
    202       LUA_ADD_STR_S(L, base_board->devices_information[i], type)
    203       LUA_ADD_STR_S(L, base_board->devices_information[i], description)
    204       LUA_ADD_NUM_S(L, base_board->devices_information[i], status)
    205       lua_settable(L,-3);
    206     }
    207     lua_settable(L,-3);
    208   }
    209 
    210   return 1;
    211 }
    212 
    213 
    214 static int get_chassis_table(lua_State *L, s_dmi *dmi_ptr)
    215 {
    216   s_chassis *chassis = &dmi_ptr->chassis;
    217 
    218   if (!chassis->filled)
    219     return 0;
    220   /* chassis */
    221   lua_newtable(L);
    222   LUA_ADD_STR_P(L, chassis, manufacturer)
    223   LUA_ADD_STR_P(L, chassis, type)
    224   LUA_ADD_STR_P(L, chassis, lock)
    225   LUA_ADD_STR_P(L, chassis, version)
    226   LUA_ADD_STR_P(L, chassis, serial)
    227   LUA_ADD_STR_P(L, chassis, asset_tag)
    228   LUA_ADD_STR_P(L, chassis, boot_up_state)
    229   LUA_ADD_STR_P(L, chassis, power_supply_state)
    230   LUA_ADD_STR_P(L, chassis, thermal_state)
    231   LUA_ADD_STR_P(L, chassis, security_status)
    232   LUA_ADD_STR_P(L, chassis, oem_information)
    233   LUA_ADD_NUM_P(L, chassis, height)
    234   LUA_ADD_NUM_P(L, chassis, nb_power_cords)
    235 
    236   return 1;
    237 }
    238 
    239 
    240 static int get_processor_table(lua_State *L, s_dmi *dmi_ptr)
    241 {
    242   s_processor *processor = &dmi_ptr->processor;
    243   s_signature *signature = &processor->signature;
    244 
    245   if (!processor->filled)
    246     return 0;
    247   /* processor */
    248   lua_newtable(L);
    249   LUA_ADD_STR_P(L, processor, socket_designation)
    250   LUA_ADD_STR_P(L, processor, type)
    251   LUA_ADD_STR_P(L, processor, family)
    252   LUA_ADD_STR_P(L, processor, manufacturer)
    253   LUA_ADD_STR_P(L, processor, version)
    254   LUA_ADD_NUM_P(L, processor, external_clock)
    255   LUA_ADD_NUM_P(L, processor, max_speed)
    256   LUA_ADD_NUM_P(L, processor, current_speed)
    257   LUA_ADD_NUM_P(L, processor, voltage_mv)
    258   LUA_ADD_STR_P(L, processor, status)
    259   LUA_ADD_STR_P(L, processor, upgrade)
    260   LUA_ADD_STR_P(L, processor, cache1)
    261   LUA_ADD_STR_P(L, processor, cache2)
    262   LUA_ADD_STR_P(L, processor, cache3)
    263   LUA_ADD_STR_P(L, processor, serial)
    264   LUA_ADD_STR_P(L, processor, part_number)
    265   LUA_ADD_STR_P(L, processor, id)
    266   LUA_ADD_NUM_P(L, processor, core_count)
    267   LUA_ADD_NUM_P(L, processor, core_enabled)
    268   LUA_ADD_NUM_P(L, processor, thread_count)
    269 
    270   /* processor signature */
    271   lua_pushstring(L, "signature");
    272   lua_newtable(L);
    273   LUA_ADD_NUM_P(L, signature, type)
    274   LUA_ADD_NUM_P(L, signature, family)
    275   LUA_ADD_NUM_P(L, signature, model)
    276   LUA_ADD_NUM_P(L, signature, stepping)
    277   LUA_ADD_NUM_P(L, signature, minor_stepping)
    278   lua_settable(L,-3);
    279 
    280   /* processor flags */
    281   lua_pushstring(L, "flags");
    282   lua_newtable(L);
    283   get_bool_table(L, cpu_flags_strings,
    284                  sizeof(s_dmi_cpu_flags)/sizeof(bool),
    285                  (bool *)(&processor->cpu_flags));
    286   lua_settable(L,-3);
    287 
    288   return 1;
    289 }
    290 
    291 
    292 static int get_battery_table(lua_State *L, s_dmi *dmi_ptr)
    293 {
    294   s_battery *battery = &dmi_ptr->battery;
    295 
    296   if (!battery->filled)
    297     return 0;
    298   /* battery */
    299   lua_newtable(L);
    300   LUA_ADD_STR_P(L, battery, location)
    301   LUA_ADD_STR_P(L, battery, manufacturer)
    302   LUA_ADD_STR_P(L, battery, manufacture_date)
    303   LUA_ADD_STR_P(L, battery, serial)
    304   LUA_ADD_STR_P(L, battery, name)
    305   LUA_ADD_STR_P(L, battery, chemistry)
    306   LUA_ADD_STR_P(L, battery, design_capacity)
    307   LUA_ADD_STR_P(L, battery, design_voltage)
    308   LUA_ADD_STR_P(L, battery, sbds)
    309   LUA_ADD_STR_P(L, battery, sbds_serial)
    310   LUA_ADD_STR_P(L, battery, maximum_error)
    311   LUA_ADD_STR_P(L, battery, sbds_manufacture_date)
    312   LUA_ADD_STR_P(L, battery, sbds_chemistry)
    313   LUA_ADD_STR_P(L, battery, oem_info)
    314 
    315   return 1;
    316 }
    317 
    318 
    319 static int get_memory_table(lua_State *L, s_dmi *dmi_ptr)
    320 {
    321   s_memory *memory = dmi_ptr->memory;
    322   int i, j, n_mem = dmi_ptr->memory_count;
    323 
    324   if (n_mem <= 0)  /*  no memory info */
    325     return 0;
    326 
    327   /* memory */
    328   lua_newtable(L);
    329   for (j = 1, i = 0; i < n_mem; i++) {
    330     if (!memory[i].filled)
    331       continue;
    332 
    333     lua_pushinteger(L, j++);
    334     lua_newtable(L);
    335     LUA_ADD_STR_S(L, memory[i], manufacturer)
    336     LUA_ADD_STR_S(L, memory[i], error)
    337     LUA_ADD_STR_S(L, memory[i], total_width)
    338     LUA_ADD_STR_S(L, memory[i], data_width)
    339     LUA_ADD_STR_S(L, memory[i], size)
    340     LUA_ADD_STR_S(L, memory[i], form_factor)
    341     LUA_ADD_STR_S(L, memory[i], device_set)
    342     LUA_ADD_STR_S(L, memory[i], device_locator)
    343     LUA_ADD_STR_S(L, memory[i], bank_locator)
    344     LUA_ADD_STR_S(L, memory[i], type)
    345     LUA_ADD_STR_S(L, memory[i], type_detail)
    346     LUA_ADD_STR_S(L, memory[i], speed)
    347     LUA_ADD_STR_S(L, memory[i], serial)
    348     LUA_ADD_STR_S(L, memory[i], asset_tag)
    349     LUA_ADD_STR_S(L, memory[i], part_number)
    350     lua_settable(L,-3);
    351   }
    352   return 1;
    353 }
    354 
    355 
    356 static int get_memory_module_table(lua_State *L, s_dmi *dmi_ptr)
    357 {
    358   s_memory_module *memory_module = dmi_ptr->memory_module;
    359   int i, j, n_mem = dmi_ptr->memory_module_count;
    360 
    361   if (n_mem <= 0)  /*  no memory module info */
    362     return 0;
    363 
    364   /* memory module */
    365   lua_newtable(L);
    366   for (j = 1, i = 0; i < n_mem; i++) {
    367     if (!memory_module[i].filled)
    368       continue;
    369 
    370     lua_pushinteger(L, j++);
    371     lua_newtable(L);
    372     LUA_ADD_STR_S(L, memory_module[i], socket_designation)
    373     LUA_ADD_STR_S(L, memory_module[i], bank_connections)
    374     LUA_ADD_STR_S(L, memory_module[i], speed)
    375     LUA_ADD_STR_S(L, memory_module[i], type)
    376     LUA_ADD_STR_S(L, memory_module[i], installed_size)
    377     LUA_ADD_STR_S(L, memory_module[i], enabled_size)
    378     LUA_ADD_STR_S(L, memory_module[i], error_status)
    379     lua_settable(L,-3);
    380   }
    381   return 1;
    382 }
    383 
    384 
    385 static int get_cache_table(lua_State *L, s_dmi *dmi_ptr)
    386 {
    387   s_cache *cache = dmi_ptr->cache;
    388   int i, n_cache = dmi_ptr->cache_count;
    389 
    390   if (n_cache <= 0)  /*  no cache info */
    391     return 0;
    392 
    393   /* memory */
    394   lua_newtable(L);
    395   for (i = 0; i < n_cache; i++) {
    396     lua_pushinteger(L, i + 1);
    397     lua_newtable(L);
    398     LUA_ADD_STR_S(L, cache[i], socket_designation)
    399     LUA_ADD_STR_S(L, cache[i], configuration)
    400     LUA_ADD_STR_S(L, cache[i], mode)
    401     LUA_ADD_STR_S(L, cache[i], location)
    402     LUA_ADD_NUM_S(L, cache[i], installed_size)
    403     LUA_ADD_NUM_S(L, cache[i], max_size)
    404     LUA_ADD_STR_S(L, cache[i], supported_sram_types)
    405     LUA_ADD_STR_S(L, cache[i], installed_sram_types)
    406     LUA_ADD_NUM_S(L, cache[i], speed)
    407     LUA_ADD_STR_S(L, cache[i], error_correction_type)
    408     LUA_ADD_STR_S(L, cache[i], system_type)
    409     LUA_ADD_STR_S(L, cache[i], associativity)
    410     lua_settable(L,-3);
    411   }
    412   return 1;
    413 }
    414 
    415 
    416 static int get_hardware_security_table(lua_State *L, s_dmi *dmi_ptr)
    417 {
    418   if (!dmi_ptr->hardware_security.filled)
    419     return 0;
    420   /* hardware_security */
    421   lua_newtable(L);
    422   LUA_ADD_STR_S(L, dmi_ptr->hardware_security, power_on_passwd_status)
    423 	LUA_ADD_STR_S(L, dmi_ptr->hardware_security, keyboard_passwd_status)
    424 	LUA_ADD_STR_S(L, dmi_ptr->hardware_security, administrator_passwd_status)
    425 	LUA_ADD_STR_S(L, dmi_ptr->hardware_security, front_panel_reset_status)
    426 
    427   return 1;
    428 }
    429 
    430 
    431 static int get_dmi_info_table(lua_State *L, s_dmi *dmi_ptr)
    432 {
    433   dmi_table *dmitable = &dmi_ptr->dmitable;
    434 
    435   /* dmi info */
    436   lua_newtable(L);
    437   LUA_ADD_NUM_P(L, dmitable, num)
    438   LUA_ADD_NUM_P(L, dmitable, len)
    439   LUA_ADD_NUM_P(L, dmitable, ver)
    440   LUA_ADD_NUM_P(L, dmitable, base)
    441   LUA_ADD_NUM_P(L, dmitable, major_version)
    442   LUA_ADD_NUM_P(L, dmitable, minor_version)
    443 
    444   return 1;
    445 }
    446 
    447 
    448 static int get_ipmi_table(lua_State *L, s_dmi *dmi_ptr)
    449 {
    450   s_ipmi *ipmi = &dmi_ptr->ipmi;
    451 
    452   if (!ipmi->filled)
    453     return 0;
    454   /* ipmi */
    455   lua_newtable(L);
    456   LUA_ADD_STR_P(L, ipmi, interface_type)
    457   LUA_ADD_NUM_P(L, ipmi, major_specification_version)
    458   LUA_ADD_NUM_P(L, ipmi, minor_specification_version)
    459   LUA_ADD_NUM_P(L, ipmi, I2C_slave_address)
    460   LUA_ADD_NUM_P(L, ipmi, nv_address)
    461   LUA_ADD_NUM_P(L, ipmi, base_address)
    462   LUA_ADD_NUM_P(L, ipmi, irq)
    463 
    464   return 1;
    465 }
    466 /*
    467 ** {======================================================
    468 ** End of DMI subtables
    469 ** =======================================================
    470 */
    471 
    472 
    473 static int dmi_gettable(lua_State *L)
    474 {
    475   s_dmi dmi;
    476 
    477   lua_newtable(L);
    478 
    479   if ( ! dmi_iterate(&dmi) ) {
    480           printf("No DMI Structure found\n");
    481           return -1;
    482   }
    483 
    484   parse_dmitable(&dmi);
    485 
    486   LUA_ADD_NUM_S(L, dmi, memory_module_count)
    487   LUA_ADD_NUM_S(L, dmi, memory_count)
    488   LUA_ADD_NUM_S(L, dmi, cache_count)
    489   LUA_ADD_STR_S(L, dmi, oem_strings)
    490 
    491   LUA_ADD_TABLE(L, &dmi, bios)
    492   LUA_ADD_TABLE(L, &dmi, system)
    493   LUA_ADD_TABLE(L, &dmi, base_board)
    494   LUA_ADD_TABLE(L, &dmi, chassis)
    495   LUA_ADD_TABLE(L, &dmi, processor)
    496   LUA_ADD_TABLE(L, &dmi, battery)
    497   LUA_ADD_TABLE(L, &dmi, memory)
    498   LUA_ADD_TABLE(L, &dmi, memory_module)
    499   LUA_ADD_TABLE(L, &dmi, cache)
    500   LUA_ADD_TABLE(L, &dmi, ipmi)
    501   LUA_ADD_TABLE(L, &dmi, hardware_security)
    502   LUA_ADD_TABLE(L, &dmi, dmi_info)
    503 
    504   /* set global variable: lua_setglobal(L, "dmitable"); */
    505 
    506   /* return number of return values on stack */
    507   return 1;
    508 }
    509 
    510 
    511 static int dmi_supported(lua_State *L)
    512 {
    513   s_dmi dmi;
    514 
    515   if ( dmi_iterate(&dmi) ) {
    516     lua_pushboolean(L, 1);
    517   } else {
    518     lua_pushboolean(L, 0);
    519   }
    520   return 1;
    521 }
    522 
    523 
    524 static const luaL_Reg dmilib[] = {
    525   {"gettable", dmi_gettable},
    526   {"supported", dmi_supported},
    527   {NULL, NULL}
    528 };
    529 
    530 
    531 LUALIB_API int luaopen_dmi (lua_State *L) {
    532   luaL_newlib(L, dmilib);
    533   return 1;
    534 }
    535 
    536