Ejemplo n.º 1
0
/*-------------------------------------------------------------------------*/
int
tls_continue_handshake (interactive_t *ip)

/* Continue the TLS initialisation handshake for interactive <ip>.
 * Return a negative error code if the connection can not be set up.
 * Return 0 if the connection is still begin set up.
 * Return 1 if the connection is now active (or if no secure connection
 * had been requested).
 *
 * If a callback is set for <ip> and connection comes out of the handshaking
 * state, it will be called with the result code.
 */

{
    int ret;

    if (ip->tls_status != TLS_HANDSHAKING)
        return 1;

    ret = tls_do_handshake(ip);
    if (!ret)
	return 0;


    if (ret < 0)
    {
        ip->tls_status = TLS_INACTIVE;
    }
    else
    {
        ip->tls_status = TLS_ACTIVE;
    }

    /* If the connection is no longer in handshake, execute the callback */
    if (ip->tls_cb != NULL)
    {
        tls_cb_handler_t * handler;

        xallocate( handler, sizeof(*handler)
                 , "TLS: Callback handler protector");
        handler->cb = ip->tls_cb;
        ip->tls_cb = NULL;
            /* Protect the callback during its execution. */

        push_error_handler (handle_tls_cb_error, &(handler->head));

        push_number(inter_sp, ret < 0 ? ret : 0);
        push_ref_object(inter_sp, ip->ob, "tls_handshake");

        command_giver = ip->ob;
        current_interactive = ip->ob;
        /* Set current_interactive as it would be for a normal logon() call. */

        (void)apply_callback(handler->cb, 2);

        if (!(ip->ob->flags & O_DESTRUCTED))
            print_prompt();

        command_giver = NULL;

        free_svalue(inter_sp); inter_sp--; /* free the callback */
    }

    return ret;
} /* tls_continue_handshake() */
Ejemplo n.º 2
0
Archivo: main.c Proyecto: jtniehof/dpkg
void commandfd(const char *const *argv) {
  jmp_buf ejbuf;
  struct varbuf linevb = VARBUF_INIT;
  const char * pipein;
  const char **newargs = NULL;
  char *ptr, *endptr;
  FILE *in;
  unsigned long infd;
  int c, lno, i;
  bool skipchar;
  void (*actionfunction)(const char *const *argv);

  pipein = *argv++;
  if (pipein == NULL)
    badusage(_("--command-fd takes one argument, not zero"));
  if (*argv)
    badusage(_("--command-fd only takes one argument"));
  errno = 0;
  infd = strtoul(pipein, &endptr, 10);
  if (pipein == endptr || *endptr || infd > INT_MAX)
    ohshite(_("invalid integer for --%s: `%.250s'"), "command-fd", pipein);
  if ((in= fdopen(infd, "r")) == NULL)
    ohshite(_("couldn't open `%i' for stream"), (int) infd);

  if (setjmp(ejbuf)) { /* expect warning about possible clobbering of argv */
    error_unwind(ehflag_bombout); exit(2);
  }

  for (;;) {
    bool mode = false;
    int argc= 1;
    lno= 0;
    push_error_handler(&ejbuf, print_error_fatal, NULL);

    do { c= getc(in); if (c == '\n') lno++; } while (c != EOF && isspace(c));
    if (c == EOF) break;
    if (c == '#') {
      do { c= getc(in); if (c == '\n') lno++; } while (c != EOF && c != '\n');
      continue;
    }
    varbufreset(&linevb);
    do {
      varbufaddc(&linevb,c);
      c= getc(in);
      if (c == '\n') lno++;
      if (isspace(c)) argc++;  /* This isn't fully accurate, but overestimating can't hurt. */
    } while (c != EOF && c != '\n');
    if (c == EOF) ohshit(_("unexpected eof before end of line %d"),lno);
    if (!argc) continue;
    varbufaddc(&linevb,0);
    newargs = m_realloc(newargs, sizeof(const char *) * (argc + 1));
    argc= 1;
    ptr= linevb.buf;
    endptr= ptr + linevb.used;
    skipchar = false;
    while(ptr < endptr) {
      if (skipchar) {
	skipchar = false;
      } else if (*ptr == '\\') {
	memmove(ptr, (ptr+1), (linevb.used-(linevb.buf - ptr)-1));
	endptr--;
	skipchar = true;
	continue;
      } else if (isspace(*ptr)) {
	if (mode == true) {
	  *ptr = '\0';
	  mode = false;
	}
      } else {
	if (mode == false) {
	  newargs[argc]= ptr;
	  argc++;
	  mode = true;
	}
      }
      ptr++;
    }
    *ptr = '\0';
    newargs[argc++] = NULL;

/* We strdup each argument, but never free it, because the error messages
 * contain references back to these strings.  Freeing them, and reusing
 * the memory, would make those error messages confusing, to say the
 * least.
 */
    for(i=1;i<argc;i++)
      if (newargs[i])
        newargs[i] = m_strdup(newargs[i]);

    cipaction= NULL;
    myopt((const char *const**)&newargs,cmdinfos);
    if (!cipaction) badusage(_("need an action option"));

    actionfunction= (void (*)(const char* const*))cipaction->farg;
    actionfunction(newargs);
    set_error_display(NULL, NULL);
    error_unwind(ehflag_normaltidy);
  }
}
Ejemplo n.º 3
0
/*-------------------------------------------------------------------------*/
svalue_t * 
v_sl_exec (svalue_t * sp, int num_arg) 

