aboutsummaryrefslogblamecommitdiffstats
path: root/cmd/cmd_lua.c
blob: 8127af626dff35728900be5696a07fb4ecf1ce4a (plain) (tree)
1
2

                    






























































































































                                                                                           
                                





                          


                                                                                


                  
                                                                           
 
                                                
 
                                                                          
 


                                                                                         














                                                 



                         

                        
 

                          
                              
              
 



                                              
 
                 
 





                          
 



                                                                                
                                             
 
                     
   

                                  

   








                                                                                


                                        















                                                                                

                                      




                                      
 

                           


             
#include "cmd_lua.h"

void fatal_error(lua_State *L, char *msg)
{
  fprintf(stderr, "\n FATAL ERROR:\n %s %s\n\n", msg, lua_tostring(L,-1));
}

int check_table_key_string(lua_State *L, const char *key, const char **value, size_t *size)
{
  const char *result;
  size_t result_sz;
  int t;

  lua_pushstring(L, key);
  lua_gettable(L,1);
  t = lua_type(L,-1);
  if (t == LUA_TSTRING)
  {
    result = luaL_checklstring(L,-1,&result_sz);
    *value = result; 
    *size  = result_sz;
    return 0;
  } else
  {
    *value = NULL;
    *size = 0;
    return -1;
  }
}

int check_table_key_integer(lua_State *L, const char *key, int *value)
{
  int result;
  int t;

  lua_pushstring(L, key);
  lua_gettable(L,1);
  if ((t = lua_type(L, -1)) == LUA_TNUMBER)
  {
    result = luaL_checkinteger(L,-1);
    *value = result;
    return 0;
  }
  
  return -1;
}

int verify_name(const char *lua_name)
{
  int i;

  //check if all symbols are alphanumeric
  for (i=0;i<strlen(lua_name);i++)
  {
    if (!isdigit(lua_name[i]) && !isalpha(lua_name[i]))
    {
      return -1;
    }
  }
  return 0;
}

int lua_excute(const char *fname, rpc_call_request *req, rpc_call_response **resp)
{
  lua_State *L;
  sds lua_full_path = sdsempty();

  L = luaL_newstate();
  luaL_openlibs(L);

  if (verify_name(fname) != 0)
  {
    return -1;
  }

  lua_full_path = sdscat(lua_full_path, "lua/");
  lua_full_path = sdscat(lua_full_path, fname);
  lua_full_path = sdscat(lua_full_path, ".lua");

  if (luaL_loadfile(L,lua_full_path))
  {
    fatal_error(L, "load file failed");
    sdsfree(lua_full_path);
    return -1;
  }
  sdsfree(lua_full_path);

  if (lua_pcall(L,0,0,0))
  {
    fatal_error(L, "lua_pcall failed");
    return -1;
  }

  lua_getglobal(L, "callback");
  lua_newtable(L);

  lua_pushstring(L,"method");
  lua_pushstring(L, req->method);
  lua_settable(L,-3);

  lua_pushstring(L,"params");
  lua_pushstring(L, req->params);
  lua_settable(L,-3);

  lua_pushstring(L,"id");
  lua_pushinteger(L, req->id);
  lua_settable(L,-3);

  lua_pushstring(L,"user");
  lua_pushstring(L, req->user);
  lua_settable(L,-3);

  lua_pushstring(L,"mask");
  lua_pushstring(L, req->mask);
  lua_settable(L,-3);

  lua_pushstring(L,"server");
  lua_pushstring(L, req->server);
  lua_settable(L,-3);

  if (lua_pcall(L,1,1,0))
  {
    fatal_error(L, "cant call callback function from file");
    return -1;
  }

  {
    int t;
    int top = lua_gettop(L);
    //int len = lua_rawlen(L,1);

    if (top == 1)
    {
      t = lua_type(L,1);
      if (t == LUA_TTABLE)
      {
       
        char *r_result; //this care unchangable stupid C dont know what is const
        char *r_error;  //this unchangable stupid C dont know what is const
        int r_id;
        size_t sz;

        check_table_key_string(L, "result", (const char **)&r_result, &sz);

        check_table_key_integer(L, "id", &r_id);

        check_table_key_string(L, "error",  (const char **)&r_error, &sz);

        if (r_result == NULL) r_result = "!";
        if (r_error == NULL) r_error = "!";
        *resp = rpc_call_resp_new(alloc_new_str(r_result), alloc_new_str(r_error), r_id);
        (*resp)->user = alloc_new_str(" ");
        (*resp)->server = alloc_new_str(" ");
        (*resp)->mask = alloc_new_str(" ");

      }
    } else
    {
      fatal_error(L,"Some unexpected argumetns");
      return -1;
    }
  }

  lua_close(L);
  return 0;
}

void *cmd_lua(void *data)
{
  char *ret = NULL;
  char *req_data = NULL;
  int fret;

  int count;
  sds params = sdsempty();
  sds out_result = sdsempty();
  sds *tokens;

  rpc_call_request  *req  = NULL;
  rpc_call_response *resp = NULL;
  netbyte_store *nb_req = NULL, *nb_resp=NULL;
  char *nb_buf = NULL;

  PRINT("LUA\n");

  req_data = (char *)data;
  if (!req_data)
  {
    PERM();
    return NULL;
  }

  //----------------------------------------------------------------------------
  //prepare request
  nb_req = malloc(sizeof(netbyte_store));
  nb_init(nb_req);
  nb_load(nb_req, (unsigned char *)req_data);

  if (nb_req == NULL)
  {
    ERROR("implement response\n");
    return NULL;
  }

  fret = rpc_call_req_unmarsh(nb_req, &req);
  if (fret != 0)
  {
    ERROR("Invalid request format\n");
    return NULL;
  }

  //----------------------------------------------------------------------------
  //main code
  params = sdsnew(req->params);
  tokens = sdssplitargs(params, &count);

  if (-1 == lua_excute(tokens[1], req, &resp))
  {
    resp = rpc_call_resp_new(out_result,"None",1);
    resp->user = alloc_new_str(" ");
    resp->server = alloc_new_str(" ");
    resp->mask = alloc_new_str(" ");
  }

  sdsfree(params);
  sdsfreesplitres(tokens, count);

  //----------------------------------------------------------------------------
  //prepare response
  nb_resp = malloc(sizeof(netbyte_store));
  nb_init(nb_resp);

  rpc_call_resp_marsh(resp, &nb_resp);

  nb_buf = (char *)nb_create(nb_resp);
  if (nb_buf)
  {
    ret = nb_buf;
  }

  nb_free(nb_resp);
  rpc_call_resp_free(resp);

  return ret;
}