#include "apr_file_info.h"
/* forward dec'l from this file */
-// static int load_file(apr_pool_t *working_pool, lua_State* L, const apw_code_cache* cfg, apw_vm_spec *spec);
void pstack_dump(lua_State* L, apr_pool_t* r, int level, const char* msg) {
ap_log_perror(APLOG_MARK, level, 0, r, "Lua Stack Dump: [%s]", msg);
lua_pop(L, 1); /* pop "package" off the stack */
}
-/**
- * pool is a working pool
- */
-// static lua_State* create_vm(apw_vm_spec *spec,
-// apw_code_cache *cache,
-// apr_pool_t *pool) {
-// lua_State* L = luaL_newstate();
-// luaL_openlibs(L);
-//
-// apw_run_wombat_open(L, pool);
-//
-// munge_path(L, "path", "?.lua", "./?.lua", pool, spec->package_paths, spec->file);
-// munge_path(L, "cpath", "?.so", "./?.so", pool, spec->package_cpaths, spec->file);
-//
-// if (load_file(pool, L, cache, spec)) {
-// ap_log_perror(APLOG_MARK, APLOG_ERR, 0, pool,
-// "Unable to compile Lua file '%s' because of '%s'",
-// spec->file, luaL_checkstring(L, -1));
-// return NULL;
-// }
-// return L;
-// }
-
-// typedef struct {
-// server_rec *server;
-// apw_vm_spec *spec;
-// } server_vm_params;
-
-
-// static apr_status_t server_vm_ctor(void **resource, void *_params, apr_pool_t *pool) {
-// server_vm_params *params = _params;
-// apw_server_cfg *cfg = ap_get_module_config(params->server->module_config, &wombat_module);
-// lua_State *L = create_vm(params->spec, cfg->code_cache, pool);
-// *resource = L;
-// /* ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, params->server, "L is %d", (int)L); */
-// return OK;
-// }
-//
-// static apr_status_t server_vm_dtor(void *resource, void *_params, apr_pool_t *pool) {
-// return OK;
-// }
-//
-// typedef struct {
-// apr_reslist_t *reslist;
-// lua_State *L;
-// } server_release_t;
-//
-// static apr_status_t release_server_vm(void *l) {
-// server_release_t *srt = l;
-// apr_reslist_release(srt->reslist, srt->L);
-// return APR_SUCCESS;
-// }
-
-/* Initially we will just use a resource list keyed to the file name */
-// static lua_State* get_server_vm(server_rec *server, apw_vm_spec *spec) {
-// apr_status_t rv;
-// apw_server_cfg *cfg = ap_get_module_config(server->module_config, &wombat_module);
-//
-// apr_thread_rwlock_rdlock(cfg->vm_reslists_lock);
-// apr_reslist_t *rlist = apr_hash_get(cfg->vm_reslists, spec->file, APR_HASH_KEY_STRING);
-// apr_thread_rwlock_unlock(cfg->vm_reslists_lock);
-// if (!rlist) {
-// apr_thread_rwlock_wrlock(cfg->vm_reslists_lock);
-// /* double checked lock (works in C :-) */
-// rlist = apr_hash_get(cfg->vm_reslists, spec->file, APR_HASH_KEY_STRING);
-// if (!rlist) {
-// ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Creating RESLIST");
-//
-// server_vm_params *params = apr_palloc(server->process->pconf, sizeof(server_vm_params));
-//
-// params->server = server;
-// params->spec = apr_pcalloc(server->process->pconf, sizeof(apw_vm_spec));
-// params->spec->file = apr_pstrdup(server->process->pconf, spec->file);
-// params->spec->code_cache_style = spec->code_cache_style;
-// params->spec->scope = APW_SCOPE_SERVER;
-// params->spec->package_paths = spec->package_paths;
-// params->spec->package_cpaths = spec->package_cpaths;
-// ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Creating reslist for %s", spec->file);
-// rv = apr_reslist_create(&rlist, /* the list */
-// 10, 100, 100, /* min, soft max, hard max */
-// 0, /* TTL */
-// server_vm_ctor,
-// server_vm_dtor,
-// params,
-// server->process->pconf);
-//
-// apr_hash_set(cfg->vm_reslists, params->spec->file, APR_HASH_KEY_STRING, (void*)rlist);
-// }
-// apr_thread_rwlock_unlock(cfg->vm_reslists_lock);
-// }
-// lua_State *L;
-// apr_reslist_acquire(rlist, (void*)&L);
-//
-// server_release_t *srt = apr_palloc(spec->pool, sizeof(server_release_t));
-// srt->reslist = rlist;
-// srt->L = L;
-// apr_pool_cleanup_register(spec->pool, srt, release_server_vm, apr_pool_cleanup_null);
-//
-// /* apr_pool_cleanup_register(r->pool, L, cleanup_lua, apr_pool_cleanup_null); */
-//
-// ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Acquired lua_State %p", L);
-// return L;
-// }
-
-/* Initially we will just use a resource list keyed to the file name */
-// static lua_State* get_request_vm(request_rec *r, apw_vm_spec *spec) {
-// /* apr_status_t rv; */
-// apw_request_cfg *cfg = ap_get_module_config(r->request_config, &wombat_module);
-// apw_server_cfg *server_cfg = ap_get_module_config(r->server->module_config, &wombat_module);
-//
-// ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "got module config! %p", cfg);
-// lua_State *L = apr_hash_get(cfg->request_scoped_vms, spec->file, APR_HASH_KEY_STRING);
-// if (!L) {
-// L = create_vm(spec, server_cfg->code_cache, r->pool);
-// apr_hash_set(cfg->request_scoped_vms, spec->file, APR_HASH_KEY_STRING, L);
-// }
-// return L;
-// }
-
-// lua_State* apw_rgetvm(request_rec *r, apw_vm_spec *spec) {
-// apr_status_t rv;
-// const apw_dir_cfg* cfg = ap_get_module_config(r->per_dir_config, &wombat_module);
-// apw_server_cfg *server_cfg = ap_get_module_config(r->server->module_config, &wombat_module);
-// char *fixed_filename;
-// rv = apr_filepath_merge(&fixed_filename, server_cfg->root_path, spec->file, APR_FILEPATH_NOTRELATIVE, r->pool);
-// if (rv != APR_SUCCESS) {
-// ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "Unable to build full path to file, %s", spec->file);
-// return NULL;
-// }
-// spec->file = fixed_filename;
-// lua_State* L;
-// switch (spec->scope) {
-// case APW_SCOPE_REQUEST:
-// spec->package_paths = cfg->package_paths;
-// spec->package_cpaths = cfg->package_cpaths;
-// spec->pool = r->pool;
-// L = get_request_vm(r, spec);
-// return L;
-// return NULL;
-//
-// case APW_SCOPE_CONN:
-// ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Conn Scoped Lua VMs not implemented yet");
-// return NULL;
-//
-// case APW_SCOPE_SERVER:
-// spec->package_paths = cfg->package_paths;
-// spec->package_cpaths = cfg->package_cpaths;
-// spec->pool = r->pool;
-// L = get_server_vm(r->server, spec);
-// return L;
-//
-// default:
-// ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Unknown Lua VM scope specified, using 'once'");
-// /* fall through on purpose */
-// case APW_SCOPE_ONCE:
-// spec->package_paths = cfg->package_paths;
-// spec->package_cpaths = cfg->package_cpaths;
-// L = create_vm(spec, server_cfg->code_cache, r->pool);
-// if (spec->pool == NULL) {
-// apr_pool_cleanup_register(r->pool, L, cleanup_lua, apr_pool_cleanup_null);
-// }
-// apr_pool_cleanup_register(spec->pool, L, cleanup_lua, apr_pool_cleanup_null);
-// break;
-// }
-//
-// return L;
-// }
-
-/* returns NULL if the spec requires a request scope */
-// lua_State* apw_cgetvm(conn_rec *conn, apw_vm_spec *spec) {
-//
-// return NULL;
-// }
-
-/**
- * TODO Redo to make use of the create_vm
- */
-// lua_State* apw_sgetvm(server_rec *server, apw_vm_spec *spec) {
-// apr_status_t rv;
-// if (spec->scope == APW_SCOPE_REQUEST || spec->scope == APW_SCOPE_CONN) {
-// return NULL;
-// }
-//
-// apw_server_cfg *server_cfg = ap_get_module_config(server->module_config, &wombat_module);
-// char *fixed_filename;
-// rv = apr_filepath_merge(&fixed_filename, server_cfg->root_path, spec->file, APR_FILEPATH_NOTRELATIVE,
-// server->process->pconf);
-// if (rv != APR_SUCCESS) {
-// ap_log_error(APLOG_MARK, APLOG_ERR, rv, server, "Unable to build full path to file, %s", spec->file);
-// return NULL;
-// }
-// spec->file = fixed_filename;
-//
-// apr_pool_t *pool = NULL;
-// ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "ALLOCATING A LUA");
-// /* TODO change to use load_file */
-// lua_State* L = luaL_newstate();
-// luaL_openlibs(L);
-// apw_load_apache2_lmodule(L);
-// apw_load_config_lmodule(L);
-//
-// if (luaL_loadfile(L, spec->file)) {
-// ap_log_error(APLOG_MARK, APLOG_ERR, 0, server,
-// "Unable to compile Lua file '%s' because of '%s'",
-// spec->file, luaL_checkstring(L, -1));
-// return NULL;
-// }
-//
-// if (lua_pcall(L, 0, LUA_MULTRET, 0)) {
-// ap_log_error(APLOG_MARK, APLOG_ERR, 0, server,
-// "Unable to compile Lua file '%s' because of '%s'",
-// spec->file, luaL_checkstring(L, -1));
-// return NULL;
-// }
-//
-// switch (spec->scope) {
-// case APW_SCOPE_ONCE:
-// if (spec->pool == NULL) {
-// ap_log_error(APLOG_MARK, APLOG_ERR, 0, server,
-// "You must provide a pool for APW_SCOPE_ONCE");
-// lua_close(L);
-// return NULL;
-// }
-// pool = spec->pool;
-// break;
-//
-// case APW_SCOPE_REQUEST:
-// break;
-//
-// case APW_SCOPE_CONN:
-// break;
-//
-// case APW_SCOPE_SERVER:
-// lua_close(L);
-// ap_log_error(APLOG_MARK, APLOG_ERR, 0, server,
-// "Server Scoped Lua VMs not implemented yet");
-// return NULL;
-//
-// default:
-// pool = spec->pool;
-// ap_log_error(APLOG_MARK, APLOG_ERR, 0, server,
-// "Unknown Lua VM scope specified, using 'once'");
-// }
-//
-// apr_pool_cleanup_register(pool, L, cleanup_lua, apr_pool_cleanup_null);
-// return L;
-// }
-
-/* represents a cache entry */
-// typedef struct {
-// apr_array_header_t *parts; /* <part_t> */
-// apr_time_t mtime;
-// apr_pool_t *pool;
-// } code_cache_entry;
-//
-// typedef struct {
-// apr_pool_t *pool;
-// apr_array_header_t *parts; /* <part_t> */
-// } dumper_t;
-//
-// typedef struct {
-// apr_array_header_t* parts;
-// int idx;
-// request_rec* r;
-// } loader_t;
-//
-// typedef struct {
-// const void* chunk;
-// size_t sz;
-// } part_t;
-//
-// static int wlua_dumper(lua_State *L, const void* p, size_t sz, void* ud) {
-// dumper_t* d = (dumper_t*)ud;
-// part_t* part = apr_palloc(d->pool, sizeof(part_t));
-// void* mine = apr_palloc(d->pool, sz);
-// memcpy(mine, p, sz);
-// part->chunk = mine;
-// part->sz = sz;
-// *(const part_t**)apr_array_push(d->parts) = part;
-// return 0;
-// }
-//
-// static const char* wlua_loader(lua_State* L, void* data, size_t* size) {
-// loader_t* l = (loader_t*) data;
-// /* ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, l->r, "part count %d", l->parts->nelts); */
-// if (l->idx == l->parts->nelts) {
-// return NULL;
-// }
-// part_t* part = ((part_t**)l->parts->elts)[l->idx++];
-// *size = part->sz;
-// /* ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, l->r, "got part of size %lu", *size); */
-// return part->chunk;
-// }
-
-// static int load_file(apr_pool_t *working_pool, lua_State* L, const apw_code_cache* cfg, apw_vm_spec *spec) {
-// int rs;
-//
-// if (spec->bytecode_len != 0) {
-// rs = luaL_loadbuffer(L, spec->bytecode, spec->bytecode_len, spec->file);
-// if (rs) {
-// ap_log_perror(APLOG_MARK, APLOG_DEBUG, rs, working_pool, "Unable to load %s from buffer", spec->file);
-// return rs;
-// }
-// }
-// else if (spec->code_cache_style != APW_CODE_CACHE_NEVER) {
-// /* start code caching magic */
-// apr_thread_rwlock_rdlock(cfg->compiled_files_lock);
-// code_cache_entry *cache = apr_hash_get(cfg->compiled_files, spec->file, APR_HASH_KEY_STRING);
-// apr_thread_rwlock_unlock(cfg->compiled_files_lock);
-//
-// int stale = 0;
-// apr_finfo_t *finfo = NULL;
-// if (cache == NULL || spec->code_cache_style == APW_CODE_CACHE_STAT) {
-// ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, working_pool, "stating %s", spec->file);
-//
-// finfo = apr_palloc(working_pool, sizeof(apr_finfo_t));
-// apr_stat(finfo, spec->file, APR_FINFO_MTIME, working_pool);
-//
-// /* has the file been modified or is this the first time we load the file? */
-// if (cache == NULL || finfo->mtime > cache->mtime) {
-// /* we're expired */
-// ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, working_pool, "file is stale: %s ", spec->file);
-// stale = 1;
-// }
-// }
-//
-// if (!stale) {
-// ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, working_pool, "loading from cache: %s", spec->file);
-//
-// loader_t* l = apr_palloc(working_pool, sizeof(loader_t));
-// apr_thread_rwlock_rdlock(cfg->compiled_files_lock);
-// l->parts = cache->parts;
-// l->idx = 0;
-// if ((rs = lua_load(L, wlua_loader, l, spec->file))) {
-// apr_thread_rwlock_unlock(cfg->compiled_files_lock);
-// switch (rs) {
-// case LUA_ERRSYNTAX: {
-// ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, working_pool,
-// "syntax error on compiled [%s] from cache", spec->file);
-// return rs;
-// }
-// case LUA_ERRMEM: {
-// ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, working_pool,
-// "memory error on compiled [%s] from cache", spec->file);
-// return rs;
-// }
-// default: {
-// ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, working_pool,
-// "other error, %d, on compiled [%s] from cache", rs, spec->file);
-// return rs;
-// }
-// }
-// return rs;
-// }
-// else {
-// apr_thread_rwlock_unlock(cfg->compiled_files_lock);
-// }
-// }
-// else {
-// ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, working_pool, "loading & caching: %s", spec->file);
-//
-// if ((rs = luaL_loadfile(L, spec->file))) {
-// return rs;
-// }
-//
-// int is_new = 0;
-// if (!cache) {
-// /* allocate a new code_cache_entry from the cfg pool. Since entries are reused
-// * when files are re-loaded and we don't evict entries from the cache,
-// * we don't need to care about de-allocation.
-// */
-// cache = apr_palloc(cfg->pool, sizeof(code_cache_entry));
-// is_new = 1;
-// }
-//
-//
-// apr_pool_t *mp;
-// apr_pool_create(&mp, cfg->pool); /* pool from which everything in this code_cache_entry
-// * will be allocated */
-//
-// dumper_t* d = apr_palloc(working_pool, sizeof(dumper_t));
-// d->pool = mp;
-// d->parts = apr_array_make(mp, 250, sizeof(part_t*));
-// lua_dump(L, wlua_dumper, d);
-//
-// apr_thread_rwlock_wrlock(cfg->compiled_files_lock);
-//
-// if (is_new) {
-// /* we copy the filename into a string allocated from the cfg pool. apr_hash keeps
-// * pointers to keys and values, and we need the key to survive beyond the request lifetime
-// */
-// const char* key = apr_pstrdup(cfg->pool, spec->file);
-// apr_hash_set(cfg->compiled_files, key, APR_HASH_KEY_STRING, cache);
-// }
-// else {
-// apr_pool_clear(cache->pool);
-// }
-//
-// cache->parts = d->parts;
-// cache->pool = d->pool;
-// cache->mtime = finfo->mtime;
-//
-// apr_thread_rwlock_unlock(cfg->compiled_files_lock);
-//
-// /* end code caching magic */
-// }
-// }
-// else { /* CODE_CACHE_NEVER */
-// ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, working_pool, "loading: %s", spec->file);
-//
-// if ((rs = luaL_loadfile(L, spec->file))) {
-// return rs;
-// }
-// }
-//
-// return 0;
-// }
-
-/* BEGIN NEW STYLE lua_State MANAGEMENT */
-
lua_State* apw_get_lua_state(apr_pool_t* lifecycle_pool,
char* file,
apr_array_header_t* package_paths,