/* EFUN sl_exec()
 *
 *   mixed* sl_exec(string statement, ...)
 *
 * Executes the SQL statement <statement> for the current
 * SQLite database. The SQL statement may contain wildcards like
 * '?' and '?nnn', where 'nnn' is an integer. These wildcards
 * can be given as further parameters to sl_exec. With '?nnn'
 * the number of a specific parameter can be given, the first
 * parameter has number 1.
 * 
 * If the statement returns data, sl_exec returns an array
 * with each row (which is itself an array of columns) as 
 * an element.
 */

{
    svalue_t *argp;
    sqlite_dbs_t *db;
    sqlite3_stmt *stmt;
    const char* tail;
    int err, rows, cols, num;
    struct sl_exec_cleanup_s * rec_data;
    vector_t * result;

    argp = sp - num_arg + 1; /* First argument: the SQL query */
    
    db = find_db (current_object);
    if (!db)
        errorf("The current object doesn't have a database open.\n");
    
    err = sqlite3_prepare(db->db, get_txt(argp->u.str), mstrsize(argp->u.str),
        &stmt, &tail);
    if(err)
    {
        const char* msg = sqlite3_errmsg(db->db);
        if(stmt)
            sqlite3_finalize(stmt);
        errorf("sl_exec: %s\n", msg);
        /* NOTREACHED */
    }
    
    /* Now bind all parameters. */
    for(argp++, num=1; argp <= sp; argp++, num++)
    {
        switch(argp->type)
        {
        default:
            sqlite3_finalize(stmt);
            errorf("Bad argument %d to sl_exec(): type %s\n",
                num+1, typename(argp->type));
            break; /* NOTREACHED */

        case T_FLOAT:
            sqlite3_bind_double(stmt, num, READ_DOUBLE(argp));
            break;

        case T_NUMBER:
            if (sizeof(argp->u.number) > 4)
                sqlite3_bind_int64(stmt, num, argp->u.number);
            else
                sqlite3_bind_int(stmt, num, argp->u.number);
            break;
    
        case T_STRING:
            sqlite3_bind_text(stmt, num, get_txt(argp->u.str),
                mstrsize(argp->u.str), SQLITE_STATIC);
            break;
        }
    }
    
    rows = 0;
    cols = sqlite3_column_count(stmt);

    rec_data = xalloc(sizeof(*rec_data));
    if(!rec_data)
    {
        sqlite3_finalize(stmt);
        errorf("(sl_exec) Out of memory: (%lu bytes) for cleanup structure\n",
            (unsigned long) sizeof(*rec_data));
    }
    rec_data->rows = NULL;
    rec_data->stmt = stmt;
    
    sp = push_error_handler(sl_exec_cleanup, &(rec_data->head));
    
    while((err = sqlite3_step(stmt)) == SQLITE_ROW)
    {
        int col;
        sqlite_rows_t *this_row;

        rows++;
        this_row = pxalloc(sizeof(*this_row));
        if(!this_row)
            errorf("(sl_exec) Out of memory: (%lu bytes)\n",
                (unsigned long) sizeof(*this_row));

        this_row->last = rec_data->rows;
        rec_data->rows = this_row;
        this_row->row = NULL; /* Because allocate_array may throw an error. */

        this_row->row = allocate_array(cols);
        if(!this_row->row)
            errorf("(sl_exec) Out of memory: row vector\n");
    
        for(col = 0; col < cols; col++)
        {
            svalue_t * entry;
            STORE_DOUBLE_USED;

            entry = this_row->row->item + col;

            switch(sqlite3_column_type(stmt, col))
            {
            default:
                errorf( "sl_exec: Unknown type %d.\n"
                      , sqlite3_column_type(stmt, col));
                break;

            case SQLITE_BLOB:
                errorf("sl_exec: Blob columns are not supported.\n");
                break;

            case SQLITE_INTEGER:
                if (sizeof(entry->u.number) >= 8)
                    put_number(entry, sqlite3_column_int64(stmt, col));
                else
                    put_number(entry, sqlite3_column_int(stmt, col));
                break;

           case SQLITE_FLOAT:
                entry->type = T_FLOAT;
                STORE_DOUBLE(entry, sqlite3_column_double(stmt, col));
                break;

            case SQLITE_TEXT:
                put_c_n_string( entry
                              , (char *)sqlite3_column_text(stmt, col)
                              , sqlite3_column_bytes(stmt, col));
                break;

            case SQLITE_NULL:
                /* All elements from this_row->row are initialized to 0. */
                break;
            }
        }
    }

    sqlite3_finalize(stmt);
    rec_data->stmt = NULL;
    
    switch(err)
    {
    default:
        errorf("sl_exec: Unknown return code from sqlite3_step: %d.\n", err);
        break;

    case SQLITE_BUSY:
        errorf("sl_exec: Database is locked.\n");
        break;

    case SQLITE_ERROR:
        errorf("sl_exec: %s\n", sqlite3_errmsg(db->db));
        break;

    case SQLITE_MISUSE:
        errorf("sl_exec: sqlite3_step was called inappropriately.\n");
        break;

    case SQLITE_DONE:
        break;
    }

    if(rows)
    {
        sqlite_rows_t *this_row;

        result = allocate_array(rows);
        if(!result)
            errorf("(sl_exec) Out of memory: result vector\n");

        this_row = rec_data->rows;
        while(rows--)
        {
            put_array(result->item + rows, this_row->row);
            this_row->row = NULL;
            this_row = this_row->last;
        }
    }
    else
        result = NULL;

    // Pop arguments and our error handler.
    // Our error handler gets called and cleans the row stuff.
    sp = pop_n_elems(num_arg + 1, sp) + 1; 
 
    if(rows)
        put_array(sp,result);
    else
        put_number(sp, 0);

    return sp;
} /* v_sl_exec() */
Ejemplo n.º 4
0
// Ctor, initialization
lua_kernel_base::lua_kernel_base()
 : mState(luaL_newstate())
 , cmd_log_()
{
	get_lua_kernel_base_ptr(mState) = this;
	lua_State *L = mState;

	cmd_log_ << "Initializing " << my_name() << "...\n";

	// Open safe libraries.
	// Debug and OS are not, but most of their functions will be disabled below.
	cmd_log_ << "Adding standard libs...\n";

	static const luaL_Reg safe_libs[] {
		{ "",       luaopen_base   },
		{ "table",  luaopen_table  },
		{ "string", luaopen_string },
		{ "math",   luaopen_math   },
		{ "coroutine",   luaopen_coroutine   },
		{ "debug",  luaopen_debug  },
		{ "os",     luaopen_os     },
		{ "utf8",	luaopen_utf8   }, // added in Lua 5.3
		{ nullptr, nullptr }
	};
	for (luaL_Reg const *lib = safe_libs; lib->func; ++lib)
	{
		luaL_requiref(L, lib->name, lib->func, 1);
		lua_pop(L, 1);  /* remove lib */
	}

	// Disable functions from os which we don't want.
	lua_getglobal(L, "os");
	lua_pushnil(L);
	while(lua_next(L, -2) != 0) {
		lua_pop(L, 1);
		char const* function = lua_tostring(L, -1);
		if(strcmp(function, "clock") == 0 || strcmp(function, "date") == 0
			|| strcmp(function, "time") == 0 || strcmp(function, "difftime") == 0) continue;
		lua_pushnil(L);
		lua_setfield(L, -3, function);
	}
	lua_pop(L, 1);

	// Disable functions from debug which we don't want.
	lua_getglobal(L, "debug");
	lua_pushnil(L);
	while(lua_next(L, -2) != 0) {
		lua_pop(L, 1);
		char const* function = lua_tostring(L, -1);
		if(strcmp(function, "traceback") == 0 || strcmp(function, "getinfo") == 0) continue;	//traceback is needed for our error handler
		lua_pushnil(L);										//getinfo is needed for ilua strict mode
		lua_setfield(L, -3, function);
	}
	lua_pop(L, 1);

	// Delete dofile and loadfile.
	lua_pushnil(L);
	lua_setglobal(L, "dofile");
	lua_pushnil(L);
	lua_setglobal(L, "loadfile");

	// Store the error handler.
	cmd_log_ << "Adding error handler...\n";
	push_error_handler(L);

	// Create the gettext metatable.
	cmd_log_ << lua_common::register_gettext_metatable(L);

	// Create the tstring metatable.
	cmd_log_ << lua_common::register_tstring_metatable(L);


	lua_settop(L, 0);

	// Define the CPP_function metatable ( so we can override print to point to a C++ member function, add "show_dialog" for this kernel, etc. )
	cmd_log_ << "Adding boost function proxy...\n";

	lua_cpp::register_metatable(L);

	// Add some callback from the wesnoth lib
	cmd_log_ << "Registering basic wesnoth API...\n";

	static luaL_Reg const callbacks[] {
		{ "compare_versions",         &intf_compare_versions         		},
		{ "debug",                    &intf_wml_tostring                           },
		{ "deprecated_message",       &intf_deprecated_message              },
		{ "have_file",                &lua_fileops::intf_have_file          },
		{ "read_file",                &lua_fileops::intf_read_file          },
		{ "textdomain",               &lua_common::intf_textdomain   		},
		{ "tovconfig",                &lua_common::intf_tovconfig		},
		{ "get_dialog_value",         &lua_gui2::intf_get_dialog_value		},
		{ "set_dialog_tooltip",       &lua_gui2::intf_set_dialog_tooltip	},
		{ "set_dialog_active",        &lua_gui2::intf_set_dialog_active		},
		{ "set_dialog_visible",       &lua_gui2::intf_set_dialog_visible    },
		{ "add_dialog_tree_node",     &lua_gui2::intf_add_dialog_tree_node	},
		{ "add_widget_definition",    &lua_gui2::intf_add_widget_definition },
		{ "set_dialog_callback",      &lua_gui2::intf_set_dialog_callback	},
		{ "set_dialog_canvas",        &lua_gui2::intf_set_dialog_canvas		},
		{ "set_dialog_focus",         &lua_gui2::intf_set_dialog_focus      },
		{ "set_dialog_markup",        &lua_gui2::intf_set_dialog_markup		},
		{ "set_dialog_value",         &lua_gui2::intf_set_dialog_value		},
		{ "remove_dialog_item",       &lua_gui2::intf_remove_dialog_item    },
		{ "dofile",                   &dispatch<&lua_kernel_base::intf_dofile>           },
		{ "require",                  &dispatch<&lua_kernel_base::intf_require>          },
		{ "kernel_type",              &dispatch<&lua_kernel_base::intf_kernel_type>          },
		{ "show_dialog",              &lua_gui2::show_dialog   },
		{ "show_menu",                &lua_gui2::show_menu  },
		{ "show_message_dialog",      &lua_gui2::show_message_dialog },
		{ "show_popup_dialog",        &lua_gui2::show_popup_dialog   },
		{ "show_story",               &lua_gui2::show_story          },
		{ "show_message_box",         &lua_gui2::show_message_box    },
		{ "show_lua_console",	      &dispatch<&lua_kernel_base::intf_show_lua_console> },
		{ "compile_formula",          &lua_formula_bridge::intf_compile_formula},
		{ "eval_formula",             &lua_formula_bridge::intf_eval_formula},
		{ "name_generator",           &intf_name_generator           },
		{ "random",                   &intf_random                   },
		{ "wml_matches_filter",       &intf_wml_matches_filter       },
		{ "log",                      &intf_log                      },
		{ "get_image_size",           &intf_get_image_size           },
		{ "get_time_stamp",           &intf_get_time_stamp           },
		{ "format",                   &intf_format                   },
		{ "format_conjunct_list",     &intf_format_list<true>        },
		{ "format_disjunct_list",     &intf_format_list<false>       },
		{ "get_language",             &intf_get_language             },
		{ nullptr, nullptr }
	};

	lua_getglobal(L, "wesnoth");
	if (!lua_istable(L,-1)) {
		lua_newtable(L);
	}
	luaL_setfuncs(L, callbacks, 0);
	//lua_cpp::set_functions(L, cpp_callbacks, 0);
	lua_setglobal(L, "wesnoth");
	
	static luaL_Reg const wml_callbacks[]= {
		{ "load",      &intf_load_wml},
		{ "parse",     &intf_parse_wml},
		{ "clone",     &intf_clone_wml},
		{ nullptr, nullptr },
	};
	lua_newtable(L);
	luaL_setfuncs(L, wml_callbacks, 0);
	lua_setglobal(L, "wml");

	// Override the print function
	cmd_log_ << "Redirecting print function...\n";

	lua_getglobal(L, "print");
	lua_setglobal(L, "std_print"); //storing original impl as 'std_print'
	lua_settop(L, 0); //clear stack, just to be sure

	lua_pushcfunction(L, &dispatch<&lua_kernel_base::intf_print>);
	lua_setglobal(L, "print");

	lua_pushcfunction(L, intf_load);
	lua_setglobal(L, "load");
	lua_pushnil(L);
	lua_setglobal(L, "loadstring");

	cmd_log_ << "Initializing package repository...\n";
	// Create the package table.
	lua_getglobal(L, "wesnoth");
	lua_newtable(L);
	lua_setfield(L, -2, "package");
	lua_pop(L, 1);
	lua_settop(L, 0);
	lua_pushstring(L, "lua/package.lua");
	int res = intf_require(L);
	if(res != 1) {
		cmd_log_ << "Error: Failed to initialize package repository. Falling back to less flexible C++ implementation.\n";
	}

	// Get some callbacks for map locations
	cmd_log_ << "Adding map table...\n";

	static luaL_Reg const map_callbacks[] {
		{ "get_direction",		&lua_map_location::intf_get_direction         		},
		{ "vector_sum",			&lua_map_location::intf_vector_sum			},
		{ "vector_diff",			&lua_map_location::intf_vector_diff			},
		{ "vector_negation",		&lua_map_location::intf_vector_negation			},
		{ "rotate_right_around_center",	&lua_map_location::intf_rotate_right_around_center	},
		{ "tiles_adjacent",		&lua_map_location::intf_tiles_adjacent			},
		{ "get_adjacent_tiles",		&lua_map_location::intf_get_adjacent_tiles		},
		{ "distance_between",		&lua_map_location::intf_distance_between		},
		{ "get_in_basis_N_NE",		&lua_map_location::intf_get_in_basis_N_NE		},
		{ "get_relative_dir",		&lua_map_location::intf_get_relative_dir		},
		{ nullptr, nullptr }
	};

	// Create the map_location table.
	lua_getglobal(L, "wesnoth");
	lua_newtable(L);
	luaL_setfuncs(L, map_callbacks, 0);
	lua_setfield(L, -2, "map");
	lua_pop(L, 1);

	// Create the game_config variable with its metatable.
	cmd_log_ << "Adding game_config table...\n";

	lua_getglobal(L, "wesnoth");
	lua_newuserdata(L, 0);
	lua_createtable(L, 0, 3);
	lua_pushcfunction(L, &dispatch<&lua_kernel_base::impl_game_config_get>);
	lua_setfield(L, -2, "__index");
	lua_pushcfunction(L, &dispatch<&lua_kernel_base::impl_game_config_set>);
	lua_setfield(L, -2, "__newindex");
	lua_pushstring(L, "game config");
	lua_setfield(L, -2, "__metatable");
	lua_setmetatable(L, -2);
	lua_setfield(L, -2, "game_config");
	lua_pop(L, 1);

	// Add mersenne twister rng wrapper
	cmd_log_ << "Adding rng tables...\n";
	lua_rng::load_tables(L);

	cmd_log_ << "Adding name generator metatable...\n";
	luaL_newmetatable(L, Gen);
	static luaL_Reg const generator[] {
		{ "__call", &impl_name_generator_call},
		{ "__gc", &impl_name_generator_collect},
		{ nullptr, nullptr}
	};
	luaL_setfuncs(L, generator, 0);

	// Create formula bridge metatables
	cmd_log_ << lua_formula_bridge::register_metatables(L);

	// Loading ilua:
	cmd_log_ << "Loading ilua...\n";

	lua_settop(L, 0);
	luaW_getglobal(L, "wesnoth", "require");
	lua_pushstring(L, "lua/ilua.lua");
	if(protected_call(1, 1)) {
		//run "ilua.set_strict()"
		lua_pushstring(L, "set_strict");
		lua_gettable(L, -2);
		if (!this->protected_call(0,0, std::bind(&lua_kernel_base::log_error, this, _1, _2))) {
			cmd_log_ << "Failed to activate strict mode.\n";
		} else {
			cmd_log_ << "Activated strict mode.\n";
		}

		lua_setglobal(L, "ilua"); //save ilua table as a global
	} else {
		cmd_log_ << "Error: failed to load ilua.\n";
	}
	lua_settop(L, 0);
}