diff --git a/CLAUDE.md b/CLAUDE.md
index 3b201ed..8710471 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -33,15 +33,15 @@ These decisions are final:
- **UFSD-only docroot** — Remove DD-based file serving (`/DD:HTML(...)` paths), static files only from UFS
- **Remove embedded FTPD** — FTP functionality available separately
- **Remove MQTT telemetry** — HTTPT struct, telemetry_thread, mqtt370 dependency
-- **CGIs disabled by default** — No CGIs are registered unless explicitly configured in Parmlib. All existing CGI modules remain in the codebase but are only active when configured.
+- **Extract HTTPLUA/HTTPREXX** — Lua and REXX CGI handlers moved to separate projects (mvslovers/httplua, mvslovers/httprexx), lua370 dependency removed
+- **CGIs disabled by default** — No CGIs are registered unless explicitly configured in Parmlib.
## HTTPD 4.0.0 — Open Items
1. **TSK-112 CGI Chunked Bug** (M, High) — CGI responses with chunked transfer encoding
2. **TSK-110 Fehlende Status-Codes** (XS, High) — Missing HTTP status codes
3. **TSK-108 HTTP Parsing härten** (L, High) — Harden HTTP request parsing
-4. **TSK-104 HTTPLUA auslagern** (L, Medium) — Extract HTTPLUA into separate module
-5. **TSK-10 Doku + Version Bump** (M, Medium) — Documentation and version bump to 4.0.0
+4. **TSK-10 Doku + Version Bump** (M, Medium) — Documentation and version bump to 4.0.0
## Dependencies (from project.toml)
@@ -49,7 +49,6 @@ These decisions are final:
[dependencies]
"mvslovers/crent370" = ">=1.0.6"
"mvslovers/ufs370" = ">=1.0.0"
-"mvslovers/lua370" = "..." # stays while Lua CGI code remains in codebase
```
**Note:** mqtt370 dependency will be removed (MQTT telemetry confirmed for removal).
@@ -222,14 +221,14 @@ Missing `DD:HTTPDPRM` → server starts with defaults (port 8080, no CGIs).
- **httpdsrv.c**: Server status display (2,675 LOC)
- **httpjes2.c**: JES2 spool browser (975 LOC)
- **httpdsl.c + helpers**: Dataset list/download (1,540 LOC total)
-- **httplua.c**: Lua CGI handler (1,115 LOC)
-- **httprexx.c**: REXX CGI handler (587 LOC)
+- **httplua.c**: Extracted → mvslovers/httplua
+- **httprexx.c**: Extracted → mvslovers/httprexx
- **httpdm.c / httpdmtt.c**: Device manager display (440 LOC)
- **hello.c, abend0c1.c, test.c**: Demo/test CGIs
**Subsystems:**
- **httprepo.c**: SMF Type 243 recording + simple counters (~90 LOC)
-- **Lua runtime**: lauxlib.c, liolib.c, loadlib.c, httpluax.c (3,297 LOC) — stays for Lua CGI
+- **Lua runtime**: Extracted → mvslovers/httplua
- **FTP daemon**: ftp*.c (3,290 LOC) — confirmed for removal
- **MQTT telemetry**: HTTPT struct, telemetry_thread — confirmed for removal
diff --git a/config.mk b/config.mk
index 3d17838..c44b5e4 100644
--- a/config.mk
+++ b/config.mk
@@ -18,14 +18,13 @@ CFLAGS := -fverbose-asm -S -O1
HTTPD_VERSION ?= 4.0.0-dev
# Defines and include paths
-DEFS := -DLUA_USE_C89 -DLUA_USE_JUMPTABLE=0 -DHTTPD_VERSION=\"$(HTTPD_VERSION)\"
+DEFS := -DHTTPD_VERSION=\"$(HTTPD_VERSION)\"
INC_DIR := $(ROOT_DIR)include
INC1 := $(ROOT_DIR)credentials/include
INC2 := $(ROOT_DIR)contrib/crent370_sdk/inc
INC3 := $(ROOT_DIR)contrib/ufs370_sdk/inc
-INC4 := $(ROOT_DIR)contrib/lua370_sdk/inc
-INC5 := $(ROOT_DIR)contrib/mqtt370_sdk/inc
-INCS := -I$(INC_DIR) -I$(INC1) -I$(INC2) -I$(INC3) -I$(INC4) -I$(INC5)
+INC4 := $(ROOT_DIR)contrib/mqtt370_sdk/inc
+INCS := -I$(INC_DIR) -I$(INC1) -I$(INC2) -I$(INC3) -I$(INC4)
CFLAGS += $(DEFS) $(INCS)
diff --git a/include/httpd.h b/include/httpd.h
index 80acf9b..4dc3d3b 100644
--- a/include/httpd.h
+++ b/include/httpd.h
@@ -45,8 +45,7 @@
#include "cred.h" /* Credentials */
#include "httpxlat.h" /* ASCII/EBCDIC translation */
-#define HTTPLUAX (httpd->luax) /* use this pointer */
-#include "httpluax.h" /* Lua function vector struct */
+/* httpluax.h removed — HTTPLUA is now a separate project (mvslovers/httplua) */
typedef struct httpd HTTPD; /* HTTP Daemon (server) */
typedef struct httpc HTTPC; /* HTTP Client */
@@ -112,7 +111,7 @@ struct httpd {
time64_t uptime; /* 48 Server startup time */
void *unused_50; /* 50 (was: FTPD *ftpd) */
UFSSYS *ufssys; /* 54 Unix like file system */
- LUAX *luax; /* 58 Lua function vector */
+ void *unused_58; /* 58 (was: LUAX *luax) */
const char *version; /* 5C HTTPD Version */
void *unused_60; /* 60 (was: lua_State *config) */
UCHAR cfg_maxtask; /* 64 config max task */
@@ -135,9 +134,9 @@ struct httpd {
unsigned total_bytes_sent; /* 78 total bytes sent */
unsigned active_connections; /* 7C active client connections */
void *unused_80; /* 80 (was: st_dataset) */
- UCHAR *cgilua_dataset; /* 84 CGI Lua dataset */
- UCHAR *cgilua_path; /* 88 CGI Lua package.path */
- UCHAR *cgilua_cpath; /* 8C CGI Lua package.cpath */
+ void *unused_84; /* 84 (was: cgilua_dataset) */
+ void *unused_88; /* 88 (was: cgilua_path) */
+ void *unused_8C; /* 8C (was: cgilua_cpath) */
UFS *ufs; /* 90 Unix "like" File System */
void *unused_94; /* 94 (was: HTTPT *httpt) */
CTHDTASK *self; /* 98 HTTPD main thread */
diff --git a/include/httpluax.h b/include/httpluax.h
deleted file mode 100644
index 1a43c62..0000000
--- a/include/httpluax.h
+++ /dev/null
@@ -1,723 +0,0 @@
-#ifndef HTTPLUAX_H
-#define HTTPLUAX_H
-#include "stdio.h"
-#include "string.h"
-#include "stdarg.h"
-#include "clib.h"
-#include "clibio.h"
-#include "clibos.h"
-#include "lua.h"
-#include "lualib.h"
-#include "lauxlib.h"
-
-/* To load the HTTPLUAX module, use the following:
- *
- * #define HTTPLUAX luax
- * #include "httpluax.h"
- * LUAX *luax = (LUAX *) __load(0, "HTTPLUAX", 0, 0);
- *
- * - - - O R - - -
- *
- * #define HTTPLUAX httpd->luax
- * #include "httpluax.h"
- * httpd->luax = (LUAX *) __load(0, "HTTPLUAX", 0, 0);
- *
- * - - - O R - - -
- *
- * When httpluax is LKED with main program:
- * #define HTTPLUAX luax
- * #include "httpluax.h"
- * LAUX *luax = (LUAX*) &httpluax;
- *
- * If you don't want the macro names for the LUAX functions
- * you can use #define HTTPLUAX_PRIVATE before the
- * #include "httpluax.h" to hide the lua... macro names (defines)
- */
-
-typedef struct luax LUAX;
-
-struct luax {
- const char *lua_ident;
- lua_State *(*lua_newstate) (lua_Alloc f, void *ud);
- void (*lua_close) (lua_State *L);
- lua_State *(*lua_newthread) (lua_State *L);
- int (*lua_closethread) (lua_State *L, lua_State *from);
- int (*lua_resetthread) (lua_State *L);
- lua_CFunction (*lua_atpanic) (lua_State *L, lua_CFunction panicf);
- lua_Number (*lua_version) (lua_State *L);
- int (*lua_absindex) (lua_State *L, int idx);
- int (*lua_gettop) (lua_State *L);
- void (*lua_settop) (lua_State *L, int idx);
- void (*lua_pushvalue) (lua_State *L, int idx);
- void (*lua_rotate) (lua_State *L, int idx, int n);
- void (*lua_copy) (lua_State *L, int fromidx, int toidx);
- int (*lua_checkstack) (lua_State *L, int n);
- void (*lua_xmove) (lua_State *from, lua_State *to, int n);
- int (*lua_isnumber) (lua_State *L, int idx);
- int (*lua_isstring) (lua_State *L, int idx);
- int (*lua_iscfunction) (lua_State *L, int idx);
- int (*lua_isinteger) (lua_State *L, int idx);
- int (*lua_isuserdata) (lua_State *L, int idx);
- int (*lua_type) (lua_State *L, int idx);
- const char *(*lua_typename) (lua_State *L, int tp);
- lua_Number (*lua_tonumberx) (lua_State *L, int idx, int *isnum);
- lua_Integer (*lua_tointegerx) (lua_State *L, int idx, int *isnum);
- int (*lua_toboolean) (lua_State *L, int idx);
- const char *(*lua_tolstring) (lua_State *L, int idx, size_t *len);
- lua_Unsigned (*lua_rawlen) (lua_State *L, int idx);
- lua_CFunction (*lua_tocfunction) (lua_State *L, int idx);
- void *(*lua_touserdata) (lua_State *L, int idx);
- lua_State *(*lua_tothread) (lua_State *L, int idx);
- const void *(*lua_topointer) (lua_State *L, int idx);
- int (*lua_rawequal) (lua_State *L, int idx1, int idx2);
- int (*lua_compare) (lua_State *L, int idx1, int idx2, int op);
- void (*lua_pushnil) (lua_State *L);
- void (*lua_pushnumber) (lua_State *L, lua_Number n);
- void (*lua_pushinteger) (lua_State *L, lua_Integer n);
- const char *(*lua_pushlstring) (lua_State *L, const char *s, size_t len);
- const char *(*lua_pushstring) (lua_State *L, const char *s);
- const char *(*lua_pushvfstring) (lua_State *L, const char *fmt, va_list argp);
- const char *(*lua_pushfstring) (lua_State *L, const char *fmt, ...);
- void (*lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
- void (*lua_pushboolean) (lua_State *L, int b);
- void (*lua_pushlightuserdata) (lua_State *L, void *p);
- int (*lua_pushthread) (lua_State *L);
- int (*lua_getglobal) (lua_State *L, const char *name);
- int (*lua_gettable) (lua_State *L, int idx);
- int (*lua_getfield) (lua_State *L, int idx, const char *k);
- int (*lua_geti) (lua_State *L, int idx, lua_Integer n);
- int (*lua_rawget) (lua_State *L, int idx);
- int (*lua_rawgeti) (lua_State *L, int idx, lua_Integer n);
- int (*lua_rawgetp) (lua_State *L, int idx, const void *p);
- void (*lua_createtable) (lua_State *L, int narr, int nrec);
- void *(*lua_newuserdatauv) (lua_State *L, size_t sz, int nuvalue);
- int (*lua_getmetatable) (lua_State *L, int objindex);
- int (*lua_getiuservalue) (lua_State *L, int idx, int n);
- void (*lua_setglobal) (lua_State *L, const char *name);
- void (*lua_settable) (lua_State *L, int idx);
- void (*lua_setfield) (lua_State *L, int idx, const char *k);
- void (*lua_seti) (lua_State *L, int idx, lua_Integer n);
- void (*lua_rawset) (lua_State *L, int idx);
- void (*lua_rawseti) (lua_State *L, int idx, lua_Integer n);
- void (*lua_rawsetp) (lua_State *L, int idx, const void *p);
- int (*lua_setmetatable) (lua_State *L, int objindex);
- int (*lua_setiuservalue) (lua_State *L, int idx, int n);
- void (*lua_callk) (lua_State *L, int nargs, int nresults, lua_KContext ctx, lua_KFunction k);
- int (*lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc, lua_KContext ctx, lua_KFunction k);
- int (*lua_load) (lua_State *L, lua_Reader reader, void *dt, const char *chunkname, const char *mode);
- int (*lua_dump) (lua_State *L, lua_Writer writer, void *data, int strip);
- int (*lua_yieldk) (lua_State *L, int nresults, lua_KContext ctx, lua_KFunction k);
- int (*lua_resume) (lua_State *L, lua_State *from, int narg, int *nres);
- int (*lua_status) (lua_State *L);
- int (*lua_isyieldable) (lua_State *L);
- void (*lua_setwarnf) (lua_State *L, lua_WarnFunction f, void *ud);
- void (*lua_warning) (lua_State *L, const char *msg, int tocont);
- int (*lua_gc) (lua_State *L, int what, ...);
- int (*lua_error) (lua_State *L);
- int (*lua_next) (lua_State *L, int idx);
- void (*lua_concat) (lua_State *L, int n);
- void (*lua_len) (lua_State *L, int idx);
- size_t (*lua_stringtonumber) (lua_State *L, const char *s);
- lua_Alloc (*lua_getallocf) (lua_State *L, void **ud);
- void (*lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
- void (*lua_toclose) (lua_State *L, int idx);
- void (*lua_closeslot) (lua_State *L, int idx);
- int (*lua_getstack) (lua_State *L, int level, lua_Debug *ar);
- int (*lua_getinfo) (lua_State *L, const char *what, lua_Debug *ar);
- const char *(*lua_getlocal) (lua_State *L, const lua_Debug *ar, int n);
- const char *(*lua_setlocal) (lua_State *L, const lua_Debug *ar, int n);
- const char *(*lua_getupvalue) (lua_State *L, int funcindex, int n);
- const char *(*lua_setupvalue) (lua_State *L, int funcindex, int n);
- void *(*lua_upvalueid) (lua_State *L, int fidx, int n);
- void (*lua_upvaluejoin) (lua_State *L, int fidx1, int n1, int fidx2, int n2);
- void (*lua_sethook) (lua_State *L, lua_Hook func, int mask, int count);
- lua_Hook (*lua_gethook) (lua_State *L);
- int (*lua_gethookmask) (lua_State *L);
- int (*lua_gethookcount) (lua_State *L);
- int (*lua_setcstacklimit) (lua_State *L, unsigned int limit);
- void (*lua_arith) (lua_State *L, int op);
- void *unused1;
- void *unused2;
- void *unused3;
- /* 0x198 (408 bytes) */
- /* LAUXLIB */
- void (*luaL_checkversion_) (lua_State *L, lua_Number ver, size_t sz);
- int (*luaL_getmetafield) (lua_State *L, int obj, const char *e);
- int (*luaL_callmeta) (lua_State *L, int obj, const char *e);
- const char *(*luaL_tolstring) (lua_State *L, int idx, size_t *len);
- int (*luaL_argerror) (lua_State *L, int arg, const char *extramsg);
- int (*luaL_typeerror) (lua_State *L, int arg, const char *tname);
- const char *(*luaL_checklstring) (lua_State *L, int arg, size_t *l);
- const char *(*luaL_optlstring) (lua_State *L, int arg, const char *def, size_t *l);
- lua_Number (*luaL_checknumber) (lua_State *L, int arg);
- lua_Number (*luaL_optnumber) (lua_State *L, int arg, lua_Number def);
- lua_Integer (*luaL_checkinteger) (lua_State *L, int arg);
- lua_Integer (*luaL_optinteger) (lua_State *L, int arg, lua_Integer def);
- void (*luaL_checkstack) (lua_State *L, int sz, const char *msg);
- void (*luaL_checktype) (lua_State *L, int arg, int t);
- void (*luaL_checkany) (lua_State *L, int arg);
- int (*luaL_newmetatable) (lua_State *L, const char *tname);
- void (*luaL_setmetatable) (lua_State *L, const char *tname);
- void *(*luaL_testudata) (lua_State *L, int ud, const char *tname);
- void *(*luaL_checkudata) (lua_State *L, int ud, const char *tname);
- void (*luaL_where) (lua_State *L, int lvl);
- int (*luaL_error) (lua_State *L, const char *fmt, ...);
- int (*luaL_checkoption) (lua_State *L, int arg, const char *def, const char *const lst[]);
- int (*luaL_fileresult) (lua_State *L, int stat, const char *fname);
- int (*luaL_execresult) (lua_State *L, int stat);
- int (*luaL_ref) (lua_State *L, int t);
- void (*luaL_unref) (lua_State *L, int t, int ref);
- int (*luaL_loadfilex) (lua_State *L, const char *filename, const char *mode);
- int (*luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, const char *name, const char *mode);
- int (*luaL_loadstring) (lua_State *L, const char *s);
- lua_State *(*luaL_newstate) (void);
- lua_Integer (*luaL_len) (lua_State *L, int idx);
- void (*luaL_addgsub) (luaL_Buffer *b, const char *s, const char *p, const char *r);
- const char *(*luaL_gsub) (lua_State *L, const char *s, const char *p, const char *r);
- void (*luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
- int (*luaL_getsubtable) (lua_State *L, int idx, const char *fname);
- void (*luaL_traceback) (lua_State *L, lua_State *L1, const char *msg, int level);
- void (*luaL_requiref) (lua_State *L, const char *modname, lua_CFunction openf, int glb);
- void (*luaL_buffinit) (lua_State *L, luaL_Buffer *B);
- char *(*luaL_prepbuffsize) (luaL_Buffer *B, size_t sz);
- void (*luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
- void (*luaL_addstring) (luaL_Buffer *B, const char *s);
- void (*luaL_addvalue) (luaL_Buffer *B);
- void (*luaL_pushresult) (luaL_Buffer *B);
- void (*luaL_pushresultsize) (luaL_Buffer *B, size_t sz);
- char *(*luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz);
- void (*luaL_openlibs) (lua_State *L);
-
- void *lunused1;
- void *lunused2;
-
-};
-
-extern LUAX httpluax;
-
-#ifndef HTTPLUAX_PRIVATE
-
-#ifndef HTTPLUAX
-#error "You must define HTTPLUAX with your LUAX * pointer name"
-#endif
-
-#define lua_ident \
- (HTTPLUAX)->lua_ident
-#define lua_newstate(f,ud) \
- (HTTPLUAX)->lua_newstate(f,ud)
-#define lua_close(L) \
- (HTTPLUAX)->lua_close(L)
-#define lua_newthread(L) \
- (HTTPLUAX)->lua_newthread(L)
-#define lua_closethread(L,from) \
- (HTTPLUAX)->lua_closethread(L,from)
-#define lua_resetthread(L) \
- (HTTPLUAX)->lua_resetthread(L)
-#define lua_atpanic(L,panicf) \
- (HTTPLUAX)->lua_atpanic(L,panicf)
-#define lua_version(L) \
- (HTTPLUAX)->lua_version(L)
-#define lua_absindex(L,idx) \
- (HTTPLUAX)->lua_absindex(L,idx)
-#define lua_gettop(L) \
- (HTTPLUAX)->lua_gettop(L)
-#define lua_settop(L,idx) \
- (HTTPLUAX)->lua_settop(L,idx)
-#define lua_pushvalue(L,idx) \
- (HTTPLUAX)->lua_pushvalue(L,idx)
-#define lua_rotate(L,idx,n) \
- (HTTPLUAX)->lua_rotate(L,idx,n)
-#define lua_copy(L,fromidx,toidx) \
- (HTTPLUAX)->lua_copy(L,fromidx,toidx)
-#define lua_checkstack(L,n) \
- (HTTPLUAX)->lua_checkstack(L,n)
-#define lua_xmove(from,to,n) \
- (HTTPLUAX)->lua_xmove(from,to,n)
-#define lua_isnumber(L,idx) \
- (HTTPLUAX)->lua_isnumber(L,idx)
-#define lua_isstring(L,idx) \
- (HTTPLUAX)->lua_isstring(L,idx)
-#define lua_iscfunction(L,idx) \
- (HTTPLUAX)->lua_iscfunction(L,idx)
-#define lua_isinteger(L,idx) \
- (HTTPLUAX)->lua_isinteger(L,idx)
-#define lua_isuserdata(L,idx) \
- (HTTPLUAX)->lua_isuserdata(L,idx)
-#define lua_type(L,idx) \
- (HTTPLUAX)->lua_type(L,idx)
-#define lua_typename(L,tp) \
- (HTTPLUAX)->lua_typename(L,tp)
-#define lua_tonumberx(L,idx,isnum) \
- (HTTPLUAX)->lua_tonumberx(L,idx,isnum)
-#define lua_tointegerx(L,idx,isnum) \
- (HTTPLUAX)->lua_tointegerx(L,idx,isnum)
-#define lua_toboolean(L,idx) \
- (HTTPLUAX)->lua_toboolean(L,idx)
-#define lua_tolstring(L,idx,len) \
- (HTTPLUAX)->lua_tolstring(L,idx,len)
-#define lua_rawlen(L,idx) \
- (HTTPLUAX)->lua_rawlen(L,idx)
-#define lua_tocfunction(L,idx) \
- (HTTPLUAX)->lua_tocfunction(L,idx)
-#define lua_touserdata(L,idx) \
- (HTTPLUAX)->lua_touserdata(L,idx)
-#define lua_tothread(L,idx) \
- (HTTPLUAX)->lua_tothread(L,idx)
-#define lua_topointer(L,idx) \
- (HTTPLUAX)->lua_topointer(L,idx)
-#define lua_rawequal(L,idx1,idx2) \
- (HTTPLUAX)->lua_rawequal(L,idx1,idx2)
-#define lua_compare(L,idx1,idx2,op) \
- (HTTPLUAX)->lua_compare(L,idx1,idx2,op)
-#define lua_pushnil(L) \
- (HTTPLUAX)->lua_pushnil(L)
-#define lua_pushnumber(L,n) \
- (HTTPLUAX)->lua_pushnumber(L,n)
-#define lua_pushinteger(L,n) \
- (HTTPLUAX)->lua_pushinteger(L,n)
-#define lua_pushlstring(L,s,len) \
- (HTTPLUAX)->lua_pushlstring(L,s,len)
-#define lua_pushstring(L,s) \
- (HTTPLUAX)->lua_pushstring(L,s)
-#define lua_pushvfstring(L,fmt,argp) \
- (HTTPLUAX)->lua_pushvfstring(L,fmt,argp)
-#define lua_pushfstring(L,fmt,...) \
- (HTTPLUAX)->lua_pushfstring(L,fmt,## __VA_ARGS__)
-#define lua_pushcclosure(L,fn,n) \
- (HTTPLUAX)->lua_pushcclosure(L,fn,n)
-#define lua_pushboolean(L,b) \
- (HTTPLUAX)->lua_pushboolean(L,b)
-#define lua_pushlightuserdata(L,p) \
- (HTTPLUAX)->lua_pushlightuserdata(L,p)
-#define lua_pushthread(L) \
- (HTTPLUAX)->lua_pushthread(L)
-#define lua_getglobal(L,name) \
- (HTTPLUAX)->lua_getglobal(L,name)
-#define lua_gettable(L,idx) \
- (HTTPLUAX)->lua_gettable(L,idx)
-#define lua_getfield(L,idx,k) \
- (HTTPLUAX)->lua_getfield(L,idx,k)
-#define lua_geti(L,idx,n) \
- (HTTPLUAX)->lua_geti(L,idx,n)
-#define lua_rawget(L,idx) \
- (HTTPLUAX)->lua_rawget(L,idx)
-#define lua_rawgeti(L,idx,n) \
- (HTTPLUAX)->lua_rawgeti(L,idx,n)
-#define lua_rawgetp(L,idx,p) \
- (HTTPLUAX)->lua_rawgetp(L,idx,p)
-#define lua_createtable(L,narr,nrec) \
- (HTTPLUAX)->lua_createtable(L,narr,nrec)
-#define lua_newuserdatauv(L,sz,nuvalue) \
- (HTTPLUAX)->lua_newuserdatauv(L,sz,nuvalue)
-#define lua_getmetatable(L,objindex) \
- (HTTPLUAX)->lua_getmetatable(L,objindex)
-#define lua_getiuservalue(L,idx,n) \
- (HTTPLUAX)->lua_getiuservalue(L,idx,n)
-#define lua_setglobal(L,name) \
- (HTTPLUAX)->lua_setglobal(L,name)
-#define lua_settable(L,idx) \
- (HTTPLUAX)->lua_settable(L,idx)
-#define lua_setfield(L,idx,k) \
- (HTTPLUAX)->lua_setfield(L,idx,k)
-#define lua_seti(L,idx,n) \
- (HTTPLUAX)->lua_seti(L,idx,n)
-#define lua_rawset(L,idx) \
- (HTTPLUAX)->lua_rawset(L,idx)
-#define lua_rawseti(L,idx,n) \
- (HTTPLUAX)->lua_rawseti(L,idx,n)
-#define lua_rawsetp(L,idx,p) \
- (HTTPLUAX)->lua_rawsetp(L,idx,p)
-#define lua_setmetatable(L,objindex) \
- (HTTPLUAX)->lua_setmetatable(L,objindex)
-#define lua_setiuservalue(L,idx,n) \
- (HTTPLUAX)->lua_setiuservalue(L,idx,n)
-#define lua_callk(L,nargs,nresults,ctx,k) \
- (HTTPLUAX)->lua_callk(L,nargs,nresults,ctx,k)
-#undef lua_call
-#define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL)
-#define lua_pcallk(L,nargs,nresults,errfunc,ctx,k) \
- (HTTPLUAX)->lua_pcallk(L,nargs,nresults,errfunc,ctx,k)
-#undef lua_pcall
-#define lua_pcall(L,n,r,f) lua_pcallk(L, (n), (r), (f), 0, NULL)
-#define lua_load(L,reader,dt,chunkname,mode) \
- (HTTPLUAX)->lua_load(L,reader,dt,chunkname,mode)
-#define lua_dump(L,writer,data,strip) \
- (HTTPLUAX)->lua_dump(L,writer,data,strip)
-#define lua_yieldk(L,nresults,ctx,k) \
- (HTTPLUAX)->lua_yieldk(L,nresults,ctx,k)
-#define lua_resume(L,from,narg,nres) \
- (HTTPLUAX)->lua_resume(L,from,narg,nres)
-#define lua_status(L) \
- (HTTPLUAX)->lua_status(L)
-#define lua_isyieldable(L) \
- (HTTPLUAX)->lua_isyieldable(L)
-#define lua_setwarnf(L,f,ud) \
- (HTTPLUAX)->lua_setwarnf(L,f,ud)
-#define lua_warning(L,msg,tocont) \
- (HTTPLUAX)->lua_warning(L,msg,tocont)
-#define lua_gc(L,what,...) \
- (HTTPLUAX)->lua_gc(L,what,## __VA_ARGS__)
-#define lua_error(L) \
- (HTTPLUAX)->lua_error(L)
-#define lua_next(L,idx) \
- (HTTPLUAX)->lua_next(L,idx)
-#define lua_concat(L,n) \
- (HTTPLUAX)->lua_concat(L,n)
-#define lua_len(L,idx) \
- (HTTPLUAX)->lua_len(L,idx)
-#define lua_stringtonumber(L,s) \
- (HTTPLUAX)->lua_stringtonumber(L,s)
-#define lua_getallocf(L,ud) \
- (HTTPLUAX)->lua_getallocf(L,ud)
-#define lua_setallocf(L,f,ud) \
- (HTTPLUAX)->lua_setallocf(L,f,ud)
-#define lua_toclose(L,idx) \
- (HTTPLUAX)->lua_toclose(L,idx)
-#define lua_closeslot(L,idx) \
- (HTTPLUAX)->lua_closeslot(L,idx)
-#define lua_getstack(L,level,ar) \
- (HTTPLUAX)->lua_getstack(L,level,ar)
-#define lua_getinfo(L,what,ar) \
- (HTTPLUAX)->lua_getinfo(L,what,ar)
-#define lua_getlocal(L,ar,n) \
- (HTTPLUAX)->lua_getlocal(L,ar,n)
-#define lua_setlocal(L,ar,n) \
- (HTTPLUAX)->lua_setlocal(L,ar,n)
-#define lua_getupvalue(L,funcindex,n) \
- (HTTPLUAX)->lua_getupvalue(L,funcindex,n)
-#define lua_setupvalue(L,funcindex,n) \
- (HTTPLUAX)->lua_setupvalue(L,funcindex,n)
-#define lua_upvalueid(L,fidx,n) \
- (HTTPLUAX)->lua_upvalueid(L,fidx,n)
-#define lua_upvaluejoin(L,fidx1,n1,fidx2,n2) \
- (HTTPLUAX)->lua_upvaluejoin(L,fidx1,n1,fidx2,n2)
-#define lua_sethook(L,func,mask,count) \
- (HTTPLUAX)->lua_sethook(L,func,mask,count)
-#define lua_gethook(L) \
- (HTTPLUAX)->lua_gethook(L)
-#define lua_gethookmask(L) \
- (HTTPLUAX)->lua_gethookmask(L)
-#define lua_gethookcount(L) \
- (HTTPLUAX)->lua_gethookcount(L)
-#define lua_setcstacklimit(L,limit) \
- (HTTPLUAX)->lua_setcstacklimit(L,limit)
-#define lua_arith(L,op) \
- (HTTPLUAX)->lua_arith(L,op)
-/* LAUXLIB */
-#define luaL_checkversion_(L,ver,sz) \
- (HTTPLUAX)->luaL_checkversion_(L,ver,sz)
-#define luaL_getmetafield(L,obj,e) \
- (HTTPLUAX)->luaL_getmetafield(L,obj,e)
-#define luaL_callmeta(L,obj,e) \
- (HTTPLUAX)->luaL_callmeta(L,obj,e)
-#define luaL_tolstring(L,idx,len) \
- (HTTPLUAX)->luaL_tolstring(L,idx,len)
-#define luaL_argerror(L,arg,extramsg) \
- (HTTPLUAX)->luaL_argerror(L,arg,extramsg)
-#define luaL_typeerror(L,arg,tname) \
- (HTTPLUAX)->luaL_typeerror(L,arg,tname)
-#define luaL_checklstring(L,arg,len) \
- (HTTPLUAX)->luaL_checklstring(L,arg,len)
-#define luaL_optlstring(L,arg,def,len) \
- (HTTPLUAX)->luaL_optlstring(L,arg,def,len)
-#define luaL_checknumber(L,arg) \
- (HTTPLUAX)->luaL_checknumber(L,arg)
-#define luaL_optnumber(L,arg,def) \
- (HTTPLUAX)->luaL_optnumber(L,arg,def)
-#define luaL_checkinteger(L,arg) \
- (HTTPLUAX)->luaL_checkinteger(L,arg)
-#define luaL_optinteger(L,arg,def) \
- (HTTPLUAX)->luaL_optinteger(L,arg,def)
-#define luaL_checkstack(L,sz,msg) \
- (HTTPLUAX)->luaL_checkstack(L,sz,msg)
-#define luaL_checktype(L,arg,t) \
- (HTTPLUAX)->luaL_checktype(L,arg,t)
-#define luaL_checkany(L,arg) \
- (HTTPLUAX)->luaL_checkany(L,arg)
-#define luaL_newmetatable(L,tname) \
- (HTTPLUAX)->luaL_newmetatable(L,tname)
-#define luaL_setmetatable(L,tname) \
- (HTTPLUAX)->luaL_setmetatable(L,tname)
-#define luaL_testudata(L,ud,tname) \
- (HTTPLUAX)->luaL_testudata(L,ud,tname)
-#define luaL_checkudata(L,ud,tname) \
- (HTTPLUAX)->luaL_checkudata(L,ud,tname)
-#define luaL_where(L,level) \
- (HTTPLUAX)->luaL_where(L,level)
-#define luaL_error(L,fmt,...) \
- (HTTPLUAX)->luaL_error(L,fmt,## __VA_ARGS__)
-#define luaL_checkoption(L,arg,def,lst) \
- (HTTPLUAX)->luaL_checkoption(L,arg,def,lst)
-#define luaL_fileresult(L,stat,fname) \
- (HTTPLUAX)->luaL_fileresult(L,stat,fname)
-#define luaL_execresult(L,stat) \
- (HTTPLUAX)->luaL_execresult(L,stat)
-#define luaL_ref(L,t) \
- (HTTPLUAX)->luaL_ref(L,t)
-#define luaL_unref(L,t,ref) \
- (HTTPLUAX)->luaL_unref(L,t,ref)
-#define luaL_loadfilex(L,filename,mode) \
- (HTTPLUAX)->luaL_loadfilex(L,filename,mode)
-#define luaL_loadbufferx(L,buff,sz,name,mode) \
- (HTTPLUAX)->luaL_loadbufferx(L,buff,sz,name,mode)
-#define luaL_loadstring(L,s) \
- (HTTPLUAX)->luaL_loadstring(L,s)
-#define luaL_newstate() \
- (HTTPLUAX)->luaL_newstate()
-#define luaL_len(L,idx) \
- (HTTPLUAX)->luaL_len(L,idx)
-#define luaL_addgsub(b,s,p,r) \
- (HTTPLUAX)->luaL_addgsub(b,s,p,r)
-#define luaL_gsub(L,s,p,r) \
- (HTTPLUAX)->luaL_gsub(L,s,p,r)
-#define luaL_setfuncs(L,l,nup) \
- (HTTPLUAX)->luaL_setfuncs(L,l,nup)
-#define luaL_getsubtable(L,idx,fname) \
- (HTTPLUAX)->luaL_getsubtable(L,idx,fname)
-#define luaL_traceback(L,L1,msg,level) \
- (HTTPLUAX)->luaL_traceback(L,L1,msg,level)
-#define luaL_requiref(L,modname,openf,glb) \
- (HTTPLUAX)->luaL_requiref(L,modname,openf,glb)
-#define luaL_buffinit(L,B) \
- (HTTPLUAX)->luaL_buffinit(L,B)
-#define luaL_prepbuffsize(B,sz) \
- (HTTPLUAX)->luaL_prepbuffsize(B,sz)
-#define luaL_addlstring(B,s,l) \
- (HTTPLUAX)->luaL_addlstring(B,s,l)
-#define luaL_addstring(B,s) \
- (HTTPLUAX)->luaL_addstring(B,s)
-#define luaL_addvalue(B) \
- (HTTPLUAX)->luaL_addvalue(B)
-#define luaL_pushresult(B) \
- (HTTPLUAX)->luaL_pushresult(B)
-#define luaL_pushresultsize(B,sz) \
- (HTTPLUAX)->luaL_pushresultsize(B,sz)
-#define luaL_buffinitsize(L,B,sz) \
- (HTTPLUAX)->luaL_buffinitsize(L,B,sz)
-#define luaL_openlibs(L) \
- (HTTPLUAX)->luaL_openlibs(L)
-
-
-
-#undef lua_tonumber
-#define lua_tonumber(L,i) \
- lua_tonumberx(L,(i),NULL)
-
-#undef lua_tointeger
-#define lua_tointeger(L,i) \
- lua_tointegerx(L,(i),NULL)
-
-#undef lua_pop
-#define lua_pop(L,n) \
- lua_settop(L, -(n)-1)
-
-#undef lua_newtable
-#define lua_newtable(L) \
- lua_createtable(L, 0, 0)
-
-#undef lua_pushcfunction
-#define lua_pushcfunction(L,f) \
- lua_pushcclosure(L, (f), 0)
-
-#undef lua_register
-#define lua_register(L,n,f) \
- (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
-
-#undef lua_isfunction
-#define lua_isfunction(L,n) \
- (lua_type(L, (n)) == LUA_TFUNCTION)
-
-#undef lua_istable
-#define lua_istable(L,n) \
- (lua_type(L, (n)) == LUA_TTABLE)
-
-#undef lua_islightuserdata
-#define lua_islightuserdata(L,n) \
- (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
-
-#undef lua_isnil
-#define lua_isnil(L,n) \
- (lua_type(L, (n)) == LUA_TNIL)
-
-#undef lua_isboolean
-#define lua_isboolean(L,n) \
- (lua_type(L, (n)) == LUA_TBOOLEAN)
-
-#undef lua_isthread
-#define lua_isthread(L,n) \
- (lua_type(L, (n)) == LUA_TTHREAD)
-
-#undef lua_isnone
-#define lua_isnone(L,n) \
- (lua_type(L, (n)) == LUA_TNONE)
-
-#undef lua_isnoneornil
-#define lua_isnoneornil(L, n) \
- (lua_type(L, (n)) <= 0)
-
-#undef lua_pushliteral
-#define lua_pushliteral(L, s) \
- lua_pushstring(L, "" s)
-
-#undef lua_pushglobaltable
-#define lua_pushglobaltable(L) \
- ((void)lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS))
-
-#undef lua_tostring
-#define lua_tostring(L,i) \
- lua_tolstring(L, (i), NULL)
-
-#undef lua_insert
-#define lua_insert(L,idx) \
- lua_rotate(L, (idx), 1)
-
-#undef lua_remove
-#define lua_remove(L,idx) \
- (lua_rotate(L, (idx), -1), lua_pop(L, 1))
-
-#undef lua_replace
-#define lua_replace(L,idx) \
- (lua_copy(L, -1, (idx)), lua_pop(L, 1))
-
-#undef lua_call
-#define lua_call(L,n,r) \
- lua_callk(L, (n), (r), 0, NULL)
-
-#undef lua_pcall
-#define lua_pcall(L,n,r,f) \
- lua_pcallk(L, (n), (r), (f), 0, NULL)
-
-#undef lua_yield
-#define lua_yield(L,n) \
- lua_yieldk(L, (n), 0, NULL)
-
-
-/*
-** {==============================================================
-** compatibility macros
-** ===============================================================
-*/
-#if defined(LUA_COMPAT_APIINTCASTS)
-#undef lua_pushunsigned
-#define lua_pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n))
-#undef lua_tounsignedx
-#define lua_tounsignedx(L,i,is) ((lua_Unsigned)lua_tointegerx(L,i,is))
-#undef lua_tounsigned
-#define lua_tounsigned(L,i) lua_tounsignedx(L,(i),NULL)
-#endif
-
-#undef lua_newuserdata
-#define lua_newuserdata(L,s) lua_newuserdatauv(L,s,1)
-#undef lua_getuservalue
-#define lua_getuservalue(L,idx) lua_getiuservalue(L,idx,1)
-#undef lua_setuservalue
-#define lua_setuservalue(L,idx) lua_setiuservalue(L,idx,1)
-
-#undef luaL_newlibtable
-#define luaL_newlibtable(L,l) \
- lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1)
-
-#undef luaL_argcheck
-#define luaL_argcheck(L, cond,arg,extramsg) \
- ((void)(luai_likely(cond) || luaL_argerror(L, (arg), (extramsg))))
-
-#undef luaL_argexpected
-#define luaL_argexpected(L,cond,arg,tname) \
- ((void)(luai_likely(cond) || luaL_typeerror(L, (arg), (tname))))
-
-#undef luaL_checkstring
-#define luaL_checkstring(L,n) \
- (luaL_checklstring(L, (n), NULL))
-
-#undef luaL_optstring
-#define luaL_optstring(L,n,d) \
- (luaL_optlstring(L, (n), (d), NULL))
-
-#undef luaL_typename
-#define luaL_typename(L,i) \
- lua_typename(L, lua_type(L,(i)))
-
-#undef luaL_dostring
-#define luaL_dostring(L, s) \
- (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
-
-#undef luaL_getmetatable
-#define luaL_getmetatable(L,n) \
- (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
-
-#undef luaL_opt
-#define luaL_opt(L,f,n,d) \
- (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
-
-#undef luaL_loadbuffer
-#define luaL_loadbuffer(L,s,sz,n) \
- luaL_loadbufferx(L,s,sz,n,NULL)
-
-/* push the value used to represent failure/error */
-#undef luaL_pushfail
-#define luaL_pushfail(L) \
- lua_pushnil(L)
-
-
-#undef luaL_addchar
-#define luaL_addchar(B,c) \
- ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \
- ((B)->b[(B)->n++] = (c)))
-
-#undef luaL_prepbuffer
-#define luaL_prepbuffer(B) \
- luaL_prepbuffsize(B, LUAL_BUFFERSIZE)
-
-#undef luaL_checkversion
-#define luaL_checkversion(L) \
- luaL_checkversion_(L, LUA_VERSION_NUM, LUAL_NUMSIZES)
-
-#undef luaL_newlib
-#define luaL_newlib(L,l) \
- (luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))
-
-#undef luaL_loadfile
-#define luaL_loadfile(L,f) \
- luaL_loadfilex(L,f,NULL)
-
-#undef luaL_dofile
-#define luaL_dofile(L, fn) \
- (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
-
-
-/*
-** {============================================================
-** Compatibility with deprecated conversions
-** =============================================================
-*/
-#if defined(LUA_COMPAT_APIINTCASTS)
-
-#undef luaL_checkunsigned
-#define luaL_checkunsigned(L,a) \
- ((lua_Unsigned)luaL_checkinteger(L,a))
-
-#undef luaL_optunsigned
-#define luaL_optunsigned(L,a,d) \
- ((lua_Unsigned)luaL_optinteger(L,a,(lua_Integer)(d)))
-
-#undef luaL_checkint
-#define luaL_checkint(L,n) \
- ((int)luaL_checkinteger(L, (n)))
-
-#undef luaL_optint
-#define luaL_optint(L,n,d) \
- ((int)luaL_optinteger(L, (n), (d)))
-
-#undef luaL_checklong
-#define luaL_checklong(L,n) \
- ((long)luaL_checkinteger(L, (n)))
-
-#undef luaL_optlong
-#define luaL_optlong(L,n,d) \
- ((long)luaL_optinteger(L, (n), (d)))
-
-#endif /* #if defined(LUA_COMPAT_APIINTCASTS) */
-
-#endif /* #ifndef HTTPLUAX_PRIVATE */
-
-#endif /* HTTPLUAX_H */
diff --git a/project.toml b/project.toml
index ab9c3df..fc820b3 100644
--- a/project.toml
+++ b/project.toml
@@ -6,8 +6,6 @@ type = "application"
[build]
cflags = [
"-O1",
- "-DLUA_USE_C89",
- "-DLUA_USE_JUMPTABLE=0",
"-I./include",
"-I./credentials/include",
]
@@ -50,7 +48,6 @@ space = ["TRK", 150, 50, 30]
[dependencies]
"mvslovers/crent370" = ">=1.0.9"
"mvslovers/ufsd" = "=1.0.0-dev"
-"mvslovers/lua370" = ">=1.0.2"
# --- Load Modules ------------------------------------------------
@@ -63,36 +60,8 @@ include = ["@@CRT1", "HTTPSTRT", "HTTPD", "HTTPPRM"]
setcode = "AC(1)"
[link.module.dep_includes]
-"mvslovers/lua370" = "*"
"mvslovers/ufsd" = "*"
-# Lua extension module (custom entry point, no CRT)
-[[link.module]]
-name = "HTTPLUAX"
-entry = "HTTPLUAX"
-options = ["SIZE=(4000K,40K)", "LIST", "MAP", "XREF", "RENT"]
-include = ["HTTPLUAX"]
-
-[link.module.dep_includes]
-"mvslovers/lua370" = "*"
-
-# Lua CGI handler
-[[link.module]]
-name = "HTTPLUA"
-entry = "@@CRT0"
-options = ["LIST", "MAP", "XREF", "RENT"]
-include = ["@@CRT1", "HTTPLUA"]
-
-[link.module.dep_includes]
-"mvslovers/ufsd" = "*"
-
-# BREXX say helper (@@CRTM instead of @@CRT1)
-[[link.module]]
-name = "HTTPSAY"
-entry = "@@CRT0"
-options = ["LIST", "MAP", "XREF", "RENT"]
-include = ["@@CRTM", "HTTPSAY"]
-
# JES2 CGI handler
[[link.module]]
name = "HTTPJES2"
@@ -100,13 +69,6 @@ entry = "@@CRT0"
options = ["LIST", "MAP", "XREF", "RENT"]
include = ["@@CRT1", "CGISTART", "HTTPJES2"]
-# REXX CGI handler
-[[link.module]]
-name = "HTTPREXX"
-entry = "@@CRT0"
-options = ["LIST", "MAP", "XREF", "RENT"]
-include = ["@@CRT1", "CGISTART", "HTTPREXX"]
-
# SSI handler modules
[[link.module]]
name = "HTTPDM"
@@ -137,5 +99,5 @@ version_files = ["VERSION"]
[artifacts]
headers = true
-header_files = ["httpcgi.h", "httpxlat.h", "dbg.h", "errors.h"]
+header_files = ["httpcgi.h", "httpxlat.h", "dbg.h", "errors.h", "types.h"]
loads = true
diff --git a/samplib/httpprm0 b/samplib/httpprm0
index b263607..3982019 100644
--- a/samplib/httpprm0
+++ b/samplib/httpprm0
@@ -34,18 +34,19 @@
# DEBUG=1
#
# --- CGI Modules ---
-# Format: CGI=PROGRAM /url/path
+# Format: CGI=PROGRAM /url/pattern (URL prefix match)
+# CGI=PROGRAM *.ext (extension match — uses DOCROOT)
# No CGIs are registered by default.
# Uncomment the lines below to enable them.
#
# CGI=MVSMF /zosmf/*
+# CGI=HTTPLUA *.lua
+# CGI=HTTPREXX *.rexx
# CGI=HTTPDSRV /.dsrv
# CGI=HTTPDM /.dm
# CGI=HTTPDMTT /.dmtt
-# CGI=HTTPDSL /dsl/*
-# CGI=HTTPJES2 /jes/*
-# CGI=HTTPLUA /lua/*
-# CGI=HTTPREXX /rexx/*
+# CGI=HTTPDSL /dsl/* (deprecated — use mvsMF dataset API)
+# CGI=HTTPJES2 /jes/* (deprecated — use mvsMF jobs API)
#
# --- SMF Recording ---
# SMF=NONE|ERROR|AUTH|ALL [TYPE=nnn]
diff --git a/src/httpd.c b/src/httpd.c
index 8111105..8173c00 100644
--- a/src/httpd.c
+++ b/src/httpd.c
@@ -86,9 +86,6 @@ initialize(int argc, char **argv)
/* set the server up time */
httpd->uptime = time64(NULL);
- /* httpd -> httpluax */
- httpd->luax = &httpluax;
-
/* Server version */
httpd->version = VERSION;
diff --git a/src/httpdsrv.c b/src/httpdsrv.c
index 5c121c8..9356ecf 100644
--- a/src/httpdsrv.c
+++ b/src/httpdsrv.c
@@ -378,14 +378,14 @@ display_httpd(HTTPD *httpd, HTTPC *httpc)
"
%p | \n",
O(ufssys), httpd->ufssys);
- http_printf(httpc,
+ http_printf(httpc,
"| +%04X | "
- "httpd->luax | "
- "Lua Function Vector | "
- "%p |
\n",
- O(luax), httpd->luax, sizeof(LUAX), httpd->luax);
+ "httpd->unused_58 | "
+ "(reserved) | "
+ "%p | \n",
+ O(unused_58), httpd->unused_58);
- http_printf(httpc,
+ http_printf(httpc,
"| +%04X | "
"httpd->version | "
"Version String | "
@@ -457,28 +457,28 @@ display_httpd(HTTPD *httpd, HTTPC *httpc)
"%u |
\n",
O(active_connections), httpd->active_connections);
- http_printf(httpc,
+ http_printf(httpc,
"| +%04X | "
- "httpd->cgilua_dataset | "
- "CGI Lua Dataset Name | "
- "\"%s\" |
\n",
- O(cgilua_dataset), httpd->cgilua_dataset);
-
- http_printf(httpc,
+ "httpd->unused_84 | "
+ "(reserved) | "
+ "%p | \n",
+ O(unused_84), httpd->unused_84);
+
+ http_printf(httpc,
"| +%04X | "
- "httpd->cgilua_path | "
- "CGI Lua Path Name | "
- "\"%s\" |
\n",
- O(cgilua_path), httpd->cgilua_path);
-
- http_printf(httpc,
+ "httpd->unused_88 | "
+ "(reserved) | "
+ "%p | \n",
+ O(unused_88), httpd->unused_88);
+
+ http_printf(httpc,
"| +%04X | "
- "httpd->cgilua_cpath | "
- "CGI Lua CPath Name | "
- "\"%s\" |
\n",
- O(cgilua_cpath), httpd->cgilua_cpath);
-
- http_printf(httpc,
+ "httpd->unused_8C | "
+ "(reserved) | "
+ "%p | \n",
+ O(unused_8C), httpd->unused_8C);
+
+ http_printf(httpc,
"| +%04X | "
"httpd->ufs | "
"Unix \"like\" File System Handle | "
diff --git a/src/httplua.c b/src/httplua.c
deleted file mode 100644
index 9110390..0000000
--- a/src/httplua.c
+++ /dev/null
@@ -1,1076 +0,0 @@
-/* HTTPLUA.C - CGI Program, REST style CGI program to execute lua scripts */
-#include "clibary.h"
-#include "clibos.h"
-#include "httpd.h"
-#include "svc99.h"
-
-#define httpx (httpd->httpx)
-
-static int alloc_dummy(char *ddname);
-static int alloc_temp(char *ddname, const char *tmpname);
-static int free_alloc(const char *ddname);
-static int process_stdout(HTTPD *httpd, HTTPC *httpc);
-static int process_stderr(HTTPD *httpd, HTTPC *httpc, const char *script);
-static int process_print(HTTPD *httpd, HTTPC *httpc, const char *buf);
-static int main_lua(HTTPD *httpd, HTTPC *httpc, const char *script);
-static void dumpstack(lua_State *L, const char *funcname);
-static int setLuaPath(lua_State *L, const char *path);
-static int setLuaCPath(lua_State *L, const char *path);
-static char *getLuaPath(lua_State *L);
-
-static int open_http(lua_State *L);
-
-static int http_lua_publish(lua_State *L);
-
-#define MAXPARMS 50 /* maximum number of arguments we can handle */
-
-/* we want the internal label for __start as "cgistart" for use with dumps */
-int __start(char *p, char *pgmname, int tsojbid, void **pgmr1) {
- CLIBGRT *grt = __grtget();
- HTTPD *httpd = NULL;
- HTTPC *httpc = NULL;
- char ddstdin[12] = "DD:xxxxxxxx";
- char ddstdout[12] = "DD:xxxxxxxx";
- char ddstderr[12] = "DD:xxxxxxxx";
- int x;
- int argc;
- unsigned u;
- char *argv[MAXPARMS + 1];
- int rc;
- int parmLen;
- int progLen;
- char parmbuf[310];
-
- /* we're going to process the callers parameter list first so we
- can decide is we'll bypass the opens for the permanent datasets.
- */
- if (pgmr1) {
- /* save the program parameter list values (max 10 pointers)
- note: the first pointer is always the raw EXEC PGM=...,PARM
- or CPPL (TSO) address.
- */
- for (x = 0; x < 10; x++) {
- u = (unsigned)pgmr1[x];
- /* add to array of pointers from caller */
- arrayadd(&grt->grtptrs, (void *)(u & 0x7FFFFFFF));
-
- if (u) {
- if (strcmp((void *)u, HTTPD_EYE) == 0) {
- /* this is a HTTPD pointer */
- httpd = (HTTPD *)(u & 0x7FFFFFFF);
- grt->grtapp1 = httpd;
- }
- if (strcmp((void *)u, HTTPC_EYE) == 0) {
- /* this is a HTTPC pointer */
- httpc = (HTTPC *)(u & 0x7FFFFFFF);
- grt->grtapp2 = httpc;
- }
- }
-
- if (u & 0x80000000)
- break; /* end of VL style address list */
- }
- }
-
- /* if we got a HTTPC and we didn't get a HTTPD,
- then use the HTTPD from the HTTPC handle */
- if (httpc && !httpd) {
- httpd = httpc->httpd;
- grt->grtapp1 = httpd;
- }
-
- /* need to know if this is a TSO environment straight away
- because it determines how the permanent files will be
- opened */
- parmLen = ((unsigned int)p[0] << 8) | (unsigned int)p[1];
- if ((parmLen > 0) && (p[2] == 0)) {
- grt->grtflag1 |= GRTFLAG1_TSO;
- progLen = (unsigned int)p[3];
- }
-
- rc = alloc_dummy(&ddstdin[3]);
- // wtof("%s: stdin %s", __func__, ddstdin);
- if (rc)
- goto quit;
-
- rc = alloc_temp(&ddstdout[3], "STDOUT");
- // wtof("%s: stdout %s", __func__, ddstdout);
- if (rc)
- goto quit;
-
- rc = alloc_temp(&ddstderr[3], "STDERR");
- // wtof("%s: stderr %s", __func__, ddstderr);
- if (rc)
- goto quit;
-
- stdout = fopen(ddstdout, "w");
- // wtof("%s: stdout 0x%08X", __func__, stdout);
- if (!stdout) {
- wtof("Unable to open STDOUT %s", ddstdout);
- goto quit;
- }
-
- stderr = fopen(ddstderr, "w");
- // wtof("%s: stderr 0x%08X", __func__, stderr);
- if (!stderr) {
- wtof("Unable to open STDERR %s", ddstderr);
- goto quit;
- }
-
- stdin = fopen(ddstdin, "r");
- // wtof("%s: stdin 0x%08X", __func__, stdin);
- if (!stdin) {
- stdin = fopen("'NULLFILE'", "r");
- // wtof("%s: stdin 0x%08X", __func__, stdin);
- }
- if (!stdin) {
- wtof("Unable to open STDIN %s", ddstdin);
- goto quit;
- }
-
- if (loadenv("dd:SYSENV")) {
- /* no SYSENV DD, try ENVIRON DD */
- loadenv("dd:ENVIRON");
- }
-
- /* initialize time zone offset for this thread */
- tzset();
-
- if (parmLen >= sizeof(parmbuf) - 2) {
- parmLen = sizeof(parmbuf) - 1 - 2;
- }
- if (parmLen < 0)
- parmLen = 0;
-
- /* We copy the parameter into our own area because
- the caller hasn't necessarily allocated room for
- a terminating NUL, nor is it necessarily correct
- to clobber the caller's area with NULs. */
- memset(parmbuf, 0, sizeof(parmbuf));
- if (grt->grtflag1 & GRTFLAG1_TSO) {
- parmLen -= 4;
- memcpy(parmbuf, p + 4, parmLen);
- } else {
- memcpy(parmbuf, p + 2, parmLen);
- }
- p = parmbuf;
-
- if (grt->grtflag1 & GRTFLAG1_TSO) {
- argv[0] = p;
- for (x = 0; x <= progLen; x++) {
- if (argv[0][x] == ' ') {
- argv[0][x] = 0;
- break;
- }
- }
- p += progLen;
- } else { /* batch or tso "call" */
- argv[0] = pgmname;
- pgmname[8] = '\0';
- pgmname = strchr(pgmname, ' ');
- if (pgmname)
- *pgmname = '\0';
- }
-
- while (*p == ' ')
- p++;
-
- x = 1;
- if (*p) {
- while (x < MAXPARMS) {
- char srch = ' ';
-
- if (*p == '"') {
- p++;
- srch = '"';
- }
- argv[x++] = p;
- p = strchr(p, srch);
- if (!p)
- break;
-
- *p = '\0';
- p++;
- /* skip trailing blanks */
- while (*p == ' ')
- p++;
- if (*p == '\0')
- break;
- }
- }
- argv[x] = NULL;
- argc = x;
-
- rc = main(argc, argv);
-
-quit:
- if (stdin) {
- // wtof("%s: fclose(stdin)", __func__);
- fclose(stdin);
- }
- if (stdout) {
- // wtof("%s: fclose(stdout)", __func__);
- fclose(stdout);
- }
- if (stderr) {
- // wtof("%s: fclose(stderr)", __func__);
- fclose(stderr);
- }
-
- /* release allocations */
- free_alloc(&ddstdin[3]);
- free_alloc(&ddstdout[3]);
- free_alloc(&ddstderr[3]);
-
- __exit(rc);
- return (rc);
-}
-
-int main(int argc, char **argv) {
- int rc = 0;
- CLIBPPA *ppa = __ppaget();
- CLIBGRT *grt = __grtget();
- CLIBCRT *crt = __crtget();
- UFS *ufs = NULL;
- void *crtapp1 = NULL;
- void *crtapp2 = NULL;
- HTTPD *httpd = grt->grtapp1;
- HTTPC *httpc = grt->grtapp2;
- char *path = NULL;
- char *script = NULL;
-
- if (!httpd) {
- wtof("This program %s must be called by the HTTPD web server%s", argv[0],
- "");
- /* TSO callers might not see a WTO message, so we send a STDOUT message too
- */
- printf("This program %s must be called by the HTTPD web server%s", argv[0],
- "\n");
- return 12;
- }
-
- /* save for our exit/exterbnal programs */
- if (crt) {
- // wtof("httplua.c:%s: crt=%p crt->crtufs=%p", __func__, crt, crt->crtufs);
- crtapp1 = crt->crtapp1;
- crtapp2 = crt->crtapp2;
- ufs = crt->crtufs;
- crt->crtapp1 = httpd;
- crt->crtapp2 = httpc;
- crt->crtufs = httpc->ufs;
- }
-
- // wtof("%s: enter", argv[0]);
-
- // wtof("%s: ppa=0x%08X grt=0x%08X httpd=0x%08X httpc=0x%08X",
- // argv[0], ppa, grt, httpd, httpc);
-
- /* get the request path string */
- path = http_get_env(httpc, "REQUEST_PATH");
- script = strrchr(path, '/');
-
- // wtof("%s: path=\"%s\"", argv[0], path);
- // wtof("%s: script=\"%s\"", argv[0], path);
-
- if (script) {
- rc = main_lua(httpd, httpc, script);
- }
-
-quit:
- if (crt) {
- /* restore crt values */
- crt->crtapp1 = crtapp1;
- crt->crtapp2 = crtapp2;
- crt->crtufs = ufs;
- }
-
- // wtof("%s: exit rc=%d", argv[0], rc);
- return rc;
-}
-
-static int readable(const char *filename) {
- CLIBCRT *crt = __getcrt();
- UFS *ufs = crt ? crt->crtufs : NULL;
- UFSFILE *ufp = NULL;
- FILE *f = NULL;
-
- // wtof("httplua.c:%s: enter \"%s\"", __func__, filename);
-
- if (ufs) {
- ufp = ufs_fopen(ufs, filename, "r");
- // wtof("httplua.c:%s: ufp=%p", __func__, ufp);
- if (ufp) {
- /* this filename exist and is readable */
- ufs_fclose(&ufp);
- goto okay;
- }
- }
-
- /* try opening as a dataset */
- f = fopen(filename, "r"); /* try to open file */
- // wtof("httplua.c:%s: f=%p", __func__, f);
- if (f == NULL)
- goto fail; /* open failed */
- fclose(f);
- goto okay;
-
-fail:
- // wtof("httplua.c:%s: exit 0", __func__);
- return 0;
-
-okay:
- // wtof("httplua.c:%s: exit 1", __func__);
- return 1;
-}
-
-static char *make_pathnames(const char *paths, const char *script) {
- char *pathname = NULL;
- int pathcount = 1;
- int scriptlen = strlen(script);
- int i;
- char *p;
-
- // wtof("httplua.c:%s: enter paths=\"%s\" script=\"%s\"", __func__, paths,
- // script);
-
- for (p = strchr(paths, ';'); p; p = strchr(p + 1, ';')) {
- pathcount++;
- }
-
- pathname = calloc(1, strlen(paths) + (scriptlen * pathcount));
- if (!pathname)
- goto quit;
-
- for (p = pathname; *paths; paths++) {
- *p = *paths;
- if (*p == '?') {
- strcpy(p, script);
- p += scriptlen;
- } else {
- p++;
- }
- }
-
-quit:
- // wtof("httplua.c:%s: exit pathname=\"%s\"", __func__, pathname);
- return pathname;
-}
-
-static int main_lua(HTTPD *httpd, HTTPC *httpc, const char *script) {
- int rc = 0;
- lua_State *L = NULL;
- unsigned lines = 0;
- unsigned errors = 0;
- char *path = NULL;
- char dataset[256];
-
- // wtof("%s: enter script=\"%s\"", __func__, script);
-
- while (*script == '/')
- script++;
-
- /* create new Lua state */
- L = luaL_newstate();
- // wtof("%s: lua_State=0x%08X", __func__, L);
-
- // dumpstack(L, __func__ );
-
- /* Open Lua libraries */
- // wtof("%s: calling luaL_openlibs(L)", __func__);
- luaL_openlibs(L);
-
- // dumpstack(L, __func__ );
-
- /* Install http */
- // wtof("%s: calling luaL_requiref(L, \"http\", open_http, 1)", __func__);
- luaL_requiref(L, "http", open_http, 1);
-
- // dumpstack(L, __func__ );
- lua_settop(L, 0);
-
-#if 0 /* debugging */
- path = getLuaPath(L);
- wtof("%s: path=\"%s\"", __func__, path);
- if (path) {
- free(path);
- path = NULL;
- }
-#endif /* debugging */
-
- if (httpd->cgilua_path && httpd->cgilua_path[0]) {
- setLuaPath(L, httpd->cgilua_path);
- }
-
- if (httpd->cgilua_cpath && httpd->cgilua_cpath[0]) {
- setLuaCPath(L, httpd->cgilua_cpath);
- }
-
-#if 0 /* debugging */
- path = getLuaPath(L);
- wtof("%s: path=\"%s\"", __func__, path);
- if (path) {
- free(path);
- path = NULL;
- }
-#endif /* debugging */
-
- // wtof("%s: ready to process script=%s", __func__, script);
-
- /* Here we're formatting the dataset stirng with the script
- * member name to be found in the PDS allocated to the
- * LUALIB DD. This should prevent any unwanted execution
- * of Lua scripts from outside datasets.
- */
- rc = strlen(script);
- if (rc > 8)
- rc = 8;
- if (httpd->cgilua_dataset && httpd->cgilua_dataset[0]) {
- sprintf(dataset, "%s(%.*s)", httpd->cgilua_dataset, rc, script);
- if (readable(dataset))
- goto doit;
- }
-
- // wtof("%s: httpd->cgilua_path=\"%s\"", __func__, httpd->cgilua_path);
- if (httpd->cgilua_path && httpd->cgilua_path[0]) {
- char *pathnames = make_pathnames(httpd->cgilua_path, script);
- char *name;
- char *rest;
-
- if (!pathnames)
- goto dodd;
- // wtof("%s: pathnames=\"%s\"", __func__, pathnames);
-
- for (name = strtok(pathnames, ";"); name; name = strtok(rest, ";")) {
- rest = strtok(NULL, "");
- // wtof("%s: name=\"%s\" rest=\"%s\"", __func__, name, rest);
- if (readable(name)) {
- strcpy(dataset, name);
- free(pathnames);
- goto doit;
- }
- }
- free(pathnames);
- }
-
-dodd:
- sprintf(dataset, "DD:CGILUA(%.*s)", rc, script);
- if (readable(dataset))
- goto doit;
-
- /* last chance, see if the request path exist */
- script = http_get_env(httpc, "REQUEST_PATH");
- if (script) {
- strcpy(dataset, script);
- if (readable(dataset))
- goto doit;
- }
-
- wtof("HTTPD417I CGI Lua script \"%s\" is not readable or does not exist",
- script);
- goto quit;
-
-doit:
- // wtof("%s: calling luaL_dofile(L,\"%s\")", __func__, dataset);
- rc = luaL_dofile(L, dataset);
- if (rc) {
- const char *s = lua_tostring(L, 1);
- if (s && strstr(s, "cannot open") && strstr(s, "No Error")) {
- wtof("HTTPD417I CGI Lua script \"%s\" does not exist", dataset);
- } else {
- /* Something went wrong, dump stack to console */
- wtof("HTTPD417E Error in CGI Lua script \"%s\"", dataset);
- dumpstack(L, "HTTPD418E");
- }
- }
-
- // dumpstack(L, __func__ );
-
-#if 0 /* debugging */
- luaL_dostring(L, "if http.print then http.oprint = print, print = http.print end");
- luaL_dostring(L, "for n in pairs(_G) do print(n) end");
- luaL_dostring(L, "print('-------------------------------')");
- luaL_dostring(L, "for n in pairs(http) do print(n) end");
- luaL_dostring(L, "print('-------------------------------')");
- luaL_dostring(L, "print('http.server_version ' .. http.server_version)");
- luaL_dostring(L, "for n,v in pairs(http.vars) do print(n..'='..v) end");
- luaL_dostring(L, "print('-------------------------------')");
- luaL_dostring(L, "print(\"Hello\")");
-#endif /* debugging */
-
- /* create response using STDOUT dataseet */
- // wtof("%s: calling process_stdout(httpd, httpc)", __func__);
- lines = process_stdout(httpd, httpc);
-
- /* process any errors found in STDERR dataset */
- // wtof("%s: calling process_stderr(httpd, httpc, script)", __func__);
- errors = process_stderr(httpd, httpc, script);
-
-quit:
- if (path)
- free(path);
-
- // wtof("%s: calling lua_close(L)", __func__);
- if (L)
- lua_close(L);
-
- if (!httpc->resp) {
- if (errors) {
- http_resp(httpc, 503);
- http_printf(httpc, "Content-Type: %s\r\n", "text/plain");
- http_printf(httpc, "\r\n");
- http_printf(httpc,
- "One or more errors occurred processing your request\n");
- } else {
- http_resp(httpc, 200);
- http_printf(httpc, "Content-Type: %s\r\n", "text/plain");
- http_printf(httpc, "\r\n");
- http_printf(httpc,
- "Well this is weird, that Lua script \"%s\" didn't return "
- "any output.\n",
- script);
- }
- }
-
- httpc->state = CSTATE_DONE;
- // wtof("%s: exit rc=%d", __func__, rc);
-
- // wtof("%s: exit rc=%d", __func__, rc);
- return rc;
-}
-
-static int setLuaPath(lua_State *L, const char *path) {
- HTTPD *httpd = cgihttpd();
-
- lua_getglobal(L, "package");
-
- // wtof("%s: new path=\"%s\"", __func__, path);
-
- lua_pushstring(L, path); // push the new one
- lua_setfield(
- L, -2,
- "path"); // set the field "path" in table at -2 with value at top of stack
- lua_remove(L, -1); // get rid of package table from top of stack
-
- return 0; // all done!
-}
-
-static int setLuaCPath(lua_State *L, const char *path) {
- HTTPD *httpd = cgihttpd();
-
- lua_getglobal(L, "package");
-
- // wtof("%s: new path=\"%s\"", __func__, path);
-
- lua_pushstring(L, path); // push the new one
- lua_setfield(L, -2, "cpath"); // set the field "path" in table at -2 with
- // value at top of stack
- lua_remove(L, -1); // get rid of package table from top of stack
-
- return 0; // all done!
-}
-
-static char *getLuaPath(lua_State *L) {
- HTTPD *httpd = cgihttpd();
- char *path;
-
- lua_getglobal(L, "package");
- lua_getfield(L, -1,
- "path"); // get field "path" from table at top of stack (-1)
-
- path = strdup(lua_tostring(L, -1)); // grab path string from top of stack
- // wtof("%s: path=\"%s\"", __func__, path);
-
- lua_pop(L, 1); // remove path string from stack
- lua_pop(L, 1); // remove package table from stack
-
- return path; // don't forget to free this when your done
-}
-
-static void dumpstack(lua_State *L, const char *funcname) {
- HTTPD *httpd = cgihttpd();
- int top = lua_gettop(L);
- int i;
- int j;
- char buf[256];
-
- wtof("%s Stack Dump (%d)", funcname, top);
- for (i = 1, j = -top; i <= top; i++, j++) {
- const char *typename = luaL_typename(L, i);
- sprintf(buf, "%3d (%d) %.12s", i, j, luaL_typename(L, i));
- switch (lua_type(L, i)) {
- case LUA_TNUMBER:
- wtof("%s %g", buf, lua_tonumber(L, i));
- break;
- case LUA_TSTRING:
- wtof("%s %s", buf, lua_tostring(L, i));
- break;
- case LUA_TBOOLEAN:
- wtof("%s %s", buf, (lua_toboolean(L, i) ? "true" : "false"));
- break;
- case LUA_TNIL:
- wtof("%s %s", buf, "nil");
- break;
- default:
- wtof("%s %p", buf, lua_topointer(L, i));
- break;
- }
- }
-}
-
-static int http_lua_print(lua_State *L) {
- HTTPD *httpd = cgihttpd();
- HTTPC *httpc = cgihttpc();
- int top = lua_gettop(L);
- int i;
- const char *p;
- char buf[80];
-
- // wtof("%s: enter top=%d", __func__, top);
- // wtof("%s: crt=%p httpd=%p httpc=%p", __func__, crt, httpd, httpc);
-
- for (i = 1; i <= top; i++) {
- if (i > 1) /* not the first element? */
- process_print(httpd, httpc, "\t"); /* add a tab before it */
-
- switch (lua_type(L, i)) {
- case LUA_TNUMBER:
- sprintf(buf, "%g", lua_tonumber(L, i));
- // wtof("%s: TNUMBER buf=\"%s\"", __func__, buf);
- process_print(httpd, httpc, buf);
- break;
- case LUA_TSTRING:
- p = lua_tostring(L, i);
- // wtof("%s: TSTRING p=\"%s\"", __func__, p);
- process_print(httpd, httpc, p);
- break;
- case LUA_TBOOLEAN:
- sprintf(buf, "%s", (lua_toboolean(L, i) ? "true" : "false"));
- // wtof("%s: TBOOLEAN buf=\"%s\"", __func__, buf);
- process_print(httpd, httpc, buf);
- break;
- case LUA_TNIL:
- p = "nil";
- // wtof("%s: TNIL p=\"%s\"", __func__, p);
- process_print(httpd, httpc, p);
- break;
- default:
- sprintf(buf, "%p", lua_topointer(L, i));
- // wtof("%s: default buf=\"%s\"", __func__, buf);
- process_print(httpd, httpc, buf);
- break;
- } /* switch */
- // lua_pop(L, 1); /* pop result */
- } /* for */
-
- lua_settop(L, 0); /* clear stack */
-
-#if 0
- CLIBCRT *crt = __crtget();
- HTTPD *httpd = crt->crtapp1;
- HTTPC *httpc = crt->crtapp2;
- int top = lua_gettop(L); /* number of arguments */
- int i;
-
- for (i = 1; i <= top; i++) { /* for each argument */
- const char *s = lua_tostring(L, i); /* convert it to string */
- // wtof("%s: %3d \"%s\"", __func__, i, s);
- if (i > 1) /* not the first element? */
- process_print(httpd, httpc, "\t"); /* add a tab before it */
- process_print(httpd, httpc, s); /* print it */
- lua_pop(L, 1); /* pop result */
- }
-#endif
-
- process_print(httpd, httpc, "\n");
- // wtof("%s: exit", __func__);
-
- return 0;
-}
-
-static int create_lua_vars(lua_State *L) {
- HTTPD *httpd = cgihttpd();
- HTTPC *httpc = cgihttpc();
- unsigned count = array_count(&httpc->env);
- unsigned n;
- int i;
- char *p;
- char name[256];
-
- lua_createtable(L, 0, count);
-
- for (n = 0; n < count; n++) {
- HTTPV *env = httpc->env[n];
-
- if (!env)
- continue;
-
- for (i = 0; env->name[i]; i++) {
- p = &env->name[i];
- if (*p == '-') {
- name[i] = '_';
- } else {
- name[i] = *p;
- // name[i] = toupper(*p);
- }
- }
- name[i] = 0;
-
- lua_pushstring(L, env->value);
- lua_setfield(L, -2, name);
- }
-
- /* returning 1 table on top of stack */
- return 1;
-}
-
-static int open_http(lua_State *L) {
- HTTPD *httpd = cgihttpd();
- luaL_Reg reg[] = {
- {"print", http_lua_print},
- {"publish", http_lua_publish},
- {NULL, NULL},
- };
-
- // dumpstack(L, __func__ );
-
- luaL_newlib(L, reg);
-
- // dumpstack(L, __func__ );
-
- /* create version */
- lua_pushstring(L, httpd->version);
- lua_setfield(L, -2, "server_version");
-
- /* create vars table */
- create_lua_vars(L);
- lua_setfield(L, -2, "vars");
-
- // dumpstack(L, __func__ );
- return 1;
-}
-
-static int process_print(HTTPD *httpd, HTTPC *httpc, const char *buf) {
- int rc = 0;
- const char *p;
-
- if (!httpc->resp && __patmat(buf, "HTTP/?.? *")) {
- /* looks like a HTTP response header */
- char *tmp = strdup(buf);
- if (tmp) {
- char *p1 = strtok(tmp, " "); /* HTTP/1.0 */
- char *p2 = strtok(NULL, " "); /* nnn */
- char *p3 = strtok(NULL, ""); /* OK or whatever */
-
- if (p2)
- httpc->resp = atoi(p2);
- free(tmp);
- }
- }
-
- if (!httpc->resp) {
- /* we don't have a HTTP response */
- http_resp(httpc, 200);
- for (p = buf; *p == ' '; p++)
- ;
- if (p[0] == '<') {
- /* looks like a HTML markup tag */
- http_printf(httpc, "Content-Type: %s\r\n", "text/html");
- } else {
- /* anything else */
- http_printf(httpc, "Content-Type: %s\r\n", "text/plain");
- }
- http_printf(httpc, "\r\n");
- }
-
- rc = http_printf(httpc, "%s", buf);
-
- return rc;
-}
-
-static int process_stdout(HTTPD *httpd, HTTPC *httpc) {
- int lines = 0;
- FILE *fp = NULL;
- char *p = NULL;
- char buf[256];
- char ddstdout[12] = "DD:xxxxxxxx";
-
- if (!stdout)
- goto quit;
-
- strcpy(&ddstdout[3], stdout->ddname);
- fclose(stdout);
- stdout = NULL;
-
- /* create response */
- fp = fopen(ddstdout, "r");
- // wtof("%s: fopen(\"DD:STDOUT\",\"r\") fp=0x%08X", __func__, fp);
- if (!fp)
- goto quit;
-
- while (p = fgets(buf, sizeof(buf), fp)) {
- if (!lines) {
- if (!httpc->resp && __patmat(buf, "HTTP/?.? *")) {
- /* looks like a HTTP response header */
- char *tmp = strdup(buf);
- if (tmp) {
- char *p1 = strtok(tmp, " "); /* HTTP/1.0 */
- char *p2 = strtok(NULL, " "); /* nnn */
- char *p3 = strtok(NULL, ""); /* OK or whatever */
-
- if (p2)
- httpc->resp = atoi(p2);
- free(tmp);
- }
- }
-
- if (!httpc->resp) {
- /* we don't have a HTTP response */
- http_resp(httpc, 200);
- while (*p == ' ')
- p++;
- if (p[0] == '<') {
- /* looks like a HTML markup tag */
- http_printf(httpc, "Content-Type: %s\r\n", "text/html");
- } else {
- /* anything else */
- http_printf(httpc, "Content-Type: %s\r\n", "text/plain");
- }
- http_printf(httpc, "\r\n");
- }
- }
- http_printf(httpc, "%s", buf);
- lines++;
- }
-
-quit:
- if (fp)
- fclose(fp);
-
- return lines;
-}
-
-static int process_stderr(HTTPD *httpd, HTTPC *httpc, const char *script) {
- int errors = 0;
- FILE *fp = NULL;
- char *p = NULL;
- char buf[256];
- char ddstderr[12] = "DD:xxxxxxxx";
-
- if (!stderr)
- goto quit;
-
- strcpy(&ddstderr[3], stderr->ddname);
- fclose(stderr);
- stderr = NULL;
-
- fp = fopen(ddstderr, "r");
- // wtof("%s: fopen(\"DD:STDERR\",\"r\") fp=0x%08X", __func__, fp);
- if (!fp)
- goto quit;
-
- while (p = fgets(buf, sizeof(buf), fp)) {
- if (!errors) {
- wtof("HTTPD500I CGI Program HTTPLUA script \"%s\"", script);
- }
- // wtodumpf(buf, strlen(buf), "%s: stderr", __func__);
- /* strip trailing newline */
- p = strrchr(buf, '\n');
- if (p)
- *p = 0;
-
- wtof("HTTPD501I %s", buf);
- errors++;
- }
-
-quit:
- if (fp)
- fclose(fp);
- return errors;
-}
-
-static int free_alloc(const char *ddname) {
- int err = 1;
- unsigned count = 0;
- TXT99 **txt99 = NULL;
- RB99 rb99 = {0};
-
- // wtof("%s: enter ddname=\"%s\"", __func__, ddname);
-
- /* we want to unallocate the DDNAME */
- err = __txddn(&txt99, ddname);
- if (err)
- goto quit;
-
- count = arraycount(&txt99);
- if (!count)
- goto quit;
-
- /* Set high order bit to mark end of list */
- count--;
- txt99[count] = (TXT99 *)((unsigned)txt99[count] | 0x80000000);
-
- /* construct the request block for dynamic allocation */
- rb99.len = sizeof(RB99);
- rb99.request = S99VRBUN;
- rb99.flag1 = S99NOCNV;
- rb99.txtptr = txt99;
-
- /* SVC 99 */
- err = __svc99(&rb99);
- if (err) {
- // wtof("%s: err=%d error=0x%04X info=0x%04X", __func__, err, rb99.error,
- // rb99.info);
- goto quit;
- }
-
-quit:
- if (txt99)
- FreeTXT99Array(&txt99);
-
- // wtof("%s: exit rc=%d", __func__, err);
- return err;
-}
-
-static int alloc_temp(char *ddname, const char *tmpname) {
- int err = 1;
- unsigned count = 0;
- TXT99 **txt99 = NULL;
- RB99 rb99 = {0};
- char tempname[40];
-
- // wtof("%s: enter ddname=\"%s\"", __func__, ddname);
- if (!tmpname)
- tmpname = "TEMP";
- snprintf(tempname, sizeof(tempname), "&%s", tmpname);
- tempname[sizeof(tempname) - 1] = 0;
-
- /* we want the DDNAME returned to us */
- err = __txrddn(&txt99, NULL);
- if (err)
- goto quit;
-
- /* allocate this dataset */
- err = __txdsn(&txt99, tempname);
- if (err)
- goto quit;
-
- /* DISP=NEW */
- err = __txnew(&txt99, NULL);
- if (err)
- goto quit;
-
- /* BLKSIZE=27998 */
- err = __txbksz(&txt99, "27998");
- if (err)
- goto quit;
-
- /* LRECL=255 */
- err = __txlrec(&txt99, "255");
- if (err)
- goto quit;
-
- /* SPACE=...(pri,sec) */
- err = __txspac(&txt99, "15,15");
- if (err)
- goto quit;
-
- /* SPACE=CYLS */
- err = __txcyl(&txt99, NULL);
- if (err)
- goto quit;
-
- /* RECFM=VB */
- err = __txrecf(&txt99, "VB");
- if (err)
- goto quit;
-
- /* DSORG=PS */
- err = __txorg(&txt99, "PS");
- if (err)
- goto quit;
-
- count = arraycount(&txt99);
- if (!count)
- goto quit;
-
- /* Set high order bit to mark end of list */
- count--;
- txt99[count] = (TXT99 *)((unsigned)txt99[count] | 0x80000000);
-
- /* construct the request block for dynamic allocation */
- rb99.len = sizeof(RB99);
- rb99.request = S99VRBAL;
- rb99.flag1 = S99NOCNV;
- rb99.txtptr = txt99;
-
- /* SVC 99 */
- err = __svc99(&rb99);
- if (err)
- goto quit;
-
- /* return DDNAME */
- memcpy(ddname, txt99[0]->text, 8);
-
-quit:
- if (txt99)
- FreeTXT99Array(&txt99);
-
- // wtof("%s: exit rc=%d", __func__, err);
- return err;
-}
-
-static int alloc_dummy(char *ddname) {
- int err = 1;
- unsigned count = 0;
- TXT99 **txt99 = NULL;
- RB99 rb99 = {0};
-
- // wtof("%s: enter ddname=\"%s\"", __func__, ddname);
-
- /* we want the DDNAME returned to us */
- err = __txrddn(&txt99, NULL);
- if (err)
- goto quit;
-
- /* allocate dummy dataset */
- err = __txdmy(&txt99, NULL);
- if (err)
- goto quit;
-
- count = arraycount(&txt99);
- if (!count)
- goto quit;
-
- /* Set high order bit to mark end of list */
- count--;
- txt99[count] = (TXT99 *)((unsigned)txt99[count] | 0x80000000);
-
- /* construct the request block for dynamic allocation */
- rb99.len = sizeof(RB99);
- rb99.request = S99VRBAL;
- rb99.flag1 = S99NOCNV;
- rb99.txtptr = txt99;
-
- /* SVC 99 */
- err = __svc99(&rb99);
- if (err)
- goto quit;
-
- /* return DDNAME */
- memcpy(ddname, txt99[0]->text, 8);
-
-quit:
- if (txt99)
- FreeTXT99Array(&txt99);
-
- // wtof("%s: exit rc=%d", __func__, err);
- return err;
-}
-
-/* TSK-104: HTTPLUA moves to external project, httpd->luax dependency goes away */
-static int http_lua_publish(lua_State *L) {
- HTTPD *httpd = cgihttpd(); /* needed for HTTPLUAX macro expansion */
- lua_pushinteger(L, 4);
- lua_pushstring(L, "publish: not available");
- return 2;
-}
diff --git a/src/httpluax.c b/src/httpluax.c
deleted file mode 100644
index 8d00258..0000000
--- a/src/httpluax.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * HTTPLUAX.C - Loads all Lua functions into struct of Lua function
- * pointers that can then be called via pointer to function pointers.
- */
-#define HTTPLUAX_PRIVATE /* we don't want the defines */
-#include "httpluax.h"
-
-LUAX httpluax = {
- lua_ident, lua_newstate, lua_close,
- lua_newthread, lua_closethread, lua_resetthread,
- lua_atpanic, lua_version, lua_absindex,
- lua_gettop, lua_settop, lua_pushvalue,
- lua_rotate, lua_copy, lua_checkstack,
- lua_xmove, lua_isnumber, lua_isstring,
- lua_iscfunction, lua_isinteger, lua_isuserdata,
- lua_type, lua_typename, lua_tonumberx,
- lua_tointegerx, lua_toboolean, lua_tolstring,
- lua_rawlen, lua_tocfunction, lua_touserdata,
- lua_tothread, lua_topointer, lua_rawequal,
- lua_compare, lua_pushnil, lua_pushnumber,
- lua_pushinteger, lua_pushlstring, lua_pushstring,
- lua_pushvfstring, lua_pushfstring, lua_pushcclosure,
- lua_pushboolean, lua_pushlightuserdata, lua_pushthread,
- lua_getglobal, lua_gettable, lua_getfield,
- lua_geti, lua_rawget, lua_rawgeti,
- lua_rawgetp, lua_createtable, lua_newuserdatauv,
- lua_getmetatable, lua_getiuservalue, lua_setglobal,
- lua_settable, lua_setfield, lua_seti,
- lua_rawset, lua_rawseti, lua_rawsetp,
- lua_setmetatable, lua_setiuservalue, lua_callk,
- lua_pcallk, lua_load, lua_dump,
- lua_yieldk, lua_resume, lua_status,
- lua_isyieldable, lua_setwarnf, lua_warning,
- lua_gc, lua_error, lua_next,
- lua_concat, lua_len, lua_stringtonumber,
- lua_getallocf, lua_setallocf, lua_toclose,
- lua_closeslot, lua_getstack, lua_getinfo,
- lua_getlocal, lua_setlocal, lua_getupvalue,
- lua_setupvalue, lua_upvalueid, lua_upvaluejoin,
- lua_sethook, lua_gethook, lua_gethookmask,
- lua_gethookcount, lua_setcstacklimit, lua_arith,
- (void*)0, (void*)0, (void*)0,
- /* 0x198 (408 bytes) */
- /* LAUXLIB */
- luaL_checkversion_, luaL_getmetafield, luaL_callmeta,
- luaL_tolstring, luaL_argerror, luaL_typeerror,
- luaL_checklstring, luaL_optlstring, luaL_checknumber,
- luaL_optnumber, luaL_checkinteger, luaL_optinteger,
- luaL_checkstack, luaL_checktype, luaL_checkany,
- luaL_newmetatable, luaL_setmetatable, luaL_testudata,
- luaL_checkudata, luaL_where, luaL_error,
- luaL_checkoption, luaL_fileresult, luaL_execresult,
- luaL_ref, luaL_unref, luaL_loadfilex,
- luaL_loadbufferx, luaL_loadstring, luaL_newstate,
- luaL_len, luaL_addgsub, luaL_gsub,
- luaL_setfuncs, luaL_getsubtable, luaL_traceback,
- luaL_requiref, luaL_buffinit, luaL_prepbuffsize,
- luaL_addlstring, luaL_addstring, luaL_addvalue,
- luaL_pushresult, luaL_pushresultsize, luaL_buffinitsize,
- luaL_openlibs, (void*)0, (void*)0
- /* 0x258 (600 bytes */
-};
diff --git a/src/httppc.c b/src/httppc.c
index 9518e38..a09b133 100644
--- a/src/httppc.c
+++ b/src/httppc.c
@@ -79,6 +79,15 @@ httppc(HTTPC *httpc)
goto check_done;
}
+ /* extension-based CGI (pattern starts with "*."):
+ set SCRIPT_FILENAME = docroot + request path */
+ if (cgi->path[0] == '*' && cgi->path[1] == '.') {
+ char scriptfile[384];
+ snprintf(scriptfile, sizeof(scriptfile), "%s%s",
+ httpd->docroot, path);
+ http_set_env(httpc, "SCRIPT_FILENAME", scriptfile);
+ }
+
/* path needs to be processed by external program */
rc = http_process_cgi(httpc, cgi);
goto check_done;
diff --git a/src/httpprm.c b/src/httpprm.c
index 0fd1394..5e61a61 100644
--- a/src/httpprm.c
+++ b/src/httpprm.c
@@ -109,9 +109,6 @@ set_defaults(HTTPD *httpd)
httpd->bind_tries = 10;
httpd->bind_sleep = 10;
httpd->listen_queue = 5;
- httpd->cgilua_dataset = NULL;
- httpd->cgilua_path = NULL;
- httpd->cgilua_cpath = NULL;
httpd->unused_80 = NULL;
strcpy(httpd->docroot, "/www");
httpd->codepage[0] = '\0';
@@ -303,15 +300,6 @@ parse_keyvalue(HTTPD *httpd, const char *key, const char *value)
free(tmp);
}
- else if (strcmp(key, "CGILUA_DATASET") == 0) {
- httpd->cgilua_dataset = strdup(value);
- }
- else if (strcmp(key, "CGILUA_PATH") == 0) {
- httpd->cgilua_path = strdup(value);
- }
- else if (strcmp(key, "CGILUA_CPATH") == 0) {
- httpd->cgilua_cpath = strdup(value);
- }
else if (strcmp(key, "CLIENT_TIMEOUT_MSG") == 0) {
if (atoi(value) > 0) httpd->client |= HTTPD_CLIENT_INMSG;
else httpd->client &= ~HTTPD_CLIENT_INMSG;
diff --git a/src/httprexx.c b/src/httprexx.c
deleted file mode 100644
index 5db36ad..0000000
--- a/src/httprexx.c
+++ /dev/null
@@ -1,587 +0,0 @@
-/* HTTPREXX.C - CGI Program, REST style CGI program to link BREXX and execute script */
-#include "httpd.h"
-#include "svc99.h"
-#include "clibary.h"
-#include "clibos.h"
-
-#define httpx (httpd->httpx)
-
-static int link_rexx(HTTPD *httpd, HTTPC *httpc, const char *script);
-
-int main(int argc, char **argv)
-{
- int rc = 0;
- CLIBPPA *ppa = __ppaget();
- CLIBGRT *grt = __grtget();
- CLIBCRT *crt = __crtget();
- void *crtapp1= NULL;
- void *crtapp2= NULL;
- HTTPD *httpd = grt->grtapp1;
- HTTPC *httpc = grt->grtapp2;
- char *path = NULL;
- char *script = NULL;
-
- if (!httpd) {
- wtof("This program %s must be called by the HTTPD web server%s", argv[0], "");
- /* TSO callers might not see a WTO message, so we send a STDOUT message too */
- printf("This program %s must be called by the HTTPD web server%s", argv[0], "\n");
- return 12;
- }
-
- /* save for our exit/exterbnal programs */
- if (crt) {
- crtapp1 = crt->crtapp1;
- crtapp2 = crt->crtapp2;
- crt->crtapp1 = httpd;
- crt->crtapp2 = httpc;
- }
-
- // wtof("%s: enter", argv[0]);
-
- // wtof("%s: ppa=0x%08X grt=0x%08X httpd=0x%08X httpc=0x%08X",
- // argv[0], ppa, grt, httpd, httpc);
-
- /* get the request path string */
- path = http_get_env(httpc, "REQUEST_PATH");
- script = strrchr(path, '/');
-
- // wtof("%s: path=\"%s\"", argv[0], path);
- // wtof("%s: script=\"%s\"", argv[0], path);
-
- if (script) {
- rc = link_rexx(httpd, httpc, script);
- }
-
-quit:
- if (crt) {
- /* restore crt values */
- crt->crtapp1 = crtapp1;
- crt->crtapp2 = crtapp2;
- }
-
- // wtof("%s: exit rc=%d", argv[0], rc);
- return rc;
-}
-
-static int link(HTTPD *httpd, HTTPC *httpc, const char *pgm, const char *script);
-static int alloc_dummy(const char *ddanme);
-static int alloc_temp(const char *ddname);
-static int alloc_temp_vars(const char *ddname);
-static int free_alloc(const char *ddname);
-static int process_stdout(HTTPD *httpd, HTTPC *httpc);
-static int process_stderr(HTTPD *httpd, HTTPC *httpc, const char *script);
-static int process_abend(HTTPD *httpd, HTTPC *httpc, int rc);
-static int create_vars(HTTPD *httpd, HTTPC *httpc);
-
-static int
-link_rexx(HTTPD *httpd, HTTPC *httpc, const char *script)
-{
- int rc = 0;
- int lockrc = 0;
- int lines = 0;
- int errors = 0;
- void *httpsay = NULL;
- void *dcb = 0;
- unsigned size = 0;
- char ac = 0;
- CDE *cde;
-
- // wtof("%s: enter", __func__);
-
- /* get the steplib DCB */
- dcb = __steplb();
- /* load the HTTPSAY module into storage */
- httpsay = __load(dcb, "HTTPSAY ", &size, &ac);
-
- // wtof("%s: HTTPSAY ep=%08X size=%u, ac=%u", __func__, httpsay, size, ac);
-
- /* Serialize (lock) the address of this function so that
- * only one CGI instance (for BREXX) runs at a time.
- */
- lockrc = lock(link_rexx, LOCK_EXC);
-
- while(*script=='/') script++;
-
- /* just in case we have stale allocations */
- free_alloc("STDIN");
- free_alloc("STDOUT");
- free_alloc("STDERR");
-
- /* allocate dataset for BREXX */
- rc = alloc_dummy("STDIN");
- if (rc) goto quit;
-
- rc = alloc_temp("STDOUT");
- if (rc) goto quit;
-
- rc = alloc_temp("STDERR");
- if (rc) goto quit;
-
- /* write server/client variables to "DD:HTTPVARS" */
- rc = create_vars(httpd, httpc);
- if (rc) goto quit;
-
- /* link to external program */
- rc = link(httpd, httpc, "BREXX", script);
- if (rc < 0) process_abend(httpd, httpc, rc);
-
- /* create response using STDOUT dataseet */
- lines = process_stdout(httpd, httpc);
-
- /* process any errors found in STDERR dataset */
- errors = process_stderr(httpd, httpc, script);
-
-deallocate:
- /* release allocations */
- free_alloc("STDIN");
- free_alloc("STDOUT");
- free_alloc("STDERR");
- free_alloc("HTTPVARS");
-
-quit:
- if (lockrc==0) unlock(link_rexx, LOCK_EXC);
-
- if (httpsay) __delete("HTTPSAY ");
-
- if (!httpc->resp) {
- http_resp(httpc,503);
- http_printf(httpc, "Content-Type: %s\r\n", "text/plain");
- http_printf(httpc, "\r\n");
- http_printf(httpc, "One or more errors occurred processing your request\n");
- }
-
- httpc->state = CSTATE_DONE;
- // wtof("%s: exit rc=%d", __func__, rc);
- return rc;
-}
-
-static int
-link(HTTPD *httpd, HTTPC *httpc, const char *pgm, const char *script)
-{
- void *ppa = NULL;
- int rc = -1; /* link return code */
- int prc = -1; /* pgm return code */
- void *dcb = NULL; /* no DCB for link */
- char *query;
- struct {
- unsigned short len;
- char buf[512];
- } parms = {0, ""};
- unsigned plist[4];
-
- // wtof("%s: enter", __func__);
-
- if (!pgm) goto quit; /* NULL program, quit */
- if (!*pgm) goto quit; /* "" program name, quit */
-
- query = http_get_env(httpc, "QUERY_STRING");
- if (!query) query = "";
-
- if (script) {
- /* put request in quotes as parameter string */
- snprintf(parms.buf, sizeof(parms.buf)-1, "%s \"%s\"", script, query);
- parms.buf[sizeof(parms.buf)-1] = 0;
- parms.len = strlen(parms.buf);
- }
-
- // wtodumpf(&parms, sizeof(parms), "%s: parms", __func__);
-
- /* build parameter list for the program we're linking to */
- plist[0] = (unsigned)&parms | 0x80000000;
- plist[1] = 0;
- plist[2] = 0;
- plist[3] = 0;
-
- // wtodumpf(plist, sizeof(plist), "%s: plist", __func__);
-
- /* link to pgm, with ESTAE */
- rc = __linkds(pgm, dcb, plist, &prc);
- // wtof("%s: __linkds(\"%s\",0,0x%08X,0x%08X) rc=%d prc=%d",
- // __func__, pgm, plist, &prc, rc, prc);
-
- if (rc==0) rc = prc;
-
-quit:
- // wtof("%s: exit rc=%d", __func__, rc);
- return rc;
-}
-
-static int
-create_vars(HTTPD *httpd, HTTPC *httpc)
-{
- int rc = 0;
- FILE *fp = NULL;
- char *p;
- char name[256];
-
- free_alloc("HTTPVARS");
-
- rc = alloc_temp_vars("HTTPVARS");
- if (rc) goto quit;
-
- /* create dataset containing client variables */
- fp = fopen("DD:HTTPVARS", "w");
- if (!fp) goto quit;
-
- if (httpc->env) {
- unsigned count = array_count(&httpc->env);
- unsigned n;
- for(n=0;nenv[n];
-
- if (!env) continue;
-
- /* BREXX doesn't permit variable names with '-' in the name
- * so we'll transform those to underscore characters.
- */
- strcpy(name, env->name);
- for(p=strchr(name,'-'); p; p=strchr(name,'-')) *p = '_';
- fprintf(fp, "%s=\"%s\"\n", name, env->value);
- // wtof("%s: %s=\"%s\"", __func__, name, env->value);
- }
- }
-
-quit:
- if (fp) fclose(fp);
- return rc;
-}
-
-static int
-process_stdout(HTTPD *httpd, HTTPC *httpc)
-{
- int lines = 0;
- FILE *fp = NULL;
- char *p = NULL;
- char buf[256];
-
- /* create response */
- fp = fopen("DD:STDOUT", "r");
- // wtof("%s: fopen(\"DD:STDOUT\",\"r\") fp=0x%08X", __func__, fp);
- if (!fp) goto quit;
-
- while(p=fgets(buf, sizeof(buf), fp)) {
- if (!lines) {
- if (!httpc->resp && __patmat(buf, "HTTP/?.? *")) {
- /* looks like a HTTP response header */
- char *tmp = strdup(buf);
- if (tmp) {
- char *p1 = strtok(tmp, " "); /* HTTP/1.0 */
- char *p2 = strtok(NULL, " "); /* nnn */
- char *p3 = strtok(NULL, ""); /* OK or whatever */
-
- if (p2) httpc->resp = atoi(p2);
- free(tmp);
- }
- }
-
- if (!httpc->resp) {
- /* we don't have a HTTP response */
- http_resp(httpc,200);
- while(*p==' ') p++;
- if (p[0]=='<') {
- /* looks like a HTML markup tag */
- http_printf(httpc, "Content-Type: %s\r\n", "text/html");
- }
- else {
- /* anything else */
- http_printf(httpc, "Content-Type: %s\r\n", "text/plain");
- }
- http_printf(httpc, "\r\n");
- }
- }
- http_printf(httpc, "%s", buf);
- lines++;
- }
-
-quit:
- if (fp) fclose(fp);
-
- return lines;
-}
-
-static int
-process_stderr(HTTPD *httpd, HTTPC *httpc, const char *script)
-{
- int errors = 0;
- FILE *fp = NULL;
- char *p = NULL;
- char buf[256];
-
- fp = fopen("DD:STDERR", "r");
- // wtof("%s: fopen(\"DD:STDERR\",\"r\") fp=0x%08X", __func__, fp);
- if (!fp) goto quit;
-
- while(p=fgets(buf, sizeof(buf), fp)) {
- if (!errors) {
- wtof("HTTPD500I CGI Program BREXX script \"%s\"", script);
- }
- // wtodumpf(buf, strlen(buf), "%s: stderr", __func__);
- /* strip trailing newline */
- p = strrchr(buf, '\n');
- if (p) *p = 0;
-
- wtof("HTTPD501I %s", buf);
- errors++;
- }
-
-quit:
- if (fp) fclose(fp);
- return errors;
-}
-
-static int
-process_abend(HTTPD *httpd, HTTPC *httpc, int rc)
-{
- /* some kind of ABEND occurred */
- unsigned abcode = (unsigned) (rc * -1); /* make positive again */
-
- /* we're running in the HTTPD server */
- if (!httpc->resp) {
- /* no response header was issued by CGI program */
- http_resp(httpc,503);
- http_printf(httpc, "Content-Type: %s\r\n", "text/plain");
- http_printf(httpc, "\r\n");
- }
-
- if (abcode > 4095) {
- /* system abend occurred */
- http_printf(httpc, "External program %s failed with S%03X ABEND", "BREXX", abcode >> 12);
- wtof("External program %s failed with S%03X ABEND", "BREXX", abcode >> 12);
- }
- else {
- /* user abend code */
- http_printf(httpc, "External program %s failed with U%04d ABEND", "BREXX", abcode);
- wtof("External program %s failed with U%04d ABEND", "BREXX", abcode);
- }
- http_printf(httpc, "\n");
-
- return rc;
-}
-
-static int
-alloc_dummy(const char *ddname)
-{
- int err = 1;
- unsigned count = 0;
- TXT99 **txt99 = NULL;
- RB99 rb99 = {0};
-
- // wtof("%s: enter ddname=\"%s\"", __func__, ddname);
-
- /* allocate this dd name */
- err = __txddn(&txt99, ddname);
- if (err) goto quit;
-
- /* allocate dummy dataset */
- err = __txdmy(&txt99, NULL);
- if (err) goto quit;
-
- count = arraycount(&txt99);
- if (!count) goto quit;
-
- /* Set high order bit to mark end of list */
- count--;
- txt99[count] = (TXT99*)((unsigned)txt99[count] | 0x80000000);
-
- /* construct the request block for dynamic allocation */
- rb99.len = sizeof(RB99);
- rb99.request = S99VRBAL;
- rb99.flag1 = S99NOCNV;
- rb99.txtptr = txt99;
-
- /* SVC 99 */
- err = __svc99(&rb99);
- if (err) goto quit;
-
-quit:
- if (txt99) FreeTXT99Array(&txt99);
-
- // wtof("%s: exit rc=%d", __func__, err);
- return err;
-}
-
-static int alloc_temp(const char *ddname)
-{
- int err = 1;
- unsigned count = 0;
- TXT99 **txt99 = NULL;
- RB99 rb99 = {0};
- char tempname[40];
-
- // wtof("%s: enter ddname=\"%s\"", __func__, ddname);
-
- snprintf(tempname, sizeof(tempname), "&%s", ddname);
- tempname[sizeof(tempname)-1] = 0;
-
- /* allocate this dd name */
- err = __txddn(&txt99, ddname);
- if (err) goto quit;
-
- /* allocate this dataset */
- err = __txdsn(&txt99, tempname);
- if (err) goto quit;
-
- /* DISP=NEW */
- err = __txnew(&txt99, NULL);
- if (err) goto quit;
-
- /* BLKSIZE=27998 */
- err = __txbksz(&txt99, "27998");
- if (err) goto quit;
-
- /* LRECL=255 */
- err = __txlrec(&txt99, "255");
- if (err) goto quit;
-
- /* SPACE=...(pri,sec) */
- err = __txspac(&txt99, "15,15");
- if (err) goto quit;
-
- /* SPACE=CYLS */
- err = __txcyl(&txt99, NULL);
- if (err) goto quit;
-
- /* RECFM=VB */
- err = __txrecf(&txt99, "VB");
- if (err) goto quit;
-
- /* DSORG=PS */
- err = __txorg(&txt99, "PS");
- if (err) goto quit;
-
- count = arraycount(&txt99);
- if (!count) goto quit;
-
- /* Set high order bit to mark end of list */
- count--;
- txt99[count] = (TXT99*)((unsigned)txt99[count] | 0x80000000);
-
- /* construct the request block for dynamic allocation */
- rb99.len = sizeof(RB99);
- rb99.request = S99VRBAL;
- rb99.flag1 = S99NOCNV;
- rb99.txtptr = txt99;
-
- /* SVC 99 */
- err = __svc99(&rb99);
- if (err) goto quit;
-
-quit:
- if (txt99) FreeTXT99Array(&txt99);
-
- // wtof("%s: exit rc=%d", __func__, err);
- return err;
-}
-
-static int alloc_temp_vars(const char *ddname)
-{
- int err = 1;
- unsigned count = 0;
- TXT99 **txt99 = NULL;
- RB99 rb99 = {0};
- char tempname[40];
-
- // wtof("%s: enter ddname=\"%s\"", __func__, ddname);
-
- snprintf(tempname, sizeof(tempname), "&%s", ddname);
- tempname[sizeof(tempname)-1] = 0;
-
- /* allocate this dd name */
- err = __txddn(&txt99, ddname);
- if (err) goto quit;
-
- /* allocate this dataset */
- err = __txdsn(&txt99, tempname);
- if (err) goto quit;
-
- /* DISP=NEW */
- err = __txnew(&txt99, NULL);
- if (err) goto quit;
-
- /* BLKSIZE=27998 */
- err = __txbksz(&txt99, "27998");
- if (err) goto quit;
-
- /* LRECL=8232 */
- err = __txlrec(&txt99, "8232");
- if (err) goto quit;
-
- /* SPACE=...(pri,sec) */
- err = __txspac(&txt99, "15,15");
- if (err) goto quit;
-
- /* SPACE=TRACKS */
- err = __txtrk(&txt99, NULL);
- if (err) goto quit;
-
- /* RECFM=FB */
- err = __txrecf(&txt99, "VB");
- if (err) goto quit;
-
- /* DSORG=PS */
- err = __txorg(&txt99, "PS");
- if (err) goto quit;
-
- count = arraycount(&txt99);
- if (!count) goto quit;
-
- /* Set high order bit to mark end of list */
- count--;
- txt99[count] = (TXT99*)((unsigned)txt99[count] | 0x80000000);
-
- /* construct the request block for dynamic allocation */
- rb99.len = sizeof(RB99);
- rb99.request = S99VRBAL;
- rb99.flag1 = S99NOCNV;
- rb99.txtptr = txt99;
-
- /* SVC 99 */
- err = __svc99(&rb99);
- if (err) goto quit;
-
-quit:
- if (txt99) FreeTXT99Array(&txt99);
-
- // wtof("%s: exit rc=%d", __func__, err);
- return err;
-}
-
-static int free_alloc(const char *ddname)
-{
- int err = 1;
- unsigned count = 0;
- TXT99 **txt99 = NULL;
- RB99 rb99 = {0};
-
- // wtof("%s: enter ddname=\"%s\"", __func__, ddname);
-
- /* we want to unallocate the DDNAME */
- err = __txddn(&txt99, ddname);
- if (err) goto quit;
-
- count = arraycount(&txt99);
- if (!count) goto quit;
-
- /* Set high order bit to mark end of list */
- count--;
- txt99[count] = (TXT99*)((unsigned)txt99[count] | 0x80000000);
-
- /* construct the request block for dynamic allocation */
- rb99.len = sizeof(RB99);
- rb99.request = S99VRBUN;
- rb99.flag1 = S99NOCNV;
- rb99.txtptr = txt99;
-
- /* SVC 99 */
- err = __svc99(&rb99);
- if (err) {
- // wtof("%s: err=%d error=0x%04X info=0x%04X", __func__, err, rb99.error, rb99.info);
- goto quit;
- }
-
-quit:
- if (txt99) FreeTXT99Array(&txt99);
-
- // wtof("%s: exit rc=%d", __func__, err);
- return err;
-}
diff --git a/src/httpsay.c b/src/httpsay.c
deleted file mode 100644
index 8b2fd10..0000000
--- a/src/httpsay.c
+++ /dev/null
@@ -1,162 +0,0 @@
-#include "httpd.h"
-#include "clibppa.h"
-#include "clibgrt.h"
-
-/* MVS style parameter when called from BREXX for
- * ADDRESS LINKMVS "HTTPVARS var1 .. var15"
- */
-typedef struct parm {
- short len;
- char buf[1];
-} PARM;
-
-/* BREXX structs */
-typedef struct efpl {
- void *efplcom; /* reserved */
- void *efplbarg; /* reserved */
- void *efplearg; /* reserved */
- void *efplfb; /* reserved */
- void *efplarg; /* Pointer to arguments table */
- void *efpleval; /* Pointer to address of the EVALBLOCK */
-} EFPL;
-
-typedef struct argtable_entry {
- void *argtable_argstring_ptr; /* Address of the argument string */
- int argtable_argstring_length; /* Length of the argument string */
-} ATE;
-
-typedef struct evalblock {
- int evalblock_evpad1; /* reserved - set to binary zero */
- int evalblock_evsize; /* Size of EVALBLOCK in double words */
- int evalblock_evlen; /* Length of data */
- int evalblock_evpad2; /* reserved - set to binary zero */
- unsigned char evalblock_evdata[1]; /* Result */
-} EVAL;
-
-#define MAXPARMS 15 /* maximum number of arguments we can handle */
-
-extern int main(int argc, char **argv);
-extern void __exita(int status);
-
-static int process_say(HTTPD *httpd, HTTPC *httpc, const char *buf);
-
-/* initialize to 0 to prevent linkage editor from trying to resolve httpx */
-HTTPX *httpx = 0;
-
-/* we want to use the httpx pointer in the httpd struct for the various
- http_xxx functions, so we define httpx to do just that
-*/
-#define httpx (httpd->httpx)
-
-/* NOTE: This code expects to be called from @@CRTM which is
- * a minimal @@CRT0 implementation that does not create a
- * PPA area in the stack. This allows the @@PPAGET code to
- * locate the PPA of the parent so that the GRT area can be
- * located and used for the HTTPD and HTTPC pointers.
- */
-int
-__start(void *r0, char *pgmname, int tsojbid, void **r1)
-{
- int rc = 0;
- // CLIBPPA *ppa = __ppaget();
- CLIBGRT *grt = __grtget();
- // CLIBCRT *crt = __crtget();
- HTTPD *httpd = grt->grtapp1;
- HTTPC *httpc = grt->grtapp2;
- PARM *parm;
- EFPL *efpl = NULL;
- ATE *ate = NULL;
- // EVAL *eval = NULL;
- char *buf = NULL;
- int i;
-
-#if 0
- wtof("%s: r0=0x%08X", __func__, r0);
- wtodumpf(r0, 32, "r0");
- wtof("%s: r1=0x%08X", __func__, r1);
- wtodumpf(r1, 32, "r1");
-#endif
-
-#if 1
- /* This code for ADDRESS LINKMVS "HTTPSAY var1 var2 ... var15" */
- if (r1) {
- for(parm = r1[0], i=0; i < MAXPARMS; parm = r1[++i]) {
- if (!parm) break;
- // wtodumpf(parm, 32, "parm[%d]", i);
-
- buf = calloc(1, parm->len + 1);
- if (buf) {
- memcpy(buf, parm->buf, parm->len);
- rc = process_say(httpd, httpc, buf);
- free(buf);
- buf = NULL;
- }
-
- if ((unsigned)parm & 0x80000000) break;
- }
- }
-
-#else
- /* this code for BREXX call HTTPSAY(parms,...) */
- if (r1) {
- efpl = (EFPL *)r1;
-
- ate = (ATE *)efpl->efplarg;
- for(i=0; i < MAXPARMS; i++, ate++) {
- if (!ate || ate->argtable_argstring_ptr == (void*)0xFFFFFFFF) break;
-
- buf = calloc(1, ate->argtable_argstring_length + 1);
- if (buf) {
- memcpy(buf, ate->argtable_argstring_ptr, ate->argtable_argstring_length);
- rc = process_say(httpd, httpc, buf);
- free(buf);
- buf = NULL;
- }
- }
- }
-#endif
-
-quit:
- if (buf) free(buf);
- __exit(rc);
- return (rc);
-}
-
-static int
-process_say(HTTPD *httpd, HTTPC *httpc, const char *buf)
-{
- int rc = 0;
- const char *p;
-
- if (!httpc->resp && __patmat(buf, "HTTP/?.? *")) {
- /* looks like a HTTP response header */
- char *tmp = strdup(buf);
- if (tmp) {
- char *p1 = strtok(tmp, " "); /* HTTP/1.0 */
- char *p2 = strtok(NULL, " "); /* nnn */
- char *p3 = strtok(NULL, ""); /* OK or whatever */
-
- if (p2) httpc->resp = atoi(p2);
- free(tmp);
- }
- }
-
- if (!httpc->resp) {
- /* we don't have a HTTP response */
- http_resp(httpc,200);
- for(p = buf; *p==' '; p++);
- if (p[0]=='<') {
- /* looks like a HTML markup tag */
- http_printf(httpc, "Content-Type: %s\r\n", "text/html");
- }
- else {
- /* anything else */
- http_printf(httpc, "Content-Type: %s\r\n", "text/plain");
- }
- http_printf(httpc, "\r\n");
- }
-
- http_printf(httpc, "%s\n", buf);
-
- return rc;
-}
diff --git a/src/lauxlib.c b/src/lauxlib.c
deleted file mode 100644
index 3b00003..0000000
--- a/src/lauxlib.c
+++ /dev/null
@@ -1,1310 +0,0 @@
-/*
-** $Id: lauxlib.c $
-** Auxiliary functions for building Lua libraries
-** See Copyright Notice in lua.h
-*/
-
-/* This is a copy of lauxlib.c from LUA370 with modifications
- * to support UFS in the HTTPD environment.
- */
-
-#define lauxlib_c
-#define LUA_LIB
-
-#include "lprefix.h"
-
-
-#include
-#include
-#include
-#include
-#include
-
-
-/*
-** This file uses only the official API of Lua.
-** Any function declared here could be written as an application function.
-*/
-
-#include "lua.h"
-
-#include "lauxlib.h"
-
-#define HTTPLUAX_PRIVATE /* suppress defines for Lua functions */
-//#define luai_likely(x) (x)
-//#define luai_unlikely(x) (x)
-#include "httpd.h"
-
-static UFSFILE *get_ufsfile(FILE *fp)
-{
- unsigned x = (unsigned)fp;
- UFSFILE *f = NULL;
-
- if (x & 0x80000000) {
- f = (UFSFILE *) (x & 0x7FFFFFFF);
- }
-
- return f;
-}
-
-static int is_member(const char *mem)
-{
- int i;
- int len;
-
- if (*mem=='(') mem++;
-
- for(i=0; mem[i] && !(mem[i]==')'); i++) {
- if (i > 7) return 0;
- if (i==0 && (isalpha(mem[i]) || strchr("@#$", mem[i]))) continue;
- if (i >0 && (isalnum(mem[i]) || strchr("@#$", mem[i]))) continue;
- return 0; // invalid character for member name
- }
-
- if (mem[i]==')') {
- len = strlen(&mem[i+1]);
- }
- else {
- len = strlen(&mem[i]);
- }
-
- if (len==0) {
- if (i>0 && i<8) {
- return 1;
- }
- }
- return 0;
-}
-
-static int is_dataset(const char *name)
-{
- int i;
- char *p;
- char buf[256];
-
- if (!name) return 0;
- if (*name=='\'') return 1; // This has to be a dataset
-
- strcpyp(buf, sizeof(buf), (void*)name, 0);
- buf[sizeof(buf)-1] = 0;
-
- for(i=1, p=buf; p[i]; p++, i++) {
- if (*p=='.') {
- i = 0;
- continue;
- }
-
- if (*p=='(') {
- return is_member(p);
- }
-
- if (i > 8) return 0;
-
- if (i==1) {
- if ( isalpha(*p) || strchr("@#$", *p) ) continue;
- }
- else {
- if ( isalnum(*p) || strchr("@#$", *p) ) continue;
- }
- return 0; // invalid character for dataset name
- }
-
- if (i>1 && i<9) {
- return 1;
- }
- return 0;
-}
-
-static int is_pathname(const char *name)
-{
- if (!name) return 0; // not path
-
- if (strchr(name, '\'')) return 0; // not path
-
- if (strchr(name, '/')) return 1; // most likely is a path
-
- if (is_dataset(name)) return 0; // not path, looks like a dataset name
-
- return 1;
-}
-
-#if !defined(MAX_SIZET)
-/* maximum value for size_t */
-#define MAX_SIZET ((size_t)(~(size_t)0))
-#endif
-
-
-/*
-** {======================================================
-** Traceback
-** =======================================================
-*/
-
-
-#define LEVELS1 10 /* size of the first part of the stack */
-#define LEVELS2 11 /* size of the second part of the stack */
-
-
-
-/*
-** Search for 'objidx' in table at index -1. ('objidx' must be an
-** absolute index.) Return 1 + string at top if it found a good name.
-*/
-static int findfield (lua_State *L, int objidx, int level) {
- if (level == 0 || !lua_istable(L, -1))
- return 0; /* not found */
- lua_pushnil(L); /* start 'next' loop */
- while (lua_next(L, -2)) { /* for each pair in table */
- if (lua_type(L, -2) == LUA_TSTRING) { /* ignore non-string keys */
- if (lua_rawequal(L, objidx, -1)) { /* found object? */
- lua_pop(L, 1); /* remove value (but keep name) */
- return 1;
- }
- else if (findfield(L, objidx, level - 1)) { /* try recursively */
- /* stack: lib_name, lib_table, field_name (top) */
- lua_pushliteral(L, "."); /* place '.' between the two names */
- lua_replace(L, -3); /* (in the slot occupied by table) */
- lua_concat(L, 3); /* lib_name.field_name */
- return 1;
- }
- }
- lua_pop(L, 1); /* remove value */
- }
- return 0; /* not found */
-}
-
-
-/*
-** Search for a name for a function in all loaded modules
-*/
-static int pushglobalfuncname (lua_State *L, lua_Debug *ar) {
- int top = lua_gettop(L);
- lua_getinfo(L, "f", ar); /* push function */
- lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
- if (findfield(L, top + 1, 2)) {
- const char *name = lua_tostring(L, -1);
- if (strncmp(name, LUA_GNAME ".", 3) == 0) { /* name start with '_G.'? */
- lua_pushstring(L, name + 3); /* push name without prefix */
- lua_remove(L, -2); /* remove original name */
- }
- lua_copy(L, -1, top + 1); /* copy name to proper place */
- lua_settop(L, top + 1); /* remove table "loaded" and name copy */
- return 1;
- }
- else {
- lua_settop(L, top); /* remove function and global table */
- return 0;
- }
-}
-
-
-static void pushfuncname (lua_State *L, lua_Debug *ar) {
- if (pushglobalfuncname(L, ar)) { /* try first a global name */
- lua_pushfstring(L, "function '%s'", lua_tostring(L, -1));
- lua_remove(L, -2); /* remove name */
- }
- else if (*ar->namewhat != '\0') /* is there a name from code? */
- lua_pushfstring(L, "%s '%s'", ar->namewhat, ar->name); /* use it */
- else if (*ar->what == 'm') /* main? */
- lua_pushliteral(L, "main chunk");
- else if (*ar->what != 'C') /* for Lua functions, use */
- lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined);
- else /* nothing left... */
- lua_pushliteral(L, "?");
-}
-
-
-static int lastlevel (lua_State *L) {
- lua_Debug ar;
- int li = 1, le = 1;
- /* find an upper bound */
- while (lua_getstack(L, le, &ar)) { li = le; le *= 2; }
- /* do a binary search */
- while (li < le) {
- int m = (li + le)/2;
- if (lua_getstack(L, m, &ar)) li = m + 1;
- else le = m;
- }
- return le - 1;
-}
-
-
-LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1,
- const char *msg, int level) {
- luaL_Buffer b;
- lua_Debug ar;
- int last = lastlevel(L1);
- int limit2show = (last - level > LEVELS1 + LEVELS2) ? LEVELS1 : -1;
- luaL_buffinit(L, &b);
- if (msg) {
- luaL_addstring(&b, msg);
- luaL_addchar(&b, '\n');
- }
- luaL_addstring(&b, "stack traceback:");
- while (lua_getstack(L1, level++, &ar)) {
- if (limit2show-- == 0) { /* too many levels? */
- int n = last - level - LEVELS2 + 1; /* number of levels to skip */
- lua_pushfstring(L, "\n\t...\t(skipping %d levels)", n);
- luaL_addvalue(&b); /* add warning about skip */
- level += n; /* and skip to last levels */
- }
- else {
- lua_getinfo(L1, "Slnt", &ar);
- if (ar.currentline <= 0)
- lua_pushfstring(L, "\n\t%s: in ", ar.short_src);
- else
- lua_pushfstring(L, "\n\t%s:%d: in ", ar.short_src, ar.currentline);
- luaL_addvalue(&b);
- pushfuncname(L, &ar);
- luaL_addvalue(&b);
- if (ar.istailcall)
- luaL_addstring(&b, "\n\t(...tail calls...)");
- }
- }
- luaL_pushresult(&b);
-}
-
-/* }====================================================== */
-
-
-/*
-** {======================================================
-** Error-report functions
-** =======================================================
-*/
-
-LUALIB_API int luaL_argerror (lua_State *L, int arg, const char *extramsg) {
- lua_Debug ar;
- if (!lua_getstack(L, 0, &ar)) /* no stack frame? */
- return luaL_error(L, "bad argument #%d (%s)", arg, extramsg);
- lua_getinfo(L, "n", &ar);
- if (strcmp(ar.namewhat, "method") == 0) {
- arg--; /* do not count 'self' */
- if (arg == 0) /* error is in the self argument itself? */
- return luaL_error(L, "calling '%s' on bad self (%s)",
- ar.name, extramsg);
- }
- if (ar.name == NULL)
- ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?";
- return luaL_error(L, "bad argument #%d to '%s' (%s)",
- arg, ar.name, extramsg);
-}
-
-
-LUALIB_API int luaL_typeerror (lua_State *L, int arg, const char *tname) {
- const char *msg;
- const char *typearg; /* name for the type of the actual argument */
- if (luaL_getmetafield(L, arg, "__name") == LUA_TSTRING)
- typearg = lua_tostring(L, -1); /* use the given type name */
- else if (lua_type(L, arg) == LUA_TLIGHTUSERDATA)
- typearg = "light userdata"; /* special name for messages */
- else
- typearg = luaL_typename(L, arg); /* standard name */
- msg = lua_pushfstring(L, "%s expected, got %s", tname, typearg);
- return luaL_argerror(L, arg, msg);
-}
-
-
-static void tag_error (lua_State *L, int arg, int tag) {
- luaL_typeerror(L, arg, lua_typename(L, tag));
-}
-
-
-/*
-** The use of 'lua_pushfstring' ensures this function does not
-** need reserved stack space when called.
-*/
-LUALIB_API void luaL_where (lua_State *L, int level) {
- lua_Debug ar;
- if (lua_getstack(L, level, &ar)) { /* check function at level */
- lua_getinfo(L, "Sl", &ar); /* get info about it */
- if (ar.currentline > 0) { /* is there info? */
- lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline);
- return;
- }
- }
- lua_pushfstring(L, ""); /* else, no information available... */
-}
-
-
-/*
-** Again, the use of 'lua_pushvfstring' ensures this function does
-** not need reserved stack space when called. (At worst, it generates
-** an error with "stack overflow" instead of the given message.)
-*/
-LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
- va_list argp;
- va_start(argp, fmt);
- luaL_where(L, 1);
- lua_pushvfstring(L, fmt, argp);
- va_end(argp);
- lua_concat(L, 2);
- return lua_error(L);
-}
-
-
-LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) {
- int en = errno; /* calls to Lua API may change this value */
- if (stat) {
- lua_pushboolean(L, 1);
- return 1;
- }
- else {
- luaL_pushfail(L);
- if (fname)
- lua_pushfstring(L, "%s: %s", fname, strerror(en));
- else
- lua_pushstring(L, strerror(en));
- lua_pushinteger(L, en);
- return 3;
- }
-}
-
-
-#if !defined(l_inspectstat) /* { */
-
-#if defined(LUA_USE_POSIX)
-
-#include
-
-/*
-** use appropriate macros to interpret 'pclose' return status
-*/
-#define l_inspectstat(stat,what) \
- if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \
- else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; }
-
-#else
-
-#define l_inspectstat(stat,what) /* no op */
-
-#endif
-
-#endif /* } */
-
-
-LUALIB_API int luaL_execresult (lua_State *L, int stat) {
- if (stat != 0 && errno != 0) /* error with an 'errno'? */
- return luaL_fileresult(L, 0, NULL);
- else {
- const char *what = "exit"; /* type of termination */
- l_inspectstat(stat, what); /* interpret result */
- if (*what == 'e' && stat == 0) /* successful termination? */
- lua_pushboolean(L, 1);
- else
- luaL_pushfail(L);
- lua_pushstring(L, what);
- lua_pushinteger(L, stat);
- return 3; /* return true/fail,what,code */
- }
-}
-
-/* }====================================================== */
-
-
-
-/*
-** {======================================================
-** Userdata's metatable manipulation
-** =======================================================
-*/
-
-LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
- if (luaL_getmetatable(L, tname) != LUA_TNIL) /* name already in use? */
- return 0; /* leave previous value on top, but return 0 */
- lua_pop(L, 1);
- lua_createtable(L, 0, 2); /* create metatable */
- lua_pushstring(L, tname);
- lua_setfield(L, -2, "__name"); /* metatable.__name = tname */
- lua_pushvalue(L, -1);
- lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */
- return 1;
-}
-
-
-LUALIB_API void luaL_setmetatable (lua_State *L, const char *tname) {
- luaL_getmetatable(L, tname);
- lua_setmetatable(L, -2);
-}
-
-
-LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) {
- void *p = lua_touserdata(L, ud);
- if (p != NULL) { /* value is a userdata? */
- if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
- luaL_getmetatable(L, tname); /* get correct metatable */
- if (!lua_rawequal(L, -1, -2)) /* not the same? */
- p = NULL; /* value is a userdata with wrong metatable */
- lua_pop(L, 2); /* remove both metatables */
- return p;
- }
- }
- return NULL; /* value is not a userdata with a metatable */
-}
-
-
-LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
- void *p = luaL_testudata(L, ud, tname);
- luaL_argexpected(L, p != NULL, ud, tname);
- return p;
-}
-
-/* }====================================================== */
-
-
-/*
-** {======================================================
-** Argument check functions
-** =======================================================
-*/
-
-LUALIB_API int luaL_checkoption (lua_State *L, int arg, const char *def,
- const char *const lst[]) {
- const char *name = (def) ? luaL_optstring(L, arg, def) :
- luaL_checkstring(L, arg);
- int i;
- for (i=0; lst[i]; i++)
- if (strcmp(lst[i], name) == 0)
- return i;
- return luaL_argerror(L, arg,
- lua_pushfstring(L, "invalid option '%s'", name));
-}
-
-
-/*
-** Ensures the stack has at least 'space' extra slots, raising an error
-** if it cannot fulfill the request. (The error handling needs a few
-** extra slots to format the error message. In case of an error without
-** this extra space, Lua will generate the same 'stack overflow' error,
-** but without 'msg'.)
-*/
-LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) {
- if (l_unlikely(!lua_checkstack(L, space))) {
- if (msg)
- luaL_error(L, "stack overflow (%s)", msg);
- else
- luaL_error(L, "stack overflow");
- }
-}
-
-
-LUALIB_API void luaL_checktype (lua_State *L, int arg, int t) {
- if (l_unlikely(lua_type(L, arg) != t))
- tag_error(L, arg, t);
-}
-
-
-LUALIB_API void luaL_checkany (lua_State *L, int arg) {
- if (l_unlikely(lua_type(L, arg) == LUA_TNONE))
- luaL_argerror(L, arg, "value expected");
-}
-
-
-LUALIB_API const char *luaL_checklstring (lua_State *L, int arg, size_t *len) {
- const char *s = lua_tolstring(L, arg, len);
- if (l_unlikely(!s)) tag_error(L, arg, LUA_TSTRING);
- return s;
-}
-
-
-LUALIB_API const char *luaL_optlstring (lua_State *L, int arg,
- const char *def, size_t *len) {
- if (lua_isnoneornil(L, arg)) {
- if (len)
- *len = (def ? strlen(def) : 0);
- return def;
- }
- else return luaL_checklstring(L, arg, len);
-}
-
-
-LUALIB_API lua_Number luaL_checknumber (lua_State *L, int arg) {
- int isnum;
- lua_Number d = lua_tonumberx(L, arg, &isnum);
- if (l_unlikely(!isnum))
- tag_error(L, arg, LUA_TNUMBER);
- return d;
-}
-
-
-LUALIB_API lua_Number luaL_optnumber (lua_State *L, int arg, lua_Number def) {
- return luaL_opt(L, luaL_checknumber, arg, def);
-}
-
-
-static void interror (lua_State *L, int arg) {
- if (lua_isnumber(L, arg))
- luaL_argerror(L, arg, "number has no integer representation");
- else
- tag_error(L, arg, LUA_TNUMBER);
-}
-
-
-LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int arg) {
- int isnum;
- lua_Integer d = lua_tointegerx(L, arg, &isnum);
- if (l_unlikely(!isnum)) {
- interror(L, arg);
- }
- return d;
-}
-
-
-LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int arg,
- lua_Integer def) {
- return luaL_opt(L, luaL_checkinteger, arg, def);
-}
-
-/* }====================================================== */
-
-
-/*
-** {======================================================
-** Generic Buffer manipulation
-** =======================================================
-*/
-
-/* userdata to box arbitrary data */
-typedef struct UBox {
- void *box;
- size_t bsize;
-} UBox;
-
-
-static void *resizebox (lua_State *L, int idx, size_t newsize) {
- void *ud;
- lua_Alloc allocf = lua_getallocf(L, &ud);
- UBox *box = (UBox *)lua_touserdata(L, idx);
- void *temp = allocf(ud, box->box, box->bsize, newsize);
- if (l_unlikely(temp == NULL && newsize > 0)) { /* allocation error? */
- lua_pushliteral(L, "not enough memory");
- lua_error(L); /* raise a memory error */
- }
- box->box = temp;
- box->bsize = newsize;
- return temp;
-}
-
-
-static int boxgc (lua_State *L) {
- resizebox(L, 1, 0);
- return 0;
-}
-
-
-static const luaL_Reg boxmt[] = { /* box metamethods */
- {"__gc", boxgc},
- {"__close", boxgc},
- {NULL, NULL}
-};
-
-
-static void newbox (lua_State *L) {
- UBox *box = (UBox *)lua_newuserdatauv(L, sizeof(UBox), 0);
- box->box = NULL;
- box->bsize = 0;
- if (luaL_newmetatable(L, "_UBOX*")) /* creating metatable? */
- luaL_setfuncs(L, boxmt, 0); /* set its metamethods */
- lua_setmetatable(L, -2);
-}
-
-
-/*
-** check whether buffer is using a userdata on the stack as a temporary
-** buffer
-*/
-#define buffonstack(B) ((B)->b != (B)->init.b)
-
-
-/*
-** Whenever buffer is accessed, slot 'idx' must either be a box (which
-** cannot be NULL) or it is a placeholder for the buffer.
-*/
-#define checkbufferlevel(B,idx) \
- lua_assert(buffonstack(B) ? lua_touserdata(B->L, idx) != NULL \
- : lua_touserdata(B->L, idx) == (void*)B)
-
-
-/*
-** Compute new size for buffer 'B', enough to accommodate extra 'sz'
-** bytes. (The test for "not big enough" also gets the case when the
-** computation of 'newsize' overflows.)
-*/
-static size_t newbuffsize (luaL_Buffer *B, size_t sz) {
- size_t newsize = (B->size / 2) * 3; /* buffer size * 1.5 */
- if (l_unlikely(MAX_SIZET - sz < B->n)) /* overflow in (B->n + sz)? */
- return luaL_error(B->L, "buffer too large");
- if (newsize < B->n + sz) /* not big enough? */
- newsize = B->n + sz;
- return newsize;
-}
-
-
-/*
-** Returns a pointer to a free area with at least 'sz' bytes in buffer
-** 'B'. 'boxidx' is the relative position in the stack where is the
-** buffer's box or its placeholder.
-*/
-static char *prepbuffsize (luaL_Buffer *B, size_t sz, int boxidx) {
- checkbufferlevel(B, boxidx);
- if (B->size - B->n >= sz) /* enough space? */
- return B->b + B->n;
- else {
- lua_State *L = B->L;
- char *newbuff;
- size_t newsize = newbuffsize(B, sz);
- /* create larger buffer */
- if (buffonstack(B)) /* buffer already has a box? */
- newbuff = (char *)resizebox(L, boxidx, newsize); /* resize it */
- else { /* no box yet */
- lua_remove(L, boxidx); /* remove placeholder */
- newbox(L); /* create a new box */
- lua_insert(L, boxidx); /* move box to its intended position */
- lua_toclose(L, boxidx);
- newbuff = (char *)resizebox(L, boxidx, newsize);
- memcpy(newbuff, B->b, B->n * sizeof(char)); /* copy original content */
- }
- B->b = newbuff;
- B->size = newsize;
- return newbuff + B->n;
- }
-}
-
-/*
-** returns a pointer to a free area with at least 'sz' bytes
-*/
-LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) {
- return prepbuffsize(B, sz, -1);
-}
-
-
-LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
- if (l > 0) { /* avoid 'memcpy' when 's' can be NULL */
- char *b = prepbuffsize(B, l, -1);
- memcpy(b, s, l * sizeof(char));
- luaL_addsize(B, l);
- }
-}
-
-
-LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
- luaL_addlstring(B, s, strlen(s));
-}
-
-
-LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
- lua_State *L = B->L;
- checkbufferlevel(B, -1);
- lua_pushlstring(L, B->b, B->n);
- if (buffonstack(B))
- lua_closeslot(L, -2); /* close the box */
- lua_remove(L, -2); /* remove box or placeholder from the stack */
-}
-
-
-LUALIB_API void luaL_pushresultsize (luaL_Buffer *B, size_t sz) {
- luaL_addsize(B, sz);
- luaL_pushresult(B);
-}
-
-
-/*
-** 'luaL_addvalue' is the only function in the Buffer system where the
-** box (if existent) is not on the top of the stack. So, instead of
-** calling 'luaL_addlstring', it replicates the code using -2 as the
-** last argument to 'prepbuffsize', signaling that the box is (or will
-** be) below the string being added to the buffer. (Box creation can
-** trigger an emergency GC, so we should not remove the string from the
-** stack before we have the space guaranteed.)
-*/
-LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
- lua_State *L = B->L;
- size_t len;
- const char *s = lua_tolstring(L, -1, &len);
- char *b = prepbuffsize(B, len, -2);
- memcpy(b, s, len * sizeof(char));
- luaL_addsize(B, len);
- lua_pop(L, 1); /* pop string */
-}
-
-
-LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
- B->L = L;
- B->b = B->init.b;
- B->n = 0;
- B->size = LUAL_BUFFERSIZE;
- lua_pushlightuserdata(L, (void*)B); /* push placeholder */
-}
-
-
-LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) {
- luaL_buffinit(L, B);
- return prepbuffsize(B, sz, -1);
-}
-
-/* }====================================================== */
-
-
-/*
-** {======================================================
-** Reference system
-** =======================================================
-*/
-
-/* index of free-list header (after the predefined values) */
-#define freelist (LUA_RIDX_LAST + 1)
-
-/*
-** The previously freed references form a linked list:
-** t[freelist] is the index of a first free index, or zero if list is
-** empty; t[t[freelist]] is the index of the second element; etc.
-*/
-LUALIB_API int luaL_ref (lua_State *L, int t) {
- int ref;
- if (lua_isnil(L, -1)) {
- lua_pop(L, 1); /* remove from stack */
- return LUA_REFNIL; /* 'nil' has a unique fixed reference */
- }
- t = lua_absindex(L, t);
- if (lua_rawgeti(L, t, freelist) == LUA_TNIL) { /* first access? */
- ref = 0; /* list is empty */
- lua_pushinteger(L, 0); /* initialize as an empty list */
- lua_rawseti(L, t, freelist); /* ref = t[freelist] = 0 */
- }
- else { /* already initialized */
- lua_assert(lua_isinteger(L, -1));
- ref = (int)lua_tointeger(L, -1); /* ref = t[freelist] */
- }
- lua_pop(L, 1); /* remove element from stack */
- if (ref != 0) { /* any free element? */
- lua_rawgeti(L, t, ref); /* remove it from list */
- lua_rawseti(L, t, freelist); /* (t[freelist] = t[ref]) */
- }
- else /* no free elements */
- ref = (int)lua_rawlen(L, t) + 1; /* get a new reference */
- lua_rawseti(L, t, ref);
- return ref;
-}
-
-
-LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
- if (ref >= 0) {
- t = lua_absindex(L, t);
- lua_rawgeti(L, t, freelist);
- lua_assert(lua_isinteger(L, -1));
- lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */
- lua_pushinteger(L, ref);
- lua_rawseti(L, t, freelist); /* t[freelist] = ref */
- }
-}
-
-/* }====================================================== */
-
-
-/*
-** {======================================================
-** Load functions
-** =======================================================
-*/
-
-typedef struct LoadF {
- int n; /* number of pre-read characters */
- FILE *f; /* file being read */
- char buff[BUFSIZ]; /* area for reading file */
-} LoadF;
-
-
-static const char *getF (lua_State *L, void *ud, size_t *size)
-{
- LoadF *lf = (LoadF *)ud;
- UFSFILE *ufp = get_ufsfile(lf->f);
-
- (void)L; /* not used */
-
- // wtof("lauxlib.c:%s: enter ufp=%p", __func__, ufp);
-
- if (lf->n > 0) { /* are there pre-read characters to be read? */
- *size = lf->n; /* return them (chars already in buffer) */
- lf->n = 0; /* no more pre-read characters */
- }
- else { /* read a block from file */
- /* 'fread' can return > 0 *and* set the EOF flag. If next call to
- 'getF' called 'fread', it might still wait for user input.
- The next check avoids this problem. */
- if (ufp) {
- if (ufs_feof(ufp)) return NULL;
- *size = ufs_fread(lf->buff, 1, sizeof(lf->buff), ufp); /* read block */
- // wtof("lauxlib.c:%s: ufs_fread() size=%d", __func__, *size);
- }
- else {
- if (feof(lf->f)) return NULL;
- *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); /* read block */
- // wtof("lauxlib.c:%s: fread() size=%d", __func__, *size);
- }
- }
-
- // wtodumpf(lf->buff, *size, "%s: lf->buff", __func__);
- // wtof("lauxlib.c:%s: exit", __func__);
- return lf->buff;
-}
-
-
-static int errfile (lua_State *L, const char *what, int fnameindex) {
- const char *serr = strerror(errno);
- const char *filename = lua_tostring(L, fnameindex) + 1;
- lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
- lua_remove(L, fnameindex);
- return LUA_ERRFILE;
-}
-
-
-/*
-** Skip an optional BOM at the start of a stream. If there is an
-** incomplete BOM (the first character is correct but the rest is
-** not), returns the first character anyway to force an error
-** (as no chunk can start with 0xEF).
-*/
-static int skipBOM (FILE *f)
-{
- UFSFILE *ufp = get_ufsfile(f);
- int c;
-
- if (ufp) {
- c = ufs_fgetc(ufp);
- if (c == 0xEF && ufs_fgetc(ufp) == 0xBB && ufs_fgetc(ufp) == 0xBF) /* correct BOM? */
- return ufs_fgetc(ufp); /* ignore BOM and return next char */
- else /* no (valid) BOM */
- return c; /* return first character */
- }
- else {
- c = getc(f); /* read first character */
- if (c == 0xEF && getc(f) == 0xBB && getc(f) == 0xBF) /* correct BOM? */
- return getc(f); /* ignore BOM and return next char */
- else /* no (valid) BOM */
- return c; /* return first character */
- }
-}
-
-
-/*
-** reads the first character of file 'f' and skips an optional BOM mark
-** in its beginning plus its first line if it starts with '#'. Returns
-** true if it skipped the first line. In any case, '*cp' has the
-** first "valid" character of the file (after the optional BOM and
-** a first-line comment).
-*/
-static int skipcomment (FILE *f, int *cp)
-{
- UFSFILE *ufp = get_ufsfile(f);
- int c = *cp = skipBOM(f);
-
- if (c == '#') { /* first line is a comment (Unix exec. file)? */
- if (ufp) {
- do { /* skip first line */
- c = ufs_fgetc(ufp);
- } while (c != EOF && c != '\n');
- *cp = ufs_fgetc(ufp); /* next character after comment, if present */
- return 1; /* there was a comment */
- }
- else {
- do { /* skip first line */
- c = getc(f);
- } while (c != EOF && c != '\n');
- *cp = getc(f); /* next character after comment, if present */
- return 1; /* there was a comment */
- }
- }
-
- return 0; /* no comment */
-}
-
-
-LUALIB_API int
-luaL_loadfilex (lua_State *L, const char *filename, const char *mode)
-{
- CLIBCRT *crt = __crtget();
- UFS *ufs = crt ? crt->crtufs : NULL;
- UFSFILE *ufp = NULL;
- LoadF lf = {0};
- int status, readstatus;
- int c;
- int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
-
- // wtof("lauxlib.c:%s: enter filename=\"%s\"", __func__, filename);
- // wtof("lauxlib.c:%s: crt=%p", __func__, crt);
-
- if (filename == NULL) {
- lua_pushliteral(L, "=stdin");
- lf.f = stdin;
- }
- else {
- lua_pushfstring(L, "@%s", filename);
-
- if (ufs && is_pathname(filename)) {
- ufp = ufs_fopen(ufs, filename, "r");
- // wtof("lauxlib.c:%s: ufs_fopen() ufp=%p", __func__, ufp);
- if (ufp) lf.f = (void*)((unsigned)ufp | 0x80000000);
- }
- if (!lf.f) {
- lf.f = fopen(filename, "r");
- // wtof("lauxlib.c:%s: fopen() lf.f=%p", __func__, lf.f);
- }
- if (lf.f == NULL) return errfile(L, "open", fnameindex);
- }
-
- lf.n = 0;
- if (skipcomment(lf.f, &c)) /* read initial portion */
- lf.buff[lf.n++] = '\n'; /* add newline to correct line numbers */
-
- if (c == LUA_SIGNATURE[0]) { /* binary file? */
- lf.n = 0; /* remove possible newline */
- if (filename) { /* "real" file? */
- ufp = get_ufsfile(lf.f);
-
- if (ufp) {
- ufs_fclose(&ufp);
- lf.f = NULL;
- ufp = ufs_fopen(ufs, filename, "rb");
- // wtof("lauxlib.c:%s: ufs_fopen() ufp=%p", __func__, ufp);
- if (ufp) lf.f = (void*)((unsigned)ufp | 0x80000000);
- }
- else {
- lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
- // wtof("lauxlib.c:%s: freopen() lf.f=%p", __func__, lf.f);
- }
- if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
- skipcomment(lf.f, &c); /* re-read initial portion */
- }
- }
-
- if (c != EOF)
- lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */
-
- status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode);
- // wtof("lauxlib.c:%s: lua_load() status=%d", __func__, status);
-
- if (ufp) {
- readstatus = ufs_ferror(ufp);
- // wtof("lauxlib.c:%s: ufs_ferror() readstatus=%d", __func__, readstatus);
- }
- else {
- readstatus = ferror(lf.f);
- // wtof("lauxlib.c:%s: ferror() readstatus=%d", __func__, readstatus);
- }
-
- if (filename) {
- if (ufp) {
- ufs_fclose(&ufp);
- // wtof("lauxlib.c:%s: ufs_fclose()", __func__);
- }
- else {
- fclose(lf.f); /* close file (even in case of errors) */
- // wtof("lauxlib.c:%s: fclose()", __func__);
- }
- }
-
- if (readstatus) {
- lua_settop(L, fnameindex); /* ignore results from 'lua_load' */
- return errfile(L, "read", fnameindex);
- }
-
- lua_remove(L, fnameindex);
- return status;
-}
-
-
-typedef struct LoadS {
- const char *s;
- size_t size;
-} LoadS;
-
-
-static const char *getS (lua_State *L, void *ud, size_t *size) {
- LoadS *ls = (LoadS *)ud;
- (void)L; /* not used */
- if (ls->size == 0) return NULL;
- *size = ls->size;
- ls->size = 0;
- return ls->s;
-}
-
-
-LUALIB_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t size,
- const char *name, const char *mode) {
- LoadS ls;
- ls.s = buff;
- ls.size = size;
- return lua_load(L, getS, &ls, name, mode);
-}
-
-
-LUALIB_API int luaL_loadstring (lua_State *L, const char *s) {
- return luaL_loadbuffer(L, s, strlen(s), s);
-}
-
-/* }====================================================== */
-
-
-
-LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
- if (!lua_getmetatable(L, obj)) /* no metatable? */
- return LUA_TNIL;
- else {
- int tt;
- lua_pushstring(L, event);
- tt = lua_rawget(L, -2);
- if (tt == LUA_TNIL) /* is metafield nil? */
- lua_pop(L, 2); /* remove metatable and metafield */
- else
- lua_remove(L, -2); /* remove only metatable */
- return tt; /* return metafield type */
- }
-}
-
-
-LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
- obj = lua_absindex(L, obj);
- if (luaL_getmetafield(L, obj, event) == LUA_TNIL) /* no metafield? */
- return 0;
- lua_pushvalue(L, obj);
- lua_call(L, 1, 1);
- return 1;
-}
-
-
-LUALIB_API lua_Integer luaL_len (lua_State *L, int idx) {
- lua_Integer l;
- int isnum;
- lua_len(L, idx);
- l = lua_tointegerx(L, -1, &isnum);
- if (l_unlikely(!isnum))
- luaL_error(L, "object length is not an integer");
- lua_pop(L, 1); /* remove object */
- return l;
-}
-
-
-LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
- idx = lua_absindex(L,idx);
- if (luaL_callmeta(L, idx, "__tostring")) { /* metafield? */
- if (!lua_isstring(L, -1))
- luaL_error(L, "'__tostring' must return a string");
- }
- else {
- switch (lua_type(L, idx)) {
- case LUA_TNUMBER: {
- if (lua_isinteger(L, idx))
- lua_pushfstring(L, "%I", (LUAI_UACINT)lua_tointeger(L, idx));
- else
- lua_pushfstring(L, "%f", (LUAI_UACNUMBER)lua_tonumber(L, idx));
- break;
- }
- case LUA_TSTRING:
- lua_pushvalue(L, idx);
- break;
- case LUA_TBOOLEAN:
- lua_pushstring(L, (lua_toboolean(L, idx) ? "true" : "false"));
- break;
- case LUA_TNIL:
- lua_pushliteral(L, "nil");
- break;
- default: {
- int tt = luaL_getmetafield(L, idx, "__name"); /* try name */
- const char *kind = (tt == LUA_TSTRING) ? lua_tostring(L, -1) :
- luaL_typename(L, idx);
- lua_pushfstring(L, "%s: %p", kind, lua_topointer(L, idx));
- if (tt != LUA_TNIL)
- lua_remove(L, -2); /* remove '__name' */
- break;
- }
- }
- }
- return lua_tolstring(L, -1, len);
-}
-
-
-/*
-** set functions from list 'l' into table at top - 'nup'; each
-** function gets the 'nup' elements at the top as upvalues.
-** Returns with only the table at the stack.
-*/
-LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
- luaL_checkstack(L, nup, "too many upvalues");
- for (; l->name != NULL; l++) { /* fill the table with given functions */
- if (l->func == NULL) /* place holder? */
- lua_pushboolean(L, 0);
- else {
- int i;
- for (i = 0; i < nup; i++) /* copy upvalues to the top */
- lua_pushvalue(L, -nup);
- lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */
- }
- lua_setfield(L, -(nup + 2), l->name);
- }
- lua_pop(L, nup); /* remove upvalues */
-}
-
-
-/*
-** ensure that stack[idx][fname] has a table and push that table
-** into the stack
-*/
-LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) {
- if (lua_getfield(L, idx, fname) == LUA_TTABLE)
- return 1; /* table already there */
- else {
- lua_pop(L, 1); /* remove previous result */
- idx = lua_absindex(L, idx);
- lua_newtable(L);
- lua_pushvalue(L, -1); /* copy to be left at top */
- lua_setfield(L, idx, fname); /* assign new table to field */
- return 0; /* false, because did not find table there */
- }
-}
-
-
-/*
-** Stripped-down 'require': After checking "loaded" table, calls 'openf'
-** to open a module, registers the result in 'package.loaded' table and,
-** if 'glb' is true, also registers the result in the global table.
-** Leaves resulting module on the top.
-*/
-LUALIB_API void luaL_requiref (lua_State *L, const char *modname,
- lua_CFunction openf, int glb) {
- luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
- lua_getfield(L, -1, modname); /* LOADED[modname] */
- if (!lua_toboolean(L, -1)) { /* package not already loaded? */
- lua_pop(L, 1); /* remove field */
- lua_pushcfunction(L, openf);
- lua_pushstring(L, modname); /* argument to open function */
- lua_call(L, 1, 1); /* call 'openf' to open module */
- lua_pushvalue(L, -1); /* make copy of module (call result) */
- lua_setfield(L, -3, modname); /* LOADED[modname] = module */
- }
- lua_remove(L, -2); /* remove LOADED table */
- if (glb) {
- lua_pushvalue(L, -1); /* copy of module */
- lua_setglobal(L, modname); /* _G[modname] = module */
- }
-}
-
-
-LUALIB_API void luaL_addgsub (luaL_Buffer *b, const char *s,
- const char *p, const char *r) {
- const char *wild;
- size_t l = strlen(p);
- while ((wild = strstr(s, p)) != NULL) {
- luaL_addlstring(b, s, wild - s); /* push prefix */
- luaL_addstring(b, r); /* push replacement in place of pattern */
- s = wild + l; /* continue after 'p' */
- }
- luaL_addstring(b, s); /* push last suffix */
-}
-
-
-LUALIB_API const char *luaL_gsub (lua_State *L, const char *s,
- const char *p, const char *r) {
- luaL_Buffer b;
- luaL_buffinit(L, &b);
- luaL_addgsub(&b, s, p, r);
- luaL_pushresult(&b);
- return lua_tostring(L, -1);
-}
-
-
-static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
- (void)ud; (void)osize; /* not used */
- if (nsize == 0) {
- free(ptr);
- return NULL;
- }
- else
- return realloc(ptr, nsize);
-}
-
-
-static int panic (lua_State *L) {
- const char *msg = lua_tostring(L, -1);
- if (msg == NULL) msg = "error object is not a string";
- lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n",
- msg);
- return 0; /* return to Lua to abort */
-}
-
-
-/*
-** Warning functions:
-** warnfoff: warning system is off
-** warnfon: ready to start a new message
-** warnfcont: previous message is to be continued
-*/
-static void warnfoff (void *ud, const char *message, int tocont);
-static void warnfon (void *ud, const char *message, int tocont);
-static void warnfcont (void *ud, const char *message, int tocont);
-
-
-/*
-** Check whether message is a control message. If so, execute the
-** control or ignore it if unknown.
-*/
-static int checkcontrol (lua_State *L, const char *message, int tocont) {
- if (tocont || *(message++) != '@') /* not a control message? */
- return 0;
- else {
- if (strcmp(message, "off") == 0)
- lua_setwarnf(L, warnfoff, L); /* turn warnings off */
- else if (strcmp(message, "on") == 0)
- lua_setwarnf(L, warnfon, L); /* turn warnings on */
- return 1; /* it was a control message */
- }
-}
-
-
-static void warnfoff (void *ud, const char *message, int tocont) {
- checkcontrol((lua_State *)ud, message, tocont);
-}
-
-
-/*
-** Writes the message and handle 'tocont', finishing the message
-** if needed and setting the next warn function.
-*/
-static void warnfcont (void *ud, const char *message, int tocont) {
- lua_State *L = (lua_State *)ud;
- lua_writestringerror("%s", message); /* write message */
- if (tocont) /* not the last part? */
- lua_setwarnf(L, warnfcont, L); /* to be continued */
- else { /* last part */
- lua_writestringerror("%s", "\n"); /* finish message with end-of-line */
- lua_setwarnf(L, warnfon, L); /* next call is a new message */
- }
-}
-
-
-static void warnfon (void *ud, const char *message, int tocont) {
- if (checkcontrol((lua_State *)ud, message, tocont)) /* control message? */
- return; /* nothing else to be done */
- lua_writestringerror("%s", "Lua warning: "); /* start a new warning */
- warnfcont(ud, message, tocont); /* finish processing */
-}
-
-
-LUALIB_API lua_State *luaL_newstate (void) {
- lua_State *L = lua_newstate(l_alloc, NULL);
- if (l_likely(L)) {
- lua_atpanic(L, &panic);
- lua_setwarnf(L, warnfoff, L); /* default is warnings off */
- }
- return L;
-}
-
-
-LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver, size_t sz) {
- lua_Number v = lua_version(L);
- if (sz != LUAL_NUMSIZES) /* check numeric types */
- luaL_error(L, "core and library have incompatible numeric types");
- else if (v != ver)
- luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f",
- (LUAI_UACNUMBER)ver, (LUAI_UACNUMBER)v);
-}
-
diff --git a/src/liolib.c b/src/liolib.c
deleted file mode 100644
index 02fc0c8..0000000
--- a/src/liolib.c
+++ /dev/null
@@ -1,979 +0,0 @@
-/*
-** $Id: liolib.c $
-** Standard I/O (and system) library
-** See Copyright Notice in lua.h
-*/
-
-/* This is a copy of lauxlib.c from LUA370 with modifications
- * to support UFS in the HTTPD environment.
- */
-
-#define liolib_c
-#define LUA_LIB
-
-#include "lprefix.h"
-
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "lua.h"
-
-#include "lauxlib.h"
-#include "lualib.h"
-
-#define HTTPLUAX_PRIVATE /* suppress defines for Lua functions */
-//#define luai_likely(x) (x)
-//#define luai_unlikely(x) (x)
-#include "httpd.h"
-
-static UFSFILE *get_ufsfile(FILE *fp)
-{
- unsigned x = (unsigned)fp;
- UFSFILE *f = NULL;
-
- if (x & 0x80000000) {
- f = (UFSFILE *) (x & 0x7FFFFFFF);
- }
-
- return f;
-}
-
-
-
-
-/*
-** Change this macro to accept other modes for 'fopen' besides
-** the standard ones.
-*/
-#if !defined(l_checkmode)
-
-/* accepted extensions to 'mode' in 'fopen' */
-#if !defined(L_MODEEXT)
-#define L_MODEEXT "b"
-#endif
-
-/* Check whether 'mode' matches '[rwa]%+?[L_MODEEXT]*' */
-static int l_checkmode (const char *mode) {
- return (*mode != '\0' && strchr("rwa", *(mode++)) != NULL &&
- (*mode != '+' || ((void)(++mode), 1)) && /* skip if char is '+' */
- (strspn(mode, L_MODEEXT) == strlen(mode))); /* check extensions */
-}
-
-#endif
-
-/*
-** {======================================================
-** l_popen spawns a new process connected to the current
-** one through the file streams.
-** =======================================================
-*/
-
-#if !defined(l_popen) /* { */
-
-#if defined(LUA_USE_POSIX) /* { */
-
-#define l_popen(L,c,m) (fflush(NULL), popen(c,m))
-#define l_pclose(L,file) (pclose(file))
-
-#elif defined(LUA_USE_WINDOWS) /* }{ */
-
-#define l_popen(L,c,m) (_popen(c,m))
-#define l_pclose(L,file) (_pclose(file))
-
-#if !defined(l_checkmodep)
-/* Windows accepts "[rw][bt]?" as valid modes */
-#define l_checkmodep(m) ((m[0] == 'r' || m[0] == 'w') && \
- (m[1] == '\0' || ((m[1] == 'b' || m[1] == 't') && m[2] == '\0')))
-#endif
-
-#else /* }{ */
-
-/* ISO C definitions */
-#define l_popen(L,c,m) \
- ((void)c, (void)m, \
- luaL_error(L, "'popen' not supported"), \
- (FILE*)0)
-#define l_pclose(L,file) ((void)L, (void)file, -1)
-
-#endif /* } */
-
-#endif /* } */
-
-
-#if !defined(l_checkmodep)
-/* By default, Lua accepts only "r" or "w" as valid modes */
-#define l_checkmodep(m) ((m[0] == 'r' || m[0] == 'w') && m[1] == '\0')
-#endif
-
-/* }====================================================== */
-
-
-#if !defined(l_getc) /* { */
-
-#if defined(LUA_USE_POSIX)
-#define l_getc(f) getc_unlocked(f)
-#define l_lockfile(f) flockfile(f)
-#define l_unlockfile(f) funlockfile(f)
-#else
-#define l_getc(f) getc(f)
-#define l_lockfile(f) ((void)0)
-#define l_unlockfile(f) ((void)0)
-#endif
-
-#endif /* } */
-
-
-/*
-** {======================================================
-** l_fseek: configuration for longer offsets
-** =======================================================
-*/
-
-#if !defined(l_fseek) /* { */
-
-#if defined(LUA_USE_POSIX) /* { */
-
-#include
-
-#define l_fseek(f,o,w) fseeko(f,o,w)
-#define l_ftell(f) ftello(f)
-#define l_seeknum off_t
-
-#elif defined(LUA_USE_WINDOWS) && !defined(_CRTIMP_TYPEINFO) \
- && defined(_MSC_VER) && (_MSC_VER >= 1400) /* }{ */
-
-/* Windows (but not DDK) and Visual C++ 2005 or higher */
-#define l_fseek(f,o,w) _fseeki64(f,o,w)
-#define l_ftell(f) _ftelli64(f)
-#define l_seeknum __int64
-
-#else /* }{ */
-
-/* ISO C definitions */
-#define l_fseek(f,o,w) fseek(f,o,w)
-#define l_ftell(f) ftell(f)
-#define l_seeknum long
-
-#endif /* } */
-
-#endif /* } */
-
-/* }====================================================== */
-
-
-
-#define IO_PREFIX "_IO_"
-#define IOPREF_LEN (sizeof(IO_PREFIX)/sizeof(char) - 1)
-#define IO_INPUT (IO_PREFIX "input")
-#define IO_OUTPUT (IO_PREFIX "output")
-
-
-typedef luaL_Stream LStream;
-
-
-#define tolstream(L) ((LStream *)luaL_checkudata(L, 1, LUA_FILEHANDLE))
-
-#define isclosed(p) ((p)->closef == NULL)
-
-
-static int io_type (lua_State *L) {
- LStream *p;
- luaL_checkany(L, 1);
- p = (LStream *)luaL_testudata(L, 1, LUA_FILEHANDLE);
- if (p == NULL)
- luaL_pushfail(L); /* not a file */
- else if (isclosed(p))
- lua_pushliteral(L, "closed file");
- else
- lua_pushliteral(L, "file");
- return 1;
-}
-
-
-static int f_tostring (lua_State *L) {
- LStream *p = tolstream(L);
- if (isclosed(p))
- lua_pushliteral(L, "file (closed)");
- else
- lua_pushfstring(L, "file (%p)", p->f);
- return 1;
-}
-
-
-static FILE *tofile (lua_State *L) {
- LStream *p = tolstream(L);
- if (l_unlikely(isclosed(p)))
- luaL_error(L, "attempt to use a closed file");
- lua_assert(p->f);
- return p->f;
-}
-
-
-/*
-** When creating file handles, always creates a 'closed' file handle
-** before opening the actual file; so, if there is a memory error, the
-** handle is in a consistent state.
-*/
-static LStream *newprefile (lua_State *L) {
- LStream *p = (LStream *)lua_newuserdatauv(L, sizeof(LStream), 0);
- p->closef = NULL; /* mark file handle as 'closed' */
- luaL_setmetatable(L, LUA_FILEHANDLE);
- return p;
-}
-
-
-/*
-** Calls the 'close' function from a file handle. The 'volatile' avoids
-** a bug in some versions of the Clang compiler (e.g., clang 3.0 for
-** 32 bits).
-*/
-static int aux_close (lua_State *L) {
- LStream *p = tolstream(L);
- volatile lua_CFunction cf = p->closef;
- p->closef = NULL; /* mark stream as closed */
- return (*cf)(L); /* close it */
-}
-
-
-static int f_close (lua_State *L) {
- tofile(L); /* make sure argument is an open stream */
- return aux_close(L);
-}
-
-
-static int io_close (lua_State *L) {
- if (lua_isnone(L, 1)) /* no argument? */
- lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use default output */
- return f_close(L);
-}
-
-
-static int f_gc (lua_State *L) {
- LStream *p = tolstream(L);
- if (!isclosed(p) && p->f != NULL)
- aux_close(L); /* ignore closed and incompletely open files */
- return 0;
-}
-
-
-/*
-** function to close regular files
-*/
-static int io_fclose (lua_State *L)
-{
- LStream *p = tolstream(L);
- UFSFILE *ufp = get_ufsfile(p->f);
- int res = 0;
-
- if (ufp) {
- ufs_fclose(&ufp);
- }
- else {
- res = fclose(p->f);
- }
-
- return luaL_fileresult(L, (res == 0), NULL);
-}
-
-
-static LStream *newfile (lua_State *L)
-{
- LStream *p = newprefile(L);
-
- p->f = NULL;
- p->closef = &io_fclose;
-
- return p;
-}
-
-
-static void opencheck (lua_State *L, const char *fname, const char *mode)
-{
- CLIBCRT *crt = __crtget();
- UFS *ufs = crt ? crt->crtufs : NULL;
- UFSFILE *ufp = NULL;
- LStream *p = newfile(L);
-
- p->f = NULL;
-
- if (ufs) {
- ufp = ufs_fopen(ufs, fname, mode);
- if (ufp) p->f = (void*)((unsigned)ufp & 0x80000000);
- }
-
- if (!p->f) {
- p->f = fopen(fname, mode);
- }
-
- if (l_unlikely(p->f == NULL))
- luaL_error(L, "cannot open file '%s' (%s)", fname, strerror(errno));
-}
-
-
-static int io_open (lua_State *L)
-{
- CLIBCRT *crt = __crtget();
- UFS *ufs = crt ? crt->crtufs : NULL;
- UFSFILE *ufp = NULL;
- const char *filename = luaL_checkstring(L, 1);
- const char *mode = luaL_optstring(L, 2, "r");
- LStream *p = newfile(L);
- const char *md = mode; /* to traverse/check mode */
-
- luaL_argcheck(L, l_checkmode(md), 2, "invalid mode");
-
- p->f = NULL;
-
- if (ufs) {
- ufp = ufs_fopen(ufs, filename, mode);
- if (ufp) p->f = (void*)((unsigned)ufp & 0x80000000);
- }
-
- if (!p->f) {
- p->f = fopen(filename, mode);
- }
-
- return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
-}
-
-
-/*
-** function to close 'popen' files
-*/
-static int io_pclose (lua_State *L) {
- LStream *p = tolstream(L);
- errno = 0;
- return luaL_execresult(L, l_pclose(L, p->f));
-}
-
-
-static int io_popen (lua_State *L) {
- const char *filename = luaL_checkstring(L, 1);
- const char *mode = luaL_optstring(L, 2, "r");
- LStream *p = newprefile(L);
- luaL_argcheck(L, l_checkmodep(mode), 2, "invalid mode");
- p->f = l_popen(L, filename, mode);
- p->closef = &io_pclose;
- return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
-}
-
-
-static int io_tmpfile (lua_State *L)
-{
- LStream *p = newfile(L);
-
- p->f = tmpfile();
- return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1;
-}
-
-
-static FILE *getiofile (lua_State *L, const char *findex)
-{
- LStream *p;
-
- lua_getfield(L, LUA_REGISTRYINDEX, findex);
- p = (LStream *)lua_touserdata(L, -1);
-
- if (l_unlikely(isclosed(p)))
- luaL_error(L, "default %s file is closed", findex + IOPREF_LEN);
-
- return p->f;
-}
-
-
-static int g_iofile (lua_State *L, const char *f, const char *mode) {
- if (!lua_isnoneornil(L, 1)) {
- const char *filename = lua_tostring(L, 1);
- if (filename)
- opencheck(L, filename, mode);
- else {
- tofile(L); /* check that it's a valid file handle */
- lua_pushvalue(L, 1);
- }
- lua_setfield(L, LUA_REGISTRYINDEX, f);
- }
- /* return current value */
- lua_getfield(L, LUA_REGISTRYINDEX, f);
- return 1;
-}
-
-
-static int io_input (lua_State *L) {
- return g_iofile(L, IO_INPUT, "r");
-}
-
-
-static int io_output (lua_State *L) {
- return g_iofile(L, IO_OUTPUT, "w");
-}
-
-
-static int io_readline (lua_State *L);
-
-
-/*
-** maximum number of arguments to 'f:lines'/'io.lines' (it + 3 must fit
-** in the limit for upvalues of a closure)
-*/
-#define MAXARGLINE 250
-
-/*
-** Auxiliary function to create the iteration function for 'lines'.
-** The iteration function is a closure over 'io_readline', with
-** the following upvalues:
-** 1) The file being read (first value in the stack)
-** 2) the number of arguments to read
-** 3) a boolean, true iff file has to be closed when finished ('toclose')
-** *) a variable number of format arguments (rest of the stack)
-*/
-static void aux_lines (lua_State *L, int toclose) {
- int n = lua_gettop(L) - 1; /* number of arguments to read */
- luaL_argcheck(L, n <= MAXARGLINE, MAXARGLINE + 2, "too many arguments");
- lua_pushvalue(L, 1); /* file */
- lua_pushinteger(L, n); /* number of arguments to read */
- lua_pushboolean(L, toclose); /* close/not close file when finished */
- lua_rotate(L, 2, 3); /* move the three values to their positions */
- lua_pushcclosure(L, io_readline, 3 + n);
-}
-
-
-static int f_lines (lua_State *L) {
- tofile(L); /* check that it's a valid file handle */
- aux_lines(L, 0);
- return 1;
-}
-
-
-/*
-** Return an iteration function for 'io.lines'. If file has to be
-** closed, also returns the file itself as a second result (to be
-** closed as the state at the exit of a generic for).
-*/
-static int io_lines (lua_State *L) {
- int toclose;
- if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */
- if (lua_isnil(L, 1)) { /* no file name? */
- lua_getfield(L, LUA_REGISTRYINDEX, IO_INPUT); /* get default input */
- lua_replace(L, 1); /* put it at index 1 */
- tofile(L); /* check that it's a valid file handle */
- toclose = 0; /* do not close it after iteration */
- }
- else { /* open a new file */
- const char *filename = luaL_checkstring(L, 1);
- opencheck(L, filename, "r");
- lua_replace(L, 1); /* put file at index 1 */
- toclose = 1; /* close it after iteration */
- }
- aux_lines(L, toclose); /* push iteration function */
- if (toclose) {
- lua_pushnil(L); /* state */
- lua_pushnil(L); /* control */
- lua_pushvalue(L, 1); /* file is the to-be-closed variable (4th result) */
- return 4;
- }
- else
- return 1;
-}
-
-
-/*
-** {======================================================
-** READ
-** =======================================================
-*/
-
-
-/* maximum length of a numeral */
-#if !defined (L_MAXLENNUM)
-#define L_MAXLENNUM 200
-#endif
-
-
-/* auxiliary structure used by 'read_number' */
-typedef struct {
- FILE *f; /* file being read */
- int c; /* current character (look ahead) */
- int n; /* number of elements in buffer 'buff' */
- char buff[L_MAXLENNUM + 1]; /* +1 for ending '\0' */
-} RN;
-
-
-/*
-** Add current char to buffer (if not out of space) and read next one
-*/
-static int nextc (RN *rn) {
- if (l_unlikely(rn->n >= L_MAXLENNUM)) { /* buffer overflow? */
- rn->buff[0] = '\0'; /* invalidate result */
- return 0; /* fail */
- }
- else {
- rn->buff[rn->n++] = rn->c; /* save current char */
- rn->c = l_getc(rn->f); /* read next one */
- return 1;
- }
-}
-
-
-/*
-** Accept current char if it is in 'set' (of size 2)
-*/
-static int test2 (RN *rn, const char *set) {
- if (rn->c == set[0] || rn->c == set[1])
- return nextc(rn);
- else return 0;
-}
-
-
-/*
-** Read a sequence of (hex)digits
-*/
-static int readdigits (RN *rn, int hex) {
- int count = 0;
- while ((hex ? isxdigit(rn->c) : isdigit(rn->c)) && nextc(rn))
- count++;
- return count;
-}
-
-
-/*
-** Read a number: first reads a valid prefix of a numeral into a buffer.
-** Then it calls 'lua_stringtonumber' to check whether the format is
-** correct and to convert it to a Lua number.
-*/
-static int read_number (lua_State *L, FILE *f) {
- RN rn;
- int count = 0;
- int hex = 0;
- char decp[2];
- rn.f = f; rn.n = 0;
- decp[0] = lua_getlocaledecpoint(); /* get decimal point from locale */
- decp[1] = '.'; /* always accept a dot */
- l_lockfile(rn.f);
- do { rn.c = l_getc(rn.f); } while (isspace(rn.c)); /* skip spaces */
- test2(&rn, "-+"); /* optional sign */
- if (test2(&rn, "00")) {
- if (test2(&rn, "xX")) hex = 1; /* numeral is hexadecimal */
- else count = 1; /* count initial '0' as a valid digit */
- }
- count += readdigits(&rn, hex); /* integral part */
- if (test2(&rn, decp)) /* decimal point? */
- count += readdigits(&rn, hex); /* fractional part */
- if (count > 0 && test2(&rn, (hex ? "pP" : "eE"))) { /* exponent mark? */
- test2(&rn, "-+"); /* exponent sign */
- readdigits(&rn, 0); /* exponent digits */
- }
- ungetc(rn.c, rn.f); /* unread look-ahead char */
- l_unlockfile(rn.f);
- rn.buff[rn.n] = '\0'; /* finish string */
- if (l_likely(lua_stringtonumber(L, rn.buff)))
- return 1; /* ok, it is a valid number */
- else { /* invalid format */
- lua_pushnil(L); /* "result" to be removed */
- return 0; /* read fails */
- }
-}
-
-
-static int test_eof (lua_State *L, FILE *f)
-{
- UFSFILE *ufp = get_ufsfile(f);
- int c;
-
- if (ufp) {
- c = ufs_feof(ufp) ? EOF : 0;
- }
- else {
- c = getc(f);
- ungetc(c, f); /* no-op when c == EOF */
- }
-
- lua_pushliteral(L, "");
- return (c != EOF);
-}
-
-
-static int read_line (lua_State *L, FILE *f, int chop) {
- luaL_Buffer b;
- int c;
- luaL_buffinit(L, &b);
- do { /* may need to read several chunks to get whole line */
- char *buff = luaL_prepbuffer(&b); /* preallocate buffer space */
- int i = 0;
- l_lockfile(f); /* no memory errors can happen inside the lock */
- while (i < LUAL_BUFFERSIZE && (c = l_getc(f)) != EOF && c != '\n')
- buff[i++] = c; /* read up to end of line or buffer limit */
- l_unlockfile(f);
- luaL_addsize(&b, i);
- } while (c != EOF && c != '\n'); /* repeat until end of line */
- if (!chop && c == '\n') /* want a newline and have one? */
- luaL_addchar(&b, c); /* add ending newline to result */
- luaL_pushresult(&b); /* close buffer */
- /* return ok if read something (either a newline or something else) */
- return (c == '\n' || lua_rawlen(L, -1) > 0);
-}
-
-
-static void read_all (lua_State *L, FILE *f)
-{
- UFSFILE *ufp = get_ufsfile(f);
- size_t nr;
- luaL_Buffer b;
- luaL_buffinit(L, &b);
-
- do { /* read file in chunks of LUAL_BUFFERSIZE bytes */
- char *p = luaL_prepbuffer(&b);
- if (ufp) {
- nr = ufs_fread(p, sizeof(char), LUAL_BUFFERSIZE, ufp);
- }
- else {
- nr = fread(p, sizeof(char), LUAL_BUFFERSIZE, f);
- }
- luaL_addsize(&b, nr);
- } while (nr == LUAL_BUFFERSIZE);
-
- luaL_pushresult(&b); /* close buffer */
-}
-
-
-static int read_chars (lua_State *L, FILE *f, size_t n)
-{
- UFSFILE *ufp = get_ufsfile(f);
- size_t nr; /* number of chars actually read */
- char *p;
- luaL_Buffer b;
-
- luaL_buffinit(L, &b);
- p = luaL_prepbuffsize(&b, n); /* prepare buffer to read whole block */
- if (ufp) {
- nr = ufs_fread(p, sizeof(char), n, ufp); /* try to read 'n' chars */
- }
- else {
- nr = fread(p, sizeof(char), n, f); /* try to read 'n' chars */
- }
- luaL_addsize(&b, nr);
- luaL_pushresult(&b); /* close buffer */
- return (nr > 0); /* true iff read something */
-}
-
-
-static int g_read (lua_State *L, FILE *f, int first)
-{
- UFSFILE *ufp = get_ufsfile(f);
- int nargs = lua_gettop(L) - 1;
- int n, success;
-
- if (ufp) {
- ufs_clearerr(ufp);
- }
- else {
- clearerr(f);
- }
-
- if (nargs == 0) { /* no arguments? */
- success = read_line(L, f, 1);
- n = first + 1; /* to return 1 result */
- }
- else {
- /* ensure stack space for all results and for auxlib's buffer */
- luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
- success = 1;
- for (n = first; nargs-- && success; n++) {
- if (lua_type(L, n) == LUA_TNUMBER) {
- size_t l = (size_t)luaL_checkinteger(L, n);
- success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);
- }
- else {
- const char *p = luaL_checkstring(L, n);
- if (*p == '*') p++; /* skip optional '*' (for compatibility) */
- switch (*p) {
- case 'n': /* number */
- success = read_number(L, f);
- break;
- case 'l': /* line */
- success = read_line(L, f, 1);
- break;
- case 'L': /* line with end-of-line */
- success = read_line(L, f, 0);
- break;
- case 'a': /* file */
- read_all(L, f); /* read entire file */
- success = 1; /* always success */
- break;
- default:
- return luaL_argerror(L, n, "invalid format");
- }
- }
- }
- }
-
- if (ferror(f))
- return luaL_fileresult(L, 0, NULL);
-
- if (!success) {
- lua_pop(L, 1); /* remove last result */
- luaL_pushfail(L); /* push nil instead */
- }
-
- return n - first;
-}
-
-
-static int io_read (lua_State *L) {
- return g_read(L, getiofile(L, IO_INPUT), 1);
-}
-
-
-static int f_read (lua_State *L) {
- return g_read(L, tofile(L), 2);
-}
-
-
-/*
-** Iteration function for 'lines'.
-*/
-static int io_readline (lua_State *L) {
- LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1));
- int i;
- int n = (int)lua_tointeger(L, lua_upvalueindex(2));
- if (isclosed(p)) /* file is already closed? */
- return luaL_error(L, "file is already closed");
- lua_settop(L , 1);
- luaL_checkstack(L, n, "too many arguments");
- for (i = 1; i <= n; i++) /* push arguments to 'g_read' */
- lua_pushvalue(L, lua_upvalueindex(3 + i));
- n = g_read(L, p->f, 2); /* 'n' is number of results */
- lua_assert(n > 0); /* should return at least a nil */
- if (lua_toboolean(L, -n)) /* read at least one value? */
- return n; /* return them */
- else { /* first result is false: EOF or error */
- if (n > 1) { /* is there error information? */
- /* 2nd result is error message */
- return luaL_error(L, "%s", lua_tostring(L, -n + 1));
- }
- if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */
- lua_settop(L, 0); /* clear stack */
- lua_pushvalue(L, lua_upvalueindex(1)); /* push file at index 1 */
- aux_close(L); /* close it */
- }
- return 0;
- }
-}
-
-/* }====================================================== */
-
-
-static int g_write (lua_State *L, FILE *f, int arg)
-{
- UFSFILE *ufp = get_ufsfile(f);
- int nargs = lua_gettop(L) - arg;
- int status = 1;
- int len;
- char buf[256];
-
- if (ufp) {
- for (; nargs--; arg++) {
- if (lua_type(L, arg) == LUA_TNUMBER) {
- /* optimization: could be done exactly as for strings */
- len = lua_isinteger(L, arg)
- ? sprintf(buf, LUA_INTEGER_FMT,
- (LUAI_UACINT)lua_tointeger(L, arg))
- : sprintf(buf, LUA_NUMBER_FMT,
- (LUAI_UACNUMBER)lua_tonumber(L, arg));
- len = strlen(buf);
- status = status && (ufs_fwrite(buf, sizeof(char), len, ufp) == len);
- }
- else {
- size_t l;
- const char *s = luaL_checklstring(L, arg, &l);
- status = status && (ufs_fwrite((char*)s, sizeof(char), l, ufp) == l);
- }
- }
- }
- else {
- for (; nargs--; arg++) {
- if (lua_type(L, arg) == LUA_TNUMBER) {
- /* optimization: could be done exactly as for strings */
- len = lua_isinteger(L, arg)
- ? fprintf(f, LUA_INTEGER_FMT,
- (LUAI_UACINT)lua_tointeger(L, arg))
- : fprintf(f, LUA_NUMBER_FMT,
- (LUAI_UACNUMBER)lua_tonumber(L, arg));
- status = status && (len > 0);
- }
- else {
- size_t l;
- const char *s = luaL_checklstring(L, arg, &l);
- status = status && (fwrite(s, sizeof(char), l, f) == l);
- }
- }
- }
-
- if (l_likely(status))
- return 1; /* file handle already on stack top */
- else return luaL_fileresult(L, status, NULL);
-}
-
-
-static int io_write (lua_State *L) {
- return g_write(L, getiofile(L, IO_OUTPUT), 1);
-}
-
-
-static int f_write (lua_State *L) {
- FILE *f = tofile(L);
- lua_pushvalue(L, 1); /* push file at the stack top (to be returned) */
- return g_write(L, f, 2);
-}
-
-
-static int f_seek (lua_State *L) {
- static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
- static const char *const modenames[] = {"set", "cur", "end", NULL};
- FILE *f = tofile(L);
- int op = luaL_checkoption(L, 2, "cur", modenames);
- lua_Integer p3 = luaL_optinteger(L, 3, 0);
- l_seeknum offset = (l_seeknum)p3;
- luaL_argcheck(L, (lua_Integer)offset == p3, 3,
- "not an integer in proper range");
- op = l_fseek(f, offset, mode[op]);
- if (l_unlikely(op))
- return luaL_fileresult(L, 0, NULL); /* error */
- else {
- lua_pushinteger(L, (lua_Integer)l_ftell(f));
- return 1;
- }
-}
-
-
-static int f_setvbuf (lua_State *L) {
- static const int mode[] = {_IONBF, _IOFBF, _IOLBF};
- static const char *const modenames[] = {"no", "full", "line", NULL};
- FILE *f = tofile(L);
- int op = luaL_checkoption(L, 2, NULL, modenames);
- lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
- int res = setvbuf(f, NULL, mode[op], (size_t)sz);
- return luaL_fileresult(L, res == 0, NULL);
-}
-
-
-
-static int io_flush (lua_State *L)
-{
- FILE *f = getiofile(L, IO_OUTPUT);
- UFSFILE *ufp = get_ufsfile(f);
- int status = 0;
-
- if (ufp) {
- ufs_fsync(ufp);
- status = ufs_ferror(ufp);
- }
- else {
- status = fflush(f);
- }
-
- return luaL_fileresult(L, status == 0, NULL);
-}
-
-
-static int f_flush (lua_State *L)
-{
- return luaL_fileresult(L, fflush(tofile(L)) == 0, NULL);
-}
-
-
-/*
-** functions for 'io' library
-*/
-static const luaL_Reg iolib[] = {
- {"close", io_close},
- {"flush", io_flush},
- {"input", io_input},
- {"lines", io_lines},
- {"open", io_open},
- {"output", io_output},
- {"popen", io_popen},
- {"read", io_read},
- {"tmpfile", io_tmpfile},
- {"type", io_type},
- {"write", io_write},
- {NULL, NULL}
-};
-
-
-/*
-** methods for file handles
-*/
-static const luaL_Reg meth[] = {
- {"read", f_read},
- {"write", f_write},
- {"lines", f_lines},
- {"flush", f_flush},
- {"seek", f_seek},
- {"close", f_close},
- {"setvbuf", f_setvbuf},
- {NULL, NULL}
-};
-
-
-/*
-** metamethods for file handles
-*/
-static const luaL_Reg metameth[] = {
- {"__index", NULL}, /* place holder */
- {"__gc", f_gc},
- {"__close", f_gc},
- {"__tostring", f_tostring},
- {NULL, NULL}
-};
-
-
-static void createmeta (lua_State *L) {
- luaL_newmetatable(L, LUA_FILEHANDLE); /* metatable for file handles */
- luaL_setfuncs(L, metameth, 0); /* add metamethods to new metatable */
- luaL_newlibtable(L, meth); /* create method table */
- luaL_setfuncs(L, meth, 0); /* add file methods to method table */
- lua_setfield(L, -2, "__index"); /* metatable.__index = method table */
- lua_pop(L, 1); /* pop metatable */
-}
-
-
-/*
-** function to (not) close the standard files stdin, stdout, and stderr
-*/
-static int io_noclose (lua_State *L) {
- LStream *p = tolstream(L);
- p->closef = &io_noclose; /* keep file opened */
- luaL_pushfail(L);
- lua_pushliteral(L, "cannot close standard file");
- return 2;
-}
-
-
-static void createstdfile (lua_State *L, FILE *f, const char *k,
- const char *fname) {
- LStream *p = newprefile(L);
- p->f = f;
- p->closef = &io_noclose;
- if (k != NULL) {
- lua_pushvalue(L, -1);
- lua_setfield(L, LUA_REGISTRYINDEX, k); /* add file to registry */
- }
- lua_setfield(L, -2, fname); /* add file to module */
-}
-
-
-LUAMOD_API int luaopen_io (lua_State *L) {
- luaL_newlib(L, iolib); /* new module */
- createmeta(L);
- /* create (and set) default files */
- createstdfile(L, stdin, IO_INPUT, "stdin");
- createstdfile(L, stdout, IO_OUTPUT, "stdout");
- createstdfile(L, stderr, NULL, "stderr");
- return 1;
-}
-
diff --git a/src/loadlib.c b/src/loadlib.c
deleted file mode 100644
index 1ffe9dc..0000000
--- a/src/loadlib.c
+++ /dev/null
@@ -1,946 +0,0 @@
-/*
-** $Id: loadlib.c $
-** Dynamic library loader for Lua
-** See Copyright Notice in lua.h
-**
-** This module contains an implementation of loadlib for Unix systems
-** that have dlfcn, an implementation for Windows, and a stub for other
-** systems.
-*/
-
-/* This is a copy of lauxlib.c from LUA370 with modifications
- * to support UFS in the HTTPD environment.
- */
-
-#define loadlib_c
-#define LUA_LIB
-
-#include "lprefix.h"
-
-
-#include
-#include
-#include
-
-#include "lua.h"
-
-#include "lauxlib.h"
-#include "lualib.h"
-
-#define HTTPLUAX_PRIVATE /* suppress defines for Lua functions */
-//#define luai_likely(x) (x)
-//#define luai_unlikely(x) (x)
-#include "httpd.h"
-
-
-/*
-** LUA_IGMARK is a mark to ignore all before it when building the
-** luaopen_ function name.
-*/
-#if !defined (LUA_IGMARK)
-#define LUA_IGMARK "-"
-#endif
-
-
-/*
-** LUA_CSUBSEP is the character that replaces dots in submodule names
-** when searching for a C loader.
-** LUA_LSUBSEP is the character that replaces dots in submodule names
-** when searching for a Lua loader.
-*/
-#if !defined(LUA_CSUBSEP)
-#define LUA_CSUBSEP LUA_DIRSEP
-#endif
-
-#if !defined(LUA_LSUBSEP)
-#define LUA_LSUBSEP LUA_DIRSEP
-#endif
-
-
-/* prefix for open functions in C libraries */
-#define LUA_POF "luaopen_"
-
-/* separator for open functions in C libraries */
-#define LUA_OFSEP "_"
-
-
-/*
-** key for table in the registry that keeps handles
-** for all loaded C libraries
-*/
-static const char *const CLIBS = "_CLIBS";
-
-#define LIB_FAIL "open"
-
-
-#define setprogdir(L) ((void)0)
-
-
-/*
-** Special type equivalent to '(void*)' for functions in gcc
-** (to suppress warnings when converting function pointers)
-*/
-typedef void (*voidf)(void);
-
-
-/*
-** system-dependent functions
-*/
-
-/*
-** unload library 'lib'
-*/
-static void lsys_unloadlib (void *lib);
-
-/*
-** load C library in file 'path'. If 'seeglb', load with all names in
-** the library global.
-** Returns the library; in case of error, returns NULL plus an
-** error string in the stack.
-*/
-static void *lsys_load (lua_State *L, const char *path, int seeglb);
-
-/*
-** Try to find a function named 'sym' in library 'lib'.
-** Returns the function; in case of error, returns NULL plus an
-** error string in the stack.
-*/
-static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym);
-
-
-
-
-#if defined(LUA_USE_DLOPEN) /* { */
-/*
-** {========================================================================
-** This is an implementation of loadlib based on the dlfcn interface.
-** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
-** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least
-** as an emulation layer on top of native functions.
-** =========================================================================
-*/
-
-#include
-
-/*
-** Macro to convert pointer-to-void* to pointer-to-function. This cast
-** is undefined according to ISO C, but POSIX assumes that it works.
-** (The '__extension__' in gnu compilers is only to avoid warnings.)
-*/
-#if defined(__GNUC__)
-#define cast_func(p) (__extension__ (lua_CFunction)(p))
-#else
-#define cast_func(p) ((lua_CFunction)(p))
-#endif
-
-
-static void lsys_unloadlib (void *lib) {
- dlclose(lib);
-}
-
-
-static void *lsys_load (lua_State *L, const char *path, int seeglb) {
- void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL));
- if (l_unlikely(lib == NULL))
- lua_pushstring(L, dlerror());
- return lib;
-}
-
-
-static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
- lua_CFunction f = cast_func(dlsym(lib, sym));
- if (l_unlikely(f == NULL))
- lua_pushstring(L, dlerror());
- return f;
-}
-
-/* }====================================================== */
-
-
-
-#elif defined(LUA_DL_DLL) /* }{ */
-/*
-** {======================================================================
-** This is an implementation of loadlib for Windows using native functions.
-** =======================================================================
-*/
-
-#include
-
-
-/*
-** optional flags for LoadLibraryEx
-*/
-#if !defined(LUA_LLE_FLAGS)
-#define LUA_LLE_FLAGS 0
-#endif
-
-
-#undef setprogdir
-
-
-/*
-** Replace in the path (on the top of the stack) any occurrence
-** of LUA_EXEC_DIR with the executable's path.
-*/
-static void setprogdir (lua_State *L) {
- char buff[MAX_PATH + 1];
- char *lb;
- DWORD nsize = sizeof(buff)/sizeof(char);
- DWORD n = GetModuleFileNameA(NULL, buff, nsize); /* get exec. name */
- if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
- luaL_error(L, "unable to get ModuleFileName");
- else {
- *lb = '\0'; /* cut name on the last '\\' to get the path */
- luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff);
- lua_remove(L, -2); /* remove original string */
- }
-}
-
-
-
-
-static void pusherror (lua_State *L) {
- int error = GetLastError();
- char buffer[128];
- if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
- NULL, error, 0, buffer, sizeof(buffer)/sizeof(char), NULL))
- lua_pushstring(L, buffer);
- else
- lua_pushfstring(L, "system error %d\n", error);
-}
-
-static void lsys_unloadlib (void *lib) {
- FreeLibrary((HMODULE)lib);
-}
-
-
-static void *lsys_load (lua_State *L, const char *path, int seeglb) {
- HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS);
- (void)(seeglb); /* not used: symbols are 'global' by default */
- if (lib == NULL) pusherror(L);
- return lib;
-}
-
-
-static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
- lua_CFunction f = (lua_CFunction)(voidf)GetProcAddress((HMODULE)lib, sym);
- if (f == NULL) pusherror(L);
- return f;
-}
-
-/* }====================================================== */
-
-
-#else /* }{ */
-/*
-** {======================================================
-** Fallback for other systems
-** =======================================================
-*/
-
-#undef LIB_FAIL
-#define LIB_FAIL "absent"
-
-
-#define DLMSG "dynamic libraries not enabled; check your Lua installation"
-
-
-static void lsys_unloadlib (void *lib) {
- (void)(lib); /* not used */
-}
-
-
-static void *lsys_load (lua_State *L, const char *path, int seeglb) {
- (void)(path); (void)(seeglb); /* not used */
- lua_pushliteral(L, DLMSG);
- return NULL;
-}
-
-
-static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
- (void)(lib); (void)(sym); /* not used */
- lua_pushliteral(L, DLMSG);
- return NULL;
-}
-
-/* }====================================================== */
-#endif /* } */
-
-
-/*
-** {==================================================================
-** Set Paths
-** ===================================================================
-*/
-
-/*
-** LUA_PATH_VAR and LUA_CPATH_VAR are the names of the environment
-** variables that Lua check to set its paths.
-*/
-#if !defined(LUA_PATH_VAR)
-#define LUA_PATH_VAR "LUA_PATH"
-#endif
-
-#if !defined(LUA_CPATH_VAR)
-#define LUA_CPATH_VAR "LUA_CPATH"
-#endif
-
-
-
-/*
-** return registry.LUA_NOENV as a boolean
-*/
-static int noenv (lua_State *L) {
- int b;
- lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
- b = lua_toboolean(L, -1);
- lua_pop(L, 1); /* remove value */
- return b;
-}
-
-
-/*
-** Set a path
-*/
-static void setpath (lua_State *L, const char *fieldname,
- const char *envname,
- const char *dft) {
- const char *dftmark;
- const char *nver = lua_pushfstring(L, "%s%s", envname, LUA_VERSUFFIX);
- const char *path = getenv(nver); /* try versioned name */
- if (path == NULL) /* no versioned environment variable? */
- path = getenv(envname); /* try unversioned name */
- if (path == NULL || noenv(L)) /* no environment variable? */
- lua_pushstring(L, dft); /* use default */
- else if ((dftmark = strstr(path, LUA_PATH_SEP LUA_PATH_SEP)) == NULL)
- lua_pushstring(L, path); /* nothing to change */
- else { /* path contains a ";;": insert default path in its place */
- size_t len = strlen(path);
- luaL_Buffer b;
- luaL_buffinit(L, &b);
- if (path < dftmark) { /* is there a prefix before ';;'? */
- luaL_addlstring(&b, path, dftmark - path); /* add it */
- luaL_addchar(&b, *LUA_PATH_SEP);
- }
- luaL_addstring(&b, dft); /* add default */
- if (dftmark < path + len - 2) { /* is there a suffix after ';;'? */
- luaL_addchar(&b, *LUA_PATH_SEP);
- luaL_addlstring(&b, dftmark + 2, (path + len - 2) - dftmark);
- }
- luaL_pushresult(&b);
- }
- setprogdir(L);
- lua_setfield(L, -3, fieldname); /* package[fieldname] = path value */
- lua_pop(L, 1); /* pop versioned variable name ('nver') */
-}
-
-/* }================================================================== */
-
-
-/*
-** return registry.CLIBS[path]
-*/
-static void *checkclib (lua_State *L, const char *path) {
- void *plib;
- lua_getfield(L, LUA_REGISTRYINDEX, CLIBS);
- lua_getfield(L, -1, path);
- plib = lua_touserdata(L, -1); /* plib = CLIBS[path] */
- lua_pop(L, 2); /* pop CLIBS table and 'plib' */
- return plib;
-}
-
-
-/*
-** registry.CLIBS[path] = plib -- for queries
-** registry.CLIBS[#CLIBS + 1] = plib -- also keep a list of all libraries
-*/
-static void addtoclib (lua_State *L, const char *path, void *plib) {
- lua_getfield(L, LUA_REGISTRYINDEX, CLIBS);
- lua_pushlightuserdata(L, plib);
- lua_pushvalue(L, -1);
- lua_setfield(L, -3, path); /* CLIBS[path] = plib */
- lua_rawseti(L, -2, luaL_len(L, -2) + 1); /* CLIBS[#CLIBS + 1] = plib */
- lua_pop(L, 1); /* pop CLIBS table */
-}
-
-
-/*
-** __gc tag method for CLIBS table: calls 'lsys_unloadlib' for all lib
-** handles in list CLIBS
-*/
-static int gctm (lua_State *L) {
- lua_Integer n = luaL_len(L, 1);
- for (; n >= 1; n--) { /* for each handle, in reverse order */
- lua_rawgeti(L, 1, n); /* get handle CLIBS[n] */
- lsys_unloadlib(lua_touserdata(L, -1));
- lua_pop(L, 1); /* pop handle */
- }
- return 0;
-}
-
-
-
-/* error codes for 'lookforfunc' */
-#define ERRLIB 1
-#define ERRFUNC 2
-
-/*
-** Look for a C function named 'sym' in a dynamically loaded library
-** 'path'.
-** First, check whether the library is already loaded; if not, try
-** to load it.
-** Then, if 'sym' is '*', return true (as library has been loaded).
-** Otherwise, look for symbol 'sym' in the library and push a
-** C function with that symbol.
-** Return 0 and 'true' or a function in the stack; in case of
-** errors, return an error code and an error message in the stack.
-*/
-static int lookforfunc (lua_State *L, const char *path, const char *sym) {
- void *reg = checkclib(L, path); /* check loaded C libraries */
- if (reg == NULL) { /* must load library? */
- reg = lsys_load(L, path, *sym == '*'); /* global symbols if 'sym'=='*' */
- if (reg == NULL) return ERRLIB; /* unable to load library */
- addtoclib(L, path, reg);
- }
- if (*sym == '*') { /* loading only library (no function)? */
- lua_pushboolean(L, 1); /* return 'true' */
- return 0; /* no errors */
- }
- else {
- lua_CFunction f = lsys_sym(L, reg, sym);
- if (f == NULL)
- return ERRFUNC; /* unable to find function */
- lua_pushcfunction(L, f); /* else create new function */
- return 0; /* no errors */
- }
-}
-
-
-static int ll_loadlib (lua_State *L) {
- const char *path = luaL_checkstring(L, 1);
- const char *init = luaL_checkstring(L, 2);
- int stat = lookforfunc(L, path, init);
- if (l_likely(stat == 0)) /* no errors? */
- return 1; /* return the loaded function */
- else { /* error; error message is on stack top */
- luaL_pushfail(L);
- lua_insert(L, -2);
- lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init");
- return 3; /* return fail, error message, and where */
- }
-}
-
-
-
-/*
-** {======================================================
-** 'require' function
-** =======================================================
-*/
-
-
-static int readable (const char *filename)
-{
- CLIBCRT *crt = __crtget();
- UFS *ufs = crt ? crt->crtufs : NULL;
- UFSFILE *ufp = NULL;
- FILE *f = NULL;
-
- // wtof("loadlib.c:%s: enter \"%s\"", __func__, filename);
-
- // wtof("loadlib.c:%s: ufs=%p LUA_PATH_SEP=%s", __func__, ufs, LUA_PATH_SEP);
- if (ufs) {
- ufp = ufs_fopen(ufs, filename, "r");
- // wtof("loadlib.c:%s: ufp=%p", __func__, ufp);
- if (ufp) {
- /* this filename exist and is readable */
- ufs_fclose(&ufp);
- return 1;
- }
- }
-
- /* try opening as a dataset */
- f = fopen(filename, "r"); /* try to open file */
- // wtof("loadlib.c:%s: f=%p", __func__, f);
- if (f == NULL) return 0; /* open failed */
- fclose(f);
- return 1;
-}
-
-
-/*
-** Get the next name in '*path' = 'name1;name2;name3;...', changing
-** the ending ';' to '\0' to create a zero-terminated string. Return
-** NULL when list ends.
-*/
-static const char *getnextfilename (char **path, char *end)
-{
- static const char *pathsep = LUA_PATH_SEP;
- char *sep;
- char *name = *path;
-
- // wtof("loadlib.c:%s: enter path=%p name=%p end=%p", __func__, path, name, end);
-
- if (name == end)
- return NULL; /* no more names */
- else if (*name == '\0') { /* from previous iteration? */
- *name = *pathsep; /* restore separator */
- name++; /* skip it */
- }
-
- sep = strchr(name, *pathsep); /* find next separator */
- // wtof("loadlib.c:%s: strchr(\"%s\",%c) sep=%p", __func__, name, *pathsep, sep);
- if (sep == NULL) /* separator not found? */
- sep = end; /* name goes until the end */
-
- *sep = '\0'; /* finish file name */
- *path = sep; /* will start next search from here */
- return name;
-}
-
-
-/*
-** Given a path such as ";blabla.so;blublu.so", pushes the string
-**
-** no file 'blabla.so'
-** no file 'blublu.so'
-*/
-static void pusherrornotfound (lua_State *L, const char *path) {
- luaL_Buffer b;
- luaL_buffinit(L, &b);
- luaL_addstring(&b, "no file '");
- luaL_addgsub(&b, path, LUA_PATH_SEP, "'\n\tno file '");
- luaL_addstring(&b, "'");
- luaL_pushresult(&b);
-}
-
-
-static const char *searchpath (lua_State *L, const char *name,
- const char *path,
- const char *sep,
- const char *dirsep) {
- luaL_Buffer buff;
- char *pathname; /* path with name inserted */
- char *endpathname; /* its end */
- const char *filename;
- /* separator is non-empty and appears in 'name'? */
- if (*sep != '\0' && strchr(name, *sep) != NULL)
- name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */
- luaL_buffinit(L, &buff);
- /* add path to the buffer, replacing marks ('?') with the file name */
- luaL_addgsub(&buff, path, LUA_PATH_MARK, name);
- luaL_addchar(&buff, '\0');
- pathname = luaL_buffaddr(&buff); /* writable list of file names */
- endpathname = pathname + luaL_bufflen(&buff) - 1;
- while ((filename = getnextfilename(&pathname, endpathname)) != NULL) {
- if (readable(filename)) /* does file exist and is readable? */
- return lua_pushstring(L, filename); /* save and return name */
- }
- luaL_pushresult(&buff); /* push path to create error message */
- pusherrornotfound(L, lua_tostring(L, -1)); /* create error message */
- return NULL; /* not found */
-}
-
-
-static int ll_searchpath (lua_State *L) {
- const char *f = searchpath(L, luaL_checkstring(L, 1),
- luaL_checkstring(L, 2),
- luaL_optstring(L, 3, "."),
- luaL_optstring(L, 4, LUA_DIRSEP));
- if (f != NULL) return 1;
- else { /* error message is on top of the stack */
- luaL_pushfail(L);
- lua_insert(L, -2);
- return 2; /* return fail + error message */
- }
-}
-
-
-static const char *findfile (lua_State *L, const char *name,
- const char *pname,
- const char *dirsep) {
- const char *path;
- lua_getfield(L, lua_upvalueindex(1), pname);
- path = lua_tostring(L, -1);
- if (l_unlikely(path == NULL))
- luaL_error(L, "'package.%s' must be a string", pname);
- return searchpath(L, name, path, ".", dirsep);
-}
-
-
-static int checkload (lua_State *L, int stat, const char *filename) {
- if (l_likely(stat)) { /* module loaded successfully? */
- lua_pushstring(L, filename); /* will be 2nd argument to module */
- return 2; /* return open function and file name */
- }
- else
- return luaL_error(L, "error loading module '%s' from file '%s':\n\t%s",
- lua_tostring(L, 1), filename, lua_tostring(L, -1));
-}
-
-
-static int searcher_Lua (lua_State *L) {
- const char *filename;
- const char *name = luaL_checkstring(L, 1);
- filename = findfile(L, name, "path", LUA_LSUBSEP);
- if (filename == NULL) return 1; /* module not found in this path */
- return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename);
-}
-
-
-/*
-** Try to find a load function for module 'modname' at file 'filename'.
-** First, change '.' to '_' in 'modname'; then, if 'modname' has
-** the form X-Y (that is, it has an "ignore mark"), build a function
-** name "luaopen_X" and look for it. (For compatibility, if that
-** fails, it also tries "luaopen_Y".) If there is no ignore mark,
-** look for a function named "luaopen_modname".
-*/
-static int loadfunc (lua_State *L, const char *filename, const char *modname) {
- const char *openfunc;
- const char *mark;
- modname = luaL_gsub(L, modname, ".", LUA_OFSEP);
- mark = strchr(modname, *LUA_IGMARK);
- if (mark) {
- int stat;
- openfunc = lua_pushlstring(L, modname, mark - modname);
- openfunc = lua_pushfstring(L, LUA_POF"%s", openfunc);
- stat = lookforfunc(L, filename, openfunc);
- if (stat != ERRFUNC) return stat;
- modname = mark + 1; /* else go ahead and try old-style name */
- }
- openfunc = lua_pushfstring(L, LUA_POF"%s", modname);
- return lookforfunc(L, filename, openfunc);
-}
-
-
-static int searcher_C (lua_State *L) {
- const char *name = luaL_checkstring(L, 1);
- const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP);
- if (filename == NULL) return 1; /* module not found in this path */
- return checkload(L, (loadfunc(L, filename, name) == 0), filename);
-}
-
-
-static int searcher_Croot (lua_State *L) {
- const char *filename;
- const char *name = luaL_checkstring(L, 1);
- const char *p = strchr(name, '.');
- int stat;
- if (p == NULL) return 0; /* is root */
- lua_pushlstring(L, name, p - name);
- filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP);
- if (filename == NULL) return 1; /* root not found */
- if ((stat = loadfunc(L, filename, name)) != 0) {
- if (stat != ERRFUNC)
- return checkload(L, 0, filename); /* real error */
- else { /* open function not found */
- lua_pushfstring(L, "no module '%s' in file '%s'", name, filename);
- return 1;
- }
- }
- lua_pushstring(L, filename); /* will be 2nd argument to module */
- return 2;
-}
-
-
-static int searcher_preload (lua_State *L) {
- const char *name = luaL_checkstring(L, 1);
- lua_getfield(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
- if (lua_getfield(L, -1, name) == LUA_TNIL) { /* not found? */
- lua_pushfstring(L, "no field package.preload['%s']", name);
- return 1;
- }
- else {
- lua_pushliteral(L, ":preload:");
- return 2;
- }
-}
-
-
-static void findloader (lua_State *L, const char *name) {
- int i;
- luaL_Buffer msg; /* to build error message */
- /* push 'package.searchers' to index 3 in the stack */
- if (l_unlikely(lua_getfield(L, lua_upvalueindex(1), "searchers")
- != LUA_TTABLE))
- luaL_error(L, "'package.searchers' must be a table");
- luaL_buffinit(L, &msg);
- /* iterate over available searchers to find a loader */
- for (i = 1; ; i++) {
- luaL_addstring(&msg, "\n\t"); /* error-message prefix */
- if (l_unlikely(lua_rawgeti(L, 3, i) == LUA_TNIL)) { /* no more searchers? */
- lua_pop(L, 1); /* remove nil */
- luaL_buffsub(&msg, 2); /* remove prefix */
- luaL_pushresult(&msg); /* create error message */
- luaL_error(L, "module '%s' not found:%s", name, lua_tostring(L, -1));
- }
- lua_pushstring(L, name);
- lua_call(L, 1, 2); /* call it */
- if (lua_isfunction(L, -2)) /* did it find a loader? */
- return; /* module loader found */
- else if (lua_isstring(L, -2)) { /* searcher returned error message? */
- lua_pop(L, 1); /* remove extra return */
- luaL_addvalue(&msg); /* concatenate error message */
- }
- else { /* no error message */
- lua_pop(L, 2); /* remove both returns */
- luaL_buffsub(&msg, 2); /* remove prefix */
- }
- }
-}
-
-
-static int ll_require (lua_State *L) {
- const char *name = luaL_checkstring(L, 1);
- lua_settop(L, 1); /* LOADED table will be at index 2 */
- lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
- lua_getfield(L, 2, name); /* LOADED[name] */
- if (lua_toboolean(L, -1)) /* is it there? */
- return 1; /* package is already loaded */
- /* else must load package */
- lua_pop(L, 1); /* remove 'getfield' result */
- findloader(L, name);
- lua_rotate(L, -2, 1); /* function <-> loader data */
- lua_pushvalue(L, 1); /* name is 1st argument to module loader */
- lua_pushvalue(L, -3); /* loader data is 2nd argument */
- /* stack: ...; loader data; loader function; mod. name; loader data */
- lua_call(L, 2, 1); /* run loader to load module */
- /* stack: ...; loader data; result from loader */
- if (!lua_isnil(L, -1)) /* non-nil return? */
- lua_setfield(L, 2, name); /* LOADED[name] = returned value */
- else
- lua_pop(L, 1); /* pop nil */
- if (lua_getfield(L, 2, name) == LUA_TNIL) { /* module set no value? */
- lua_pushboolean(L, 1); /* use true as result */
- lua_copy(L, -1, -2); /* replace loader result */
- lua_setfield(L, 2, name); /* LOADED[name] = true */
- }
- lua_rotate(L, -2, 1); /* loader data <-> module result */
- return 2; /* return module result and loader data */
-}
-
-/* }====================================================== */
-
-
-
-
-static const luaL_Reg pk_funcs[] = {
- {"loadlib", ll_loadlib},
- {"searchpath", ll_searchpath},
- /* placeholders */
- {"preload", NULL},
- {"cpath", NULL},
- {"path", NULL},
- {"searchers", NULL},
- {"loaded", NULL},
- {NULL, NULL}
-};
-
-
-static const luaL_Reg ll_funcs[] = {
- {"require", ll_require},
- {NULL, NULL}
-};
-
-
-static void createsearcherstable (lua_State *L) {
- static const lua_CFunction searchers[] = {
- searcher_preload,
- searcher_Lua,
- searcher_C,
- searcher_Croot,
- NULL
- };
- int i;
- /* create 'searchers' table */
- lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0);
- /* fill it with predefined searchers */
- for (i=0; searchers[i] != NULL; i++) {
- lua_pushvalue(L, -2); /* set 'package' as upvalue for all searchers */
- lua_pushcclosure(L, searchers[i], 1);
- lua_rawseti(L, -2, i+1);
- }
- lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */
-}
-
-
-/*
-** create table CLIBS to keep track of loaded C libraries,
-** setting a finalizer to close all libraries when closing state.
-*/
-static void createclibstable (lua_State *L) {
- luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS); /* create CLIBS table */
- lua_createtable(L, 0, 1); /* create metatable for CLIBS */
- lua_pushcfunction(L, gctm);
- lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */
- lua_setmetatable(L, -2);
-}
-
-#include "racf.h"
-#include "acee.h"
-#include "clibppa.h"
-typedef struct upt {
- char dontcare[16];
- char uptprefx[7];
- char uptprefl;
-} UPT;
-typedef struct pscb {
- char dontcare[52];
- UPT *pscbupt;
- short pscbuptl;
-} PSCB;
-
-static char *makepath(void)
-{
- CLIBPPA *ppa = __ppaget();
- ACEE *acee = racf_get_acee();
- char *path = calloc(1, strlen(LUA_PATH_DEFAULT)+128);
- char prefix[12] = {0};
- char userid[12] = {0};
- int pos = 0;
- int i;
-
- if (!path) goto quit;
-
- if (ppa && ppa->ppapscb) {
- /* we have a TSO PSCB control block */
- PSCB *pscb = ppa->ppapscb;
-
- if (pscb->pscbupt && pscb->pscbuptl) {
- UPT *upt = pscb->pscbupt;
- char *prefx = upt->uptprefx;
- char prefxlen = upt->uptprefl;
-
- if (prefx[0] > ' ' && prefxlen) {
- for(i=0; i < prefxlen; i++) {
- prefix[i] = prefx[i];
- }
- sprintf(&path[pos], "%s.LUA370.LUA(?);%s.LUA(?);", prefix, prefix);
- pos = strlen(path);
- }
- }
- }
-
- if (acee) {
- for(i=0; i<8; i++) {
- if (acee->aceeuser[i+1]==' ') {
- userid[i] = 0;
- break;
- }
- userid[i] = acee->aceeuser[i+1];
- }
- }
-
- if (userid[0] && strcmp(prefix, userid)!=0) {
- sprintf(&path[pos], "%s.LUA370.LUA(?);%s.LUA(?);", userid, userid);
- pos = strlen(path);
- }
-
- strcpy(&path[pos], LUA_PATH_DEFAULT);
- // wtodumpf(path, strlen(path), "%s: path", __func__);
-quit:
- return path;
-}
-
-static char *makecpath(void)
-{
- CLIBPPA *ppa = __ppaget();
- ACEE *acee = racf_get_acee();
- char *cpath = calloc(1, strlen(LUA_PATH_DEFAULT)+128);
- char prefix[12] = {0};
- char userid[12] = {0};
- int pos = 0;
- int i;
-
- if (!cpath) goto quit;
-
- if (ppa && ppa->ppapscb) {
- /* we have a TSO PSCB control block */
- PSCB *pscb = ppa->ppapscb;
-
- if (pscb->pscbupt && pscb->pscbuptl) {
- UPT *upt = pscb->pscbupt;
- char *prefx = upt->uptprefx;
- char prefxlen = upt->uptprefl;
-
- if (prefx[0] > ' ' && prefxlen) {
- for(i=0; i < prefxlen; i++) {
- prefix[i] = prefx[i];
- }
- sprintf(&cpath[pos], "%s.LUA370.LINKLIB(?);%s.LINKLIB(?);", prefix, prefix);
- pos = strlen(cpath);
- }
- }
- }
-
- if (acee) {
- for(i=0; iaceeuser[0]; i++) {
- if (acee->aceeuser[i+1]==' ') {
- userid[i] = 0;
- break;
- }
- userid[i] = acee->aceeuser[i+1];
- }
- }
-
- if (userid[0] && strcmp(prefix, userid)!=0) {
- sprintf(&cpath[pos], "%s.LUA370.LINKLIB(?);%s.LINKLIB(?);", userid, userid);
- pos = strlen(cpath);
- }
-
- strcpy(&cpath[pos], LUA_CPATH_DEFAULT);
- // wtodumpf(cpath, strlen(cpath), "%s: cpath", __func__);
-
-quit:
- return cpath;
-}
-
-LUAMOD_API int luaopen_package (lua_State *L) {
- createclibstable(L);
- luaL_newlib(L, pk_funcs); /* create 'package' table */
- createsearcherstable(L);
- /* set paths */
-#if 1
- {
- char *path = makepath();
- char *cpath = makecpath();
-
- if (path) {
- setpath(L, "path", LUA_PATH_VAR, path);
- free(path);
- }
- else {
- setpath(L, "path", LUA_PATH_VAR, LUA_PATH_DEFAULT);
- }
-
- if (cpath) {
- setpath(L, "cpath", LUA_CPATH_VAR, cpath);
- free(cpath);
- }
- else {
- setpath(L, "cpath", LUA_CPATH_VAR, LUA_CPATH_DEFAULT);
- }
- }
-#else
- setpath(L, "path", LUA_PATH_VAR, LUA_PATH_DEFAULT);
- setpath(L, "cpath", LUA_CPATH_VAR, LUA_CPATH_DEFAULT);
-#endif
- /* store config information */
- lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n"
- LUA_EXEC_DIR "\n" LUA_IGMARK "\n");
- lua_setfield(L, -2, "config");
- /* set field 'loaded' */
- luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
- lua_setfield(L, -2, "loaded");
- /* set field 'preload' */
- luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
- lua_setfield(L, -2, "preload");
- lua_pushglobaltable(L);
- lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */
- luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */
- lua_pop(L, 1); /* pop global table */
- return 1; /* return 'package' table */
-}
-