Jump the Great Firewall "step14 embedded in Lua"

Source: Internet
Author: User
Tags syslog

First of all, there is a need to advertise, Qtun's website has been opened, the function is gradually added.

First, the reason for embedding Lua

Because of the increasing number of configurable parameters of the Qtun, it is necessary to write parameters to the configuration file. And because C is not good at string processing, it has added a lightweight Lua scripting language, while embedding Lua is more useful for adding support for third-party plug-ins.

Second, the code changes

  1. Wrapper initialization function
    extern int Init_path (char* cmd), extern int Init_lua (), extern void Show_logo (), extern void Conf_init (library_conf_t* conf );
    1. The path where the Qtun program is passed into the Init_path and is converted to Realpath after it is recorded in Qtun->this_path
    2. Init_lua creates a Lua_state object and invokes the Scripts/qtun.lua script to initialize it, and finally calls the Script_global_init function to initialize the LUA environment
    3. Show_logo call the Scripts/logo.lua script to print out the Qtun logo ^o^
    4. Set the initial value for the incoming conf variable in Conf_init, such as the default port of 6687, etc.
  2. The Script_global_init function Script_global_init function is called during Init_lua to initialize the LUA environment
    int Script_global_init (lua_state* lua) {    load_lib (lua, "_g", luaopen_base);    Load_lib (LUA, Lua_tablibname, luaopen_table);    Load_lib (LUA, Lua_strlibname, luaopen_string);    Load_lib (LUA, Lua_iolibname, luaopen_io);        Lua_pushcfunction (LUA, _syslog);    Lua_setglobal (LUA, "_syslog");        Init_qtun_state (LUA);    Init_qtun_conf (LUA);    Init_qtun_log (LUA);    return 1;}
      1. Here, first load the base Lua library
      2. Then join the Custom function _syslog
      3. Create Qtun.state, qtun.conf, and Qtun.log objects by LUA.MD documents that all properties in Qtun.state are read-only, Qtun.conf.conf_file properties are read-only, and others are readable and writable. Some log level definitions for syslog are included in the Qtun.log.
      4. Let's take a look at the implementation of these three functions
        static void Init_qtun_state (lua_state* lua) {get_qtun_obj (LUA);    Lua_pushstring (LUA, "state");    Lua_newtable (LUA);    Lua_newtable (LUA);    Lua_pushstring (LUA, "__index");    Lua_pushcfunction (LUA, state_get);    Lua_settable (LUA,-3);        Lua_setmetatable (LUA,-2);    Lua_settable (LUA,-3); Lua_pop (LUA, 1);}    static void init_qtun_conf (lua_state* lua) {get_qtun_obj (LUA);    Lua_pushstring (LUA, "conf");        Lua_newtable (LUA);    Lua_newtable (LUA);    Lua_pushstring (LUA, "__index");    Lua_pushcfunction (LUA, conf_get);    Lua_settable (LUA,-3);    Lua_pushstring (LUA, "__newindex");    Lua_pushcfunction (LUA, conf_set);    Lua_settable (LUA,-3);        Lua_setmetatable (LUA,-2);    Lua_settable (LUA,-3); Lua_pop (LUA, 1);}        static void Init_qtun_log (lua_state* lua) {int new_log = 0;    Get_qtun_obj (LUA);    Lua_pushstring (LUA, "log");    Lua_gettable (LUA,-2);        if (Lua_isnil (LUA,-1)) {Lua_pop (LUA, 1);        Lua_pushstring (LUA, "log"); Lua_newtAble (LUA);    New_log = 1;    } push_log_level (Lua, "Log_emerg", 0);    Push_log_level (LUA, "Log_alert", 1);    Push_log_level (LUA, "Log_crit", 2);    Push_log_level (LUA, "Log_err", 3);    Push_log_level (LUA, "log_warning", 4);    Push_log_level (LUA, "Log_notice", 5);    Push_log_level (LUA, "Log_info", 6);    Push_log_level (LUA, "Log_debug", 7);    if (New_log) lua_settable (LUA,-3);    Lua_pop (LUA, 1); }
    From the code: Qtun.state and qtun.conf map C objects to Lua through MetaTable, and only the constants of the log level are defined in Qtun.log
  3. Script_load_config function script_load_config function load configuration file by calling Scripts/load_config.lua script
    int Script_load_config (lua_state* lua, library_conf_t* conf, const char* file_path) {    char path[max_path];    Lua_pushlightuserdata (LUA, conf);    Lua_setglobal (LUA, "__conf__");        strcpy (path, qtun->this_path);    strcat (Path, "Scripts/load_config.lua");    if (Lual_dofile (LUA, path)! = 0)    {        fprintf (stderr, "%s\n", Lua_tostring (Qtun->lua,-1));        Lua_close (Qtun->lua);        Exit (1);    }    return 1;}
  4. Let's take a look at the whole process of the main function

Third, Lua script

Finally, let's take a look at the three Lua scripts.

  1. Logo.lua
    Print (' ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ') print (' ┃ ...   .....  .   .  .  .  ┃ ') print (' ┃  ...  ┃ ') print (' ┃  ...  ┃ ') print (' ┃     ..... ...   .  .  ┃ ') print (' ┃                             ┃ ') print (' ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ ')
    This logo is not very love ^_^
  2. Qtun.lua
    Qtun = {    log = {        syslog = function (level, FMT, ...)            _syslog (Level, String.Format (FMT, ...))        End    }}function Trim (s)    return s:gsub (' ^%s* (.-)%s*$ ', '%1 ') endfunction is_numeric (s)    return Tonumber (s) ~= nilendfunction is_string (s)    return not is_numeric (s) end
    Some public functions are packaged here
  3. Load_config.lua
    Local function Append_key_value (key, value) if value = = ' true ' then value = true ElseIf value = = ' false ' Then        Value = False ElseIf is_numeric (value) then value = Tonumber (value) elseif key = = ' Log_level ' Then If is_string (value) then value = Qtun.log[value] End end Qtun.conf[key] = valueendlocal funct  Ion Set_true (key) Qtun.conf[key] = trueendlocal file = Io.open (Qtun.conf.conf_file, ' R ') while True Do::start:: Local     line = File:read (' *line ') if line = = nil and break end local len = #line local key = ' local first = ' Local start = 0 Local Have_key = False local Have_value = False local added = False local j = 0 for i=0  , len do j = i local ch = line:sub (i + 1, i + 1) if first = = "and ch ~=" then first = CH End If ch = = ' # ' then If Trim (line:sub (start, i)) = = ' Then goto start end Have_v Alue = True IF Have_key then Append_key_value (key, Trim (line:sub (start, i))) Else Set_true (tri  M (line:sub (Start, i))) End added = True break ElseIf ch = = "Then key" = Trim (line:sub (start, i)) if key = = "Then error (' Missing key ') end hav        E_key = True start = i + 2 end End If first = = ' # ' then goto start End If not added then            If not Have_key then local key = Trim (Line:sub (Start, J)) if key = = "Then goto start end Set_true (key) Else append_key_value (key, Trim (Line:sub (Start, j))) End Endendfile:close ()
    The primary logic for parsing the configuration file is here.

Iv. Complete code

Full code can be viewed in STEP14

Jump the Great Firewall "step14 embedded in Lua"

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.