Initial commit: Ananta CBT 4229938 private server with all fixes
This commit is contained in:
commit
c84135c357
286 files changed
+2214315
No files matched your search
+592
@@ -0,0 +1,592 @@
|
||||
"use strict";
|
||||
|
||||
const {
|
||||
LUA_TNIL,
|
||||
LUA_TTABLE,
|
||||
lua_close,
|
||||
lua_createtable,
|
||||
lua_getfield,
|
||||
lua_isboolean,
|
||||
lua_isnoneornil,
|
||||
lua_pop,
|
||||
lua_pushboolean,
|
||||
lua_pushfstring,
|
||||
lua_pushinteger,
|
||||
lua_pushliteral,
|
||||
lua_pushnil,
|
||||
lua_pushnumber,
|
||||
lua_pushstring,
|
||||
lua_setfield,
|
||||
lua_settop,
|
||||
lua_toboolean,
|
||||
lua_tointegerx
|
||||
} = require('./lua.js');
|
||||
const {
|
||||
luaL_Buffer,
|
||||
luaL_addchar,
|
||||
luaL_addstring,
|
||||
// luaL_argcheck,
|
||||
luaL_argerror,
|
||||
luaL_buffinit,
|
||||
luaL_checkinteger,
|
||||
luaL_checkoption,
|
||||
luaL_checkstring,
|
||||
luaL_checktype,
|
||||
luaL_error,
|
||||
luaL_execresult,
|
||||
luaL_fileresult,
|
||||
luaL_newlib,
|
||||
luaL_optinteger,
|
||||
luaL_optlstring,
|
||||
luaL_optstring,
|
||||
luaL_pushresult
|
||||
} = require('./lauxlib.js');
|
||||
const {
|
||||
luastring_eq,
|
||||
to_jsstring,
|
||||
to_luastring
|
||||
} = require("./fengaricore.js");
|
||||
|
||||
/* options for ANSI C 89 (only 1-char options) */
|
||||
// const L_STRFTIMEC89 = to_luastring("aAbBcdHIjmMpSUwWxXyYZ%");
|
||||
// const LUA_STRFTIMEOPTIONS = L_STRFTIMEC89;
|
||||
|
||||
/* options for ISO C 99 and POSIX */
|
||||
// const L_STRFTIMEC99 = to_luastring("aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%||EcECExEXEyEYOdOeOHOIOmOMOSOuOUOVOwOWOy"); /* two-char options */
|
||||
// const LUA_STRFTIMEOPTIONS = L_STRFTIMEC99;
|
||||
|
||||
/* options for Windows */
|
||||
// const L_STRFTIMEWIN = to_luastring("aAbBcdHIjmMpSUwWxXyYzZ%||#c#x#d#H#I#j#m#M#S#U#w#W#y#Y"); /* two-char options */
|
||||
// const LUA_STRFTIMEOPTIONS = L_STRFTIMEWIN;
|
||||
|
||||
/* options for our own strftime implementation
|
||||
- should be superset of C89 options for compat
|
||||
- missing from C99:
|
||||
- ISO 8601 week specifiers: gGV
|
||||
- > single char specifiers
|
||||
- beyond C99:
|
||||
- %k: TZ extension: space-padded 24-hour
|
||||
- %l: TZ extension: space-padded 12-hour
|
||||
- %P: GNU extension: lower-case am/pm
|
||||
*/
|
||||
const LUA_STRFTIMEOPTIONS = to_luastring("aAbBcCdDeFhHIjklmMnpPrRStTuUwWxXyYzZ%");
|
||||
|
||||
|
||||
const setfield = function(L, key, value) {
|
||||
lua_pushinteger(L, value);
|
||||
lua_setfield(L, -2, to_luastring(key, true));
|
||||
};
|
||||
|
||||
const setallfields = function(L, time, utc) {
|
||||
setfield(L, "sec", utc ? time.getUTCSeconds() : time.getSeconds());
|
||||
setfield(L, "min", utc ? time.getUTCMinutes() : time.getMinutes());
|
||||
setfield(L, "hour", utc ? time.getUTCHours() : time.getHours());
|
||||
setfield(L, "day", utc ? time.getUTCDate() : time.getDate());
|
||||
setfield(L, "month", (utc ? time.getUTCMonth() : time.getMonth()) + 1);
|
||||
setfield(L, "year", utc ? time.getUTCFullYear() : time.getFullYear());
|
||||
setfield(L, "wday", (utc ? time.getUTCDay() : time.getDay()) + 1);
|
||||
setfield(L, "yday", Math.floor((time - (new Date(time.getFullYear(), 0, 0 /* shortcut to correct day by one */))) / 86400000));
|
||||
// setboolfield(L, "isdst", time.get);
|
||||
};
|
||||
|
||||
const L_MAXDATEFIELD = (Number.MAX_SAFE_INTEGER / 2);
|
||||
|
||||
const getfield = function(L, key, d, delta) {
|
||||
let t = lua_getfield(L, -1, to_luastring(key, true)); /* get field and its type */
|
||||
let res = lua_tointegerx(L, -1);
|
||||
if (res === false) { /* field is not an integer? */
|
||||
if (t !== LUA_TNIL) /* some other value? */
|
||||
return luaL_error(L, to_luastring("field '%s' is not an integer"), key);
|
||||
else if (d < 0) /* absent field; no default? */
|
||||
return luaL_error(L, to_luastring("field '%s' missing in date table"), key);
|
||||
res = d;
|
||||
}
|
||||
else {
|
||||
if (!(-L_MAXDATEFIELD <= res && res <= L_MAXDATEFIELD))
|
||||
return luaL_error(L, to_luastring("field '%s' is out-of-bound"), key);
|
||||
res -= delta;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
return res;
|
||||
};
|
||||
|
||||
|
||||
const locale = {
|
||||
days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ].map((s) => to_luastring(s)),
|
||||
shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"].map((s) => to_luastring(s)),
|
||||
months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"].map((s) => to_luastring(s)),
|
||||
shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"].map((s) => to_luastring(s)),
|
||||
AM: to_luastring("AM"),
|
||||
PM: to_luastring("PM"),
|
||||
am: to_luastring("am"),
|
||||
pm: to_luastring("pm"),
|
||||
formats: {
|
||||
c: to_luastring("%a %b %e %H:%M:%S %Y"),
|
||||
D: to_luastring("%m/%d/%y"),
|
||||
F: to_luastring("%Y-%m-%d"),
|
||||
R: to_luastring("%H:%M"),
|
||||
r: to_luastring("%I:%M:%S %p"),
|
||||
T: to_luastring("%H:%M:%S"),
|
||||
X: to_luastring("%T"),
|
||||
x: to_luastring("%D")
|
||||
}
|
||||
};
|
||||
|
||||
const week_number = function(date, start_of_week) {
|
||||
// This works by shifting the weekday back by one day if we
|
||||
// are treating Monday as the first day of the week.
|
||||
let weekday = date.getDay();
|
||||
if (start_of_week === 'monday') {
|
||||
if (weekday === 0) // Sunday
|
||||
weekday = 6;
|
||||
else
|
||||
weekday--;
|
||||
}
|
||||
let yday = (date - new Date(date.getFullYear(), 0, 1)) / 86400000;
|
||||
return Math.floor((yday + 7 - weekday) / 7);
|
||||
};
|
||||
|
||||
const push_pad_2 = function(b, n, pad) {
|
||||
if (n < 10)
|
||||
luaL_addchar(b, pad);
|
||||
luaL_addstring(b, to_luastring(String(n)));
|
||||
};
|
||||
|
||||
const strftime = function(L, b, s, date) {
|
||||
let i = 0;
|
||||
while (i < s.length) {
|
||||
if (s[i] !== 37 /* % */) { /* not a conversion specifier? */
|
||||
luaL_addchar(b, s[i++]);
|
||||
} else {
|
||||
i++; /* skip '%' */
|
||||
let len = checkoption(L, s, i);
|
||||
/* each `case` has an example output above it for the UTC epoch */
|
||||
switch(s[i]) {
|
||||
// '%'
|
||||
case 37 /* % */:
|
||||
luaL_addchar(b, 37);
|
||||
break;
|
||||
|
||||
// 'Thursday'
|
||||
case 65 /* A */:
|
||||
luaL_addstring(b, locale.days[date.getDay()]);
|
||||
break;
|
||||
|
||||
// 'January'
|
||||
case 66 /* B */:
|
||||
luaL_addstring(b, locale.months[date.getMonth()]);
|
||||
break;
|
||||
|
||||
// '19'
|
||||
case 67 /* C */:
|
||||
push_pad_2(b, Math.floor(date.getFullYear() / 100), 48 /* 0 */);
|
||||
break;
|
||||
|
||||
// '01/01/70'
|
||||
case 68 /* D */:
|
||||
strftime(L, b, locale.formats.D, date);
|
||||
break;
|
||||
|
||||
// '1970-01-01'
|
||||
case 70 /* F */:
|
||||
strftime(L, b, locale.formats.F, date);
|
||||
break;
|
||||
|
||||
// '00'
|
||||
case 72 /* H */:
|
||||
push_pad_2(b, date.getHours(), 48 /* 0 */);
|
||||
break;
|
||||
|
||||
// '12'
|
||||
case 73 /* I */:
|
||||
push_pad_2(b, (date.getHours() + 11) % 12 + 1, 48 /* 0 */);
|
||||
break;
|
||||
|
||||
// '00'
|
||||
case 77 /* M */:
|
||||
push_pad_2(b, date.getMinutes(), 48 /* 0 */);
|
||||
break;
|
||||
|
||||
// 'am'
|
||||
case 80 /* P */:
|
||||
luaL_addstring(b, date.getHours() < 12 ? locale.am : locale.pm);
|
||||
break;
|
||||
|
||||
// '00:00'
|
||||
case 82 /* R */:
|
||||
strftime(L, b, locale.formats.R, date);
|
||||
break;
|
||||
|
||||
// '00'
|
||||
case 83 /* S */:
|
||||
push_pad_2(b, date.getSeconds(), 48 /* 0 */);
|
||||
break;
|
||||
|
||||
// '00:00:00'
|
||||
case 84 /* T */:
|
||||
strftime(L, b, locale.formats.T, date);
|
||||
break;
|
||||
|
||||
// '00'
|
||||
case 85 /* U */:
|
||||
push_pad_2(b, week_number(date, "sunday"), 48 /* 0 */);
|
||||
break;
|
||||
|
||||
// '00'
|
||||
case 87 /* W */:
|
||||
push_pad_2(b, week_number(date, "monday"), 48 /* 0 */);
|
||||
break;
|
||||
|
||||
// '16:00:00'
|
||||
case 88 /* X */:
|
||||
strftime(L, b, locale.formats.X, date);
|
||||
break;
|
||||
|
||||
// '1970'
|
||||
case 89 /* Y */:
|
||||
luaL_addstring(b, to_luastring(String(date.getFullYear())));
|
||||
break;
|
||||
|
||||
// 'GMT'
|
||||
case 90 /* Z */: {
|
||||
let tzString = date.toString().match(/\(([\w\s]+)\)/);
|
||||
if (tzString)
|
||||
luaL_addstring(b, to_luastring(tzString[1]));
|
||||
break;
|
||||
}
|
||||
|
||||
// 'Thu'
|
||||
case 97 /* a */:
|
||||
luaL_addstring(b, locale.shortDays[date.getDay()]);
|
||||
break;
|
||||
|
||||
// 'Jan'
|
||||
case 98 /* b */:
|
||||
case 104 /* h */:
|
||||
luaL_addstring(b, locale.shortMonths[date.getMonth()]);
|
||||
break;
|
||||
|
||||
// ''
|
||||
case 99 /* c */:
|
||||
strftime(L, b, locale.formats.c, date);
|
||||
break;
|
||||
|
||||
// '01'
|
||||
case 100 /* d */:
|
||||
push_pad_2(b, date.getDate(), 48 /* 0 */);
|
||||
break;
|
||||
|
||||
// ' 1'
|
||||
case 101 /* e */:
|
||||
push_pad_2(b, date.getDate(), 32 /* space */);
|
||||
break;
|
||||
|
||||
// '000'
|
||||
case 106 /* j */: {
|
||||
let yday = Math.floor((date - new Date(date.getFullYear(), 0, 1)) / 86400000);
|
||||
if (yday < 100) {
|
||||
if (yday < 10)
|
||||
luaL_addchar(b, 48 /* 0 */);
|
||||
luaL_addchar(b, 48 /* 0 */);
|
||||
}
|
||||
luaL_addstring(b, to_luastring(String(yday)));
|
||||
break;
|
||||
}
|
||||
|
||||
// ' 0'
|
||||
case 107 /* k */:
|
||||
push_pad_2(b, date.getHours(), 32 /* space */);
|
||||
break;
|
||||
|
||||
// '12'
|
||||
case 108 /* l */:
|
||||
push_pad_2(b, (date.getHours() + 11) % 12 + 1, 32 /* space */);
|
||||
break;
|
||||
|
||||
// '01'
|
||||
case 109 /* m */:
|
||||
push_pad_2(b, date.getMonth() + 1, 48 /* 0 */);
|
||||
break;
|
||||
|
||||
// '\n'
|
||||
case 110 /* n */:
|
||||
luaL_addchar(b, 10);
|
||||
break;
|
||||
|
||||
// 'AM'
|
||||
case 112 /* p */:
|
||||
luaL_addstring(b, date.getHours() < 12 ? locale.AM : locale.PM);
|
||||
break;
|
||||
|
||||
// '12:00:00 AM'
|
||||
case 114 /* r */:
|
||||
strftime(L, b, locale.formats.r, date);
|
||||
break;
|
||||
|
||||
// '0'
|
||||
case 115 /* s */:
|
||||
luaL_addstring(b, to_luastring(String(Math.floor(date / 1000))));
|
||||
break;
|
||||
|
||||
// '\t'
|
||||
case 116 /* t */:
|
||||
luaL_addchar(b, 8);
|
||||
break;
|
||||
|
||||
// '4'
|
||||
case 117 /* u */: {
|
||||
let day = date.getDay();
|
||||
luaL_addstring(b, to_luastring(String(day === 0 ? 7 : day)));
|
||||
break;
|
||||
}
|
||||
|
||||
// '4'
|
||||
case 119 /* w */:
|
||||
luaL_addstring(b, to_luastring(String(date.getDay())));
|
||||
break;
|
||||
|
||||
// '12/31/69'
|
||||
case 120 /* x */:
|
||||
strftime(L, b, locale.formats.x, date);
|
||||
break;
|
||||
|
||||
// '70'
|
||||
case 121 /* y */:
|
||||
push_pad_2(b, date.getFullYear() % 100, 48 /* 0 */);
|
||||
break;
|
||||
|
||||
// '+0000'
|
||||
case 122 /* z */: {
|
||||
let off = date.getTimezoneOffset();
|
||||
if (off > 0) {
|
||||
luaL_addchar(b, 45 /* - */);
|
||||
} else {
|
||||
off = -off;
|
||||
luaL_addchar(b, 43 /* + */);
|
||||
}
|
||||
push_pad_2(b, Math.floor(off/60), 48 /* 0 */);
|
||||
push_pad_2(b, off % 60, 48 /* 0 */);
|
||||
break;
|
||||
}
|
||||
}
|
||||
i += len;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const checkoption = function(L, conv, i) {
|
||||
let option = LUA_STRFTIMEOPTIONS;
|
||||
let o = 0;
|
||||
let oplen = 1; /* length of options being checked */
|
||||
for (; o < option.length && oplen <= (conv.length - i); o += oplen) {
|
||||
if (option[o] === '|'.charCodeAt(0)) /* next block? */
|
||||
oplen++; /* will check options with next length (+1) */
|
||||
else if (luastring_eq(conv.subarray(i, i+oplen), option.subarray(o, o+oplen))) { /* match? */
|
||||
return oplen; /* return length */
|
||||
}
|
||||
}
|
||||
luaL_argerror(L, 1,
|
||||
lua_pushfstring(L, to_luastring("invalid conversion specifier '%%%s'"), conv));
|
||||
};
|
||||
|
||||
/* maximum size for an individual 'strftime' item */
|
||||
// const SIZETIMEFMT = 250;
|
||||
|
||||
|
||||
const os_date = function(L) {
|
||||
let s = luaL_optlstring(L, 1, "%c");
|
||||
let stm = lua_isnoneornil(L, 2) ? new Date() : new Date(l_checktime(L, 2) * 1000);
|
||||
let utc = false;
|
||||
let i = 0;
|
||||
if (s[i] === '!'.charCodeAt(0)) { /* UTC? */
|
||||
utc = true;
|
||||
i++; /* skip '!' */
|
||||
}
|
||||
if (s[i] === "*".charCodeAt(0) && s[i+1] === "t".charCodeAt(0)) {
|
||||
lua_createtable(L, 0, 9); /* 9 = number of fields */
|
||||
setallfields(L, stm, utc);
|
||||
} else {
|
||||
let cc = new Uint8Array(4);
|
||||
cc[0] = "%".charCodeAt(0);
|
||||
let b = new luaL_Buffer();
|
||||
luaL_buffinit(L, b);
|
||||
strftime(L, b, s, stm);
|
||||
luaL_pushresult(b);
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
|
||||
const os_time = function(L) {
|
||||
let t;
|
||||
if (lua_isnoneornil(L, 1)) /* called without args? */
|
||||
t = new Date(); /* get current time */
|
||||
else {
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
lua_settop(L, 1); /* make sure table is at the top */
|
||||
t = new Date(
|
||||
getfield(L, "year", -1, 0),
|
||||
getfield(L, "month", -1, 1),
|
||||
getfield(L, "day", -1, 0),
|
||||
getfield(L, "hour", 12, 0),
|
||||
getfield(L, "min", 0, 0),
|
||||
getfield(L, "sec", 0, 0)
|
||||
);
|
||||
setallfields(L, t);
|
||||
}
|
||||
|
||||
lua_pushinteger(L, Math.floor(t / 1000));
|
||||
return 1;
|
||||
};
|
||||
|
||||
const l_checktime = function(L, arg) {
|
||||
let t = luaL_checkinteger(L, arg);
|
||||
// luaL_argcheck(L, t, arg, "time out-of-bounds");
|
||||
return t;
|
||||
};
|
||||
|
||||
const os_difftime = function(L) {
|
||||
let t1 = l_checktime(L, 1);
|
||||
let t2 = l_checktime(L, 2);
|
||||
lua_pushnumber(L, t1 - t2);
|
||||
return 1;
|
||||
};
|
||||
|
||||
const catnames = ["all", "collate", "ctype", "monetary", "numeric", "time"].map((lc) => to_luastring(lc));
|
||||
const C = to_luastring("C");
|
||||
const POSIX = to_luastring("POSIX");
|
||||
const os_setlocale = function(L) {
|
||||
const l = luaL_optstring(L, 1, null);
|
||||
luaL_checkoption(L, 2, "all", catnames);
|
||||
/* It is not possible to set the JS-VM wide locale, so we say that we only
|
||||
know the C locale. The "POSIX" locale is defined in
|
||||
IEEE Std 1003.1-2017 Section 7.2 as equivalent to "C" */
|
||||
lua_pushstring(L, (
|
||||
l === null /* passing nil returns the current locale; which is "C" */
|
||||
|| l.length == 0 /* empty string resets to the default locale; which is "C" */
|
||||
|| luastring_eq(l, C) /* user passed "C" */
|
||||
|| luastring_eq(l, POSIX) /* user passed "POSIX", equivalent to "C" */
|
||||
) ? C : null);
|
||||
return 1;
|
||||
};
|
||||
|
||||
const syslib = {
|
||||
"date": os_date,
|
||||
"difftime": os_difftime,
|
||||
"setlocale": os_setlocale,
|
||||
"time": os_time
|
||||
};
|
||||
|
||||
if (typeof process === "undefined") {
|
||||
syslib.clock = function(L) {
|
||||
lua_pushnumber(L, performance.now()/1000);
|
||||
return 1;
|
||||
};
|
||||
} else {
|
||||
/* Only with Node */
|
||||
const fs = require('fs');
|
||||
const tmp = require('tmp');
|
||||
const child_process = require('child_process');
|
||||
|
||||
syslib.exit = function(L) {
|
||||
let status;
|
||||
if (lua_isboolean(L, 1))
|
||||
status = (lua_toboolean(L, 1) ? 0 : 1);
|
||||
else
|
||||
status = luaL_optinteger(L, 1, 0);
|
||||
if (lua_toboolean(L, 2))
|
||||
lua_close(L);
|
||||
if (L) process.exit(status); /* 'if' to avoid warnings for unreachable 'return' */
|
||||
return 0;
|
||||
};
|
||||
|
||||
syslib.getenv = function(L) {
|
||||
let key = luaL_checkstring(L, 1);
|
||||
key = to_jsstring(key); /* https://github.com/nodejs/node/issues/16961 */
|
||||
if (Object.prototype.hasOwnProperty.call(process.env, key)) {
|
||||
lua_pushliteral(L, process.env[key]);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
|
||||
syslib.clock = function(L) {
|
||||
lua_pushnumber(L, process.uptime());
|
||||
return 1;
|
||||
};
|
||||
|
||||
const lua_tmpname = function() {
|
||||
return tmp.tmpNameSync();
|
||||
};
|
||||
|
||||
syslib.remove = function(L) {
|
||||
let filename = luaL_checkstring(L, 1);
|
||||
try {
|
||||
fs.unlinkSync(filename);
|
||||
} catch (e) {
|
||||
if (e.code === 'EISDIR') {
|
||||
try {
|
||||
fs.rmdirSync(filename);
|
||||
} catch (e) {
|
||||
return luaL_fileresult(L, false, filename, e);
|
||||
}
|
||||
} else {
|
||||
return luaL_fileresult(L, false, filename, e);
|
||||
}
|
||||
}
|
||||
return luaL_fileresult(L, true);
|
||||
};
|
||||
|
||||
syslib.rename = function(L) {
|
||||
let fromname = luaL_checkstring(L, 1);
|
||||
let toname = luaL_checkstring(L, 2);
|
||||
try {
|
||||
fs.renameSync(fromname, toname);
|
||||
} catch (e) {
|
||||
return luaL_fileresult(L, false, false, e);
|
||||
}
|
||||
return luaL_fileresult(L, true);
|
||||
};
|
||||
|
||||
syslib.tmpname = function(L) {
|
||||
let name = lua_tmpname();
|
||||
if (!name)
|
||||
return luaL_error(L, to_luastring("unable to generate a unique filename"));
|
||||
lua_pushstring(L, to_luastring(name));
|
||||
return 1;
|
||||
};
|
||||
|
||||
syslib.execute = function(L) {
|
||||
let cmd = luaL_optstring(L, 1, null);
|
||||
if (cmd !== null) {
|
||||
cmd = to_jsstring(cmd);
|
||||
try {
|
||||
child_process.execSync(
|
||||
cmd,
|
||||
{
|
||||
stdio: [process.stdin, process.stdout, process.stderr]
|
||||
}
|
||||
);
|
||||
} catch (e) {
|
||||
return luaL_execresult(L, e);
|
||||
}
|
||||
|
||||
return luaL_execresult(L, null);
|
||||
} else {
|
||||
/* Assume a shell is available.
|
||||
If it's good enough for musl it's good enough for us.
|
||||
http://git.musl-libc.org/cgit/musl/tree/src/process/system.c?id=ac45692a53a1b8d2ede329d91652d43c1fb5dc8d#n22
|
||||
*/
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const luaopen_os = function(L) {
|
||||
luaL_newlib(L, syslib);
|
||||
return 1;
|
||||
};
|
||||
|
||||
module.exports.luaopen_os = luaopen_os;
|
||||
Reference in new issue
Block a user