5 #define _RPMIOB_INTERNAL
24 LUALIB_API
int luaopen_syck(lua_State *
L)
27 #ifdef WITH_LUA_INTERNAL
38 #include <luasocket.h>
46 #define _RPMLUA_INTERNAL
69 #if LUA_VERSION_NUM >= 502
70 LUALIB_API
int luaopen_posix_c (lua_State *
L);
73 #if !defined(HAVE_VSNPRINTF)
74 static inline int vsnprintf(
char * buf,
size_t nb,
75 const char * fmt, va_list ap)
77 return vsprintf(buf, fmt, ap);
81 #define INITSTATE(_lua, lua) \
82 rpmlua lua = _lua ? _lua : \
83 (globalLuaState ? globalLuaState : \
85 (globalLuaState = rpmluaNew()) \
90 static rpmlua globalLuaState;
92 static int luaopen_rpm(lua_State *
L)
94 static int rpm_print(lua_State *
L)
107 return globalLuaState;
111 static void rpmluaFini(
void * _lua)
117 if (lua->L) lua_close(lua->L);
119 lua->printbuf =
_free(lua->printbuf);
128 if (_rpmluaPool == NULL) {
130 NULL, NULL, rpmluaFini);
138 if (lua == NULL) lua = globalLuaState;
140 if (lua == globalLuaState) globalLuaState = NULL;
147 rpmlua lua = rpmluaGetPool(_rpmluaPool);
148 lua_State *
L = luaL_newstate();
151 static const luaL_Reg lualibs[] = {
153 {
"lsyck", luaopen_syck},
156 #ifdef WITH_LUA_INTERNAL
157 {
"posix", luaopen_posix_c},
158 {
"rex_posix", luaopen_rex_posix},
159 {
"rex_pcre", luaopen_rex_pcre},
160 {
"uuid", luaopen_uuid},
162 {
"wrs", luaopen_wrs},
164 #ifdef USE_LUA_CRYPTO
165 {
"crypto", luaopen_crypto},
166 {
"lxp", luaopen_lxp},
168 #ifdef USE_LUA_SOCKET
169 {
"socket", luaopen_socket_core},
171 {
"local", luaopen_local},
173 {
"rpm", luaopen_rpm},
178 const luaL_Reg *lib = lualibs;
187 lua->printbufsize = 0;
188 lua->printbufused = 0;
189 lua->printbuf = NULL;
193 for (; lib->name; lib++) {
194 luaL_requiref(L, lib->name, lib->func, 1);
198 if (_lua_path != NULL) {
199 lua_pushliteral(L,
"LUA_PATH");
200 lua_pushstring(L, _lua_path);
201 _lua_path =
_free(_lua_path);
205 #if defined(LUA_GLOBALSINDEX)
206 lua_rawset(L, LUA_GLOBALSINDEX);
208 lua_pushglobaltable(L);
210 lua_pushcfunction(L, rpm_print);
211 lua_setglobal(L,
"print");
213 #if defined(LUA_GLOBALSINDEX)
214 lua_rawset(L, LUA_GLOBALSINDEX);
216 lua_pushglobaltable(L);
222 for (path = path_buf; path != NULL && *path !=
'\0'; path = path_next) {
228 path_next = strchr(path,
':');
229 if (path_next != NULL && *path_next ==
':')
232 path_next = path + strlen(path);
237 if ((i =
rpmGlob(path, &ac, &av)) != 0)
241 for (i = 0; i < ac; i++) {
242 const char *fn = av[
i];
245 #if defined(RPM_VENDOR_OPENPKG) || \
246 !defined(POPT_ERROR_BADCONFIG)
249 if (!poptSaneFile(fn))
252 rpmlog(
RPMLOG_WARNING,
"existing RPM Lua script file \"%s\" considered INSECURE -- not loaded\n", fn);
256 if (
Stat(fn, &st) != -1)
262 path_buf =
_free(path_buf);
270 INITSTATE(_lua, lua);
271 lua_State *L = lua->L;
272 lua_pushliteral(L,
"rpm_");
273 lua_pushstring(L, key);
278 lua_pushlightuserdata(L, (
void *)data);
279 lua_rawset(L, LUA_REGISTRYINDEX);
283 static void *getdata(lua_State *L,
const char *key)
287 lua_pushliteral(L,
"rpm_");
288 lua_pushstring(L, key);
290 lua_rawget(L, LUA_REGISTRYINDEX);
291 if (lua_islightuserdata(L, -1))
292 ret = lua_touserdata(L, -1);
299 INITSTATE(_lua, lua);
300 return getdata(lua->L, key);
305 INITSTATE(_lua, lua);
306 lua->storeprint = flag;
307 lua->printbuf =
_free(lua->printbuf);
308 lua->printbufsize = 0;
309 lua->printbufused = 0;
314 INITSTATE(_lua, lua);
315 return lua->printbuf;
327 lua_pushstring(L, *((
char **)value));
330 lua_pushnumber(L, *((
double *)value));
341 INITSTATE(_lua, lua);
342 lua_State *L = lua->L;
343 if (var->listmode && lua->pushsize > 0) {
344 if (var->keyType !=
RPMLUAV_NUMBER || var->key.num == (
double)0) {
346 var->key.num = (double) lua_rawlen(L, -1);
350 if (!var->listmode || lua->pushsize > 0) {
351 #if defined(LUA_GLOBALSINDEX)
352 if (lua->pushsize == 0)
353 lua_pushvalue(L, LUA_GLOBALSINDEX);
355 if (pushvar(L, var->keyType, &var->key) != -1) {
356 if (pushvar(L, var->valueType, &var->value) != -1)
361 if (lua->pushsize == 0)
366 static void popvar(lua_State *L,
rpmluavType *type,
void *value)
369 switch (lua_type(L, -1)) {
373 *((
const char **)value) = lua_tostring(L, -1);
378 *((
double *)value) = lua_tonumber(L, -1);
382 *((
void **)value) = NULL;
390 INITSTATE(_lua, lua);
391 lua_State *L = lua->L;
392 if (!var->listmode) {
393 #if defined(LUA_GLOBALSINDEX)
394 if (lua->pushsize == 0)
395 lua_pushvalue(L, LUA_GLOBALSINDEX);
397 if (lua->pushsize == 0)
398 lua_pushglobaltable(L);
400 if (pushvar(L, var->keyType, &var->key) != -1) {
402 popvar(L, &var->valueType, &var->value);
404 if (lua->pushsize == 0)
406 }
else if (lua->pushsize > 0) {
407 (void) pushvar(L, var->keyType, &var->key);
408 if (lua_next(L, -2) != 0)
409 popvar(L, &var->valueType, &var->value);
413 #define FINDKEY_RETURN 0
414 #define FINDKEY_CREATE 1
415 #define FINDKEY_REMOVE 2
416 static int findkey(lua_State *L,
int oper,
const char *key, va_list va)
424 #if defined(LUA_GLOBALSINDEX)
425 lua_pushvalue(L, LUA_GLOBALSINDEX);
427 lua_pushglobaltable(L);
430 if (*e ==
'\0' || *e ==
'.') {
432 lua_pushlstring(L, s, e-s);
448 if (!lua_istable(L, -1)) {
451 lua_pushlstring(L, s, e-s);
452 lua_pushvalue(L, -2);
461 if (!lua_istable(L, -1)) {
476 INITSTATE(_lua, lua);
479 (void) findkey(lua->L, FINDKEY_REMOVE, key, va);
485 INITSTATE(_lua, lua);
486 lua_State *L = lua->L;
490 if (findkey(L, FINDKEY_RETURN, key, va) == 0) {
491 if (!lua_isnil(L, -1))
501 INITSTATE(_lua, lua);
504 (void) findkey(lua->L, FINDKEY_CREATE, key, va);
511 INITSTATE(_lua, lua);
512 assert(lua->pushsize > 0);
529 if (_rpmluavPool == NULL) {
539 rpmluav var = rpmluavGetPool(_rpmluavPool);
543 var->value.ptr = NULL;
550 var->listmode = flag;
560 var->key.num = *((
double *)value);
563 var->key.str = (
char *)value;
573 var->valueType =
type;
577 var->value.num = *((
const double *)value);
580 var->value.str = (
const char *)value;
590 *type = var->keyType;
592 switch (var->keyType) {
594 *((
double **)value) = &var->key.num;
597 *((
const char **)value) = var->key.str;
607 *type = var->valueType;
609 switch (var->valueType) {
611 *((
double **)value) = &var->value.num;
614 *((
const char **)value) = var->value.str;
638 return *((
double *)value);
648 return *((
double *)value);
664 INITSTATE(_lua, lua);
665 lua_State *L = lua->L;
669 if (luaL_loadbuffer(L, script, strlen(script), name) != 0) {
671 _(
"invalid syntax in Lua scriptlet: %s\n"),
672 lua_tostring(L, -1));
681 INITSTATE(_lua, lua);
682 lua_State *L = lua->L;
686 if (luaL_loadbuffer(L, script, strlen(script), name) != 0) {
688 lua_tostring(L, -1));
691 }
else if (lua_pcall(L, 0, 0, 0) != 0) {
693 lua_tostring(L, -1));
702 INITSTATE(_lua, lua);
703 lua_State *L = lua->L;
705 if (luaL_loadfile(L, filename) != 0) {
707 lua_tostring(L, -1));
710 }
else if (lua_pcall(L, 0, 0, 0) != 0) {
712 lua_tostring(L, -1));
720 static int rpmluaReadline(lua_State *L,
const char *prompt)
726 (void) fputs(prompt, stdout);
727 (void) fflush(stdout);
729 if (fgets(buffer, (
int)
sizeof(
buffer), stdin) == NULL) {
732 lua_pushstring(L, buffer);
738 static void _rpmluaInteractive(lua_State *L)
742 (void) fputs(
"\n", stdout);
743 printf(
"RPM Interactive %s Interpreter\n", LUA_VERSION);
747 if (rpmluaReadline(L,
"> ") == 0)
749 if (lua_tostring(L, -1)[0] ==
'=') {
751 (void) lua_pushfstring(L,
"print(%s)", lua_tostring(L, -1)+1);
757 rc = luaL_loadbuffer(L, lua_tostring(L, -1),
758 lua_rawlen(L, -1),
"<lua>");
760 if (rc == LUA_ERRSYNTAX &&
761 strstr(lua_tostring(L, -1),
"near `<eof>'") != NULL) {
762 if (rpmluaReadline(L,
">> ") == 0)
771 rc = lua_pcall(L, 0, 0, 0);
774 fprintf(stderr,
"%s\n", lua_tostring(L, -1));
780 (void) fputs(
"\n", stdout);
786 INITSTATE(_lua, lua);
787 _rpmluaInteractive(lua->L);
794 static int rpm_macros(lua_State *L)
797 const char ** av = NULL;
810 for (i = 0; i < ac; i++) {
817 o = ((b > n && b[-1] ==
')') ? strchr(n,
'(') : NULL);
819 if (o != NULL && *o ==
'(') {
829 lua_pushstring(L, n);
832 lua_pushstring(L,
"opts");
833 lua_pushstring(L, o);
837 lua_pushstring(L,
"body");
838 lua_pushstring(L, b);
848 static int rpm_expand(lua_State *L)
852 const char *
str = luaL_checkstring(L, 1);
857 static int rpm_define(lua_State *L)
861 const char *str = luaL_checkstring(L, 1);
866 static int rpm_undefine(lua_State *L)
870 const char *str = luaL_checkstring(L, 1);
875 static int rpm_interactive(lua_State *L)
879 _rpmluaInteractive(L);
883 typedef struct rpmluaHookData_s {
890 static int rpmluaHookWrapper(
rpmhookArgs args,
void *data)
893 rpmluaHookData hookdata = (rpmluaHookData)data;
894 lua_State *L = hookdata->L;
897 lua_rawgeti(L, LUA_REGISTRYINDEX, hookdata->funcRef);
899 for (i = 0; i != args->
argc; i++) {
900 switch (args->
argt[i]) {
902 lua_pushstring(L, args->
argv[i].
s);
903 lua_rawseti(L, -2, i+1);
906 lua_pushnumber(L, (lua_Number)args->
argv[i].
i);
907 lua_rawseti(L, -2, i+1);
910 lua_pushnumber(L, (lua_Number)args->
argv[i].
f);
911 lua_rawseti(L, -2, i+1);
914 lua_pushlightuserdata(L, args->
argv[i].
p);
915 lua_rawseti(L, -2, i+1);
918 (void) luaL_error(L,
"unsupported type '%c' as "
919 "a hook argument\n", args->
argt[i]);
923 if (lua_pcall(L, 1, 1, 0) != 0) {
925 lua_tostring(L, -1));
928 if (lua_isnumber(L, -1))
929 ret = (int)lua_tonumber(L, -1);
935 static int rpm_register(lua_State *L)
939 if (!lua_isstring(L, 1)) {
940 (void) luaL_argerror(L, 1,
"hook name expected");
941 }
else if (!lua_isfunction(L, 2)) {
942 (void) luaL_argerror(L, 2,
"function expected");
944 rpmluaHookData hookdata = (rpmluaHookData)
945 lua_newuserdata(L,
sizeof(
struct rpmluaHookData_s));
946 lua_pushvalue(L, -1);
947 hookdata->dataRef = luaL_ref(L, LUA_REGISTRYINDEX);
949 hookdata->funcRef = luaL_ref(L, LUA_REGISTRYINDEX);
959 static int rpm_unregister(lua_State *L)
962 if (!lua_isstring(L, 1)) {
963 (void) luaL_argerror(L, 1,
"hook name expected");
964 }
else if (!lua_islightuserdata(L, 2)) {
965 (void) luaL_argerror(L, 2,
"hook information expected");
967 rpmluaHookData hookdata = (rpmluaHookData)lua_touserdata(L, 2);
968 luaL_unref(L, LUA_REGISTRYINDEX, hookdata->funcRef);
969 luaL_unref(L, LUA_REGISTRYINDEX, hookdata->dataRef);
975 static int rpm_call(lua_State *L)
979 if (!lua_isstring(L, 1)) {
980 (void) luaL_argerror(L, 1,
"hook name expected");
983 const char *name = lua_tostring(L, 1);
986 for (i = 0; i != args->
argc; i++) {
987 switch (lua_type(L, i+1)) {
993 float f = (float)lua_tonumber(L, i+1);
1006 args->
argv[
i].
s = lua_tostring(L, i+1);
1009 case LUA_TLIGHTUSERDATA:
1011 args->
argv[
i].
p = lua_touserdata(L, i+1);
1014 (void) luaL_error(L,
"unsupported Lua type passed to hook");
1031 static int rpm_print (lua_State *L)
1036 int n = lua_gettop(L);
1039 lua_getglobal(L,
"tostring");
1040 for (i = 1; i <= n; i++) {
1042 lua_pushvalue(L, -1);
1043 lua_pushvalue(L, i);
1045 s = lua_tostring(L, -1);
1047 return luaL_error(L,
"`tostring' must return a string to `print'");
1048 if (lua->storeprint) {
1049 size_t sl = lua_rawlen(L, -1);
1050 if ((
size_t)(lua->printbufused+sl+1) > lua->printbufsize) {
1051 lua->printbufsize += sl+512;
1052 lua->printbuf = (
char *)
xrealloc(lua->printbuf, lua->printbufsize);
1055 lua->printbuf[lua->printbufused++] =
'\t';
1056 memcpy(lua->printbuf+lua->printbufused, s, sl+1);
1057 lua->printbufused += sl;
1060 (void) fputs(
"\t", stdout);
1061 (void) fputs(s, stdout);
1065 if (!lua->storeprint) {
1066 (void) fputs(
"\n", stdout);
1068 if ((
size_t)(lua->printbufused+1) > lua->printbufsize) {
1069 lua->printbufsize += 512;
1070 lua->printbuf = (
char *)
xrealloc(lua->printbuf, lua->printbufsize);
1072 lua->printbuf[lua->printbufused] =
'\0';
1077 static int rpm_source(lua_State *L)
1081 if (!lua_isstring(L, 1)) {
1082 (void)luaL_argerror(L, 1,
"filename expected");
1085 const char *filename = lua_tostring(L, 1);
1092 static int rpm_load(lua_State *L)
1096 if (!lua_isstring(L, 1)) {
1097 (void)luaL_argerror(L, 1,
"filename expected");
1099 const char *filename = lua_tostring(L, 1);
1107 static int rpm_verbose(lua_State *L)
1115 static int rpm_debug(lua_State *L)
1123 static int rpm_slurp(lua_State *L)
1131 if (lua_isstring(L, 1))
1132 fn = lua_tostring(L, 1);
1134 (void)luaL_argerror(L, 1,
"filename");
1140 if (rc || iob == NULL) {
1141 (void)luaL_error(L,
"failed to slurp data");
1149 static int rpm_sleep(lua_State *L)
1155 if (lua_isnumber(L, 1))
1156 sec = (unsigned) lua_tonumber(L, 1);
1158 (void)luaL_argerror(L, 1,
"seconds");
1165 static int rpm_realpath(lua_State *L)
1171 char *rp = (
char *)
"";
1173 if (lua_isstring(L, 1))
1174 pn = lua_tostring(L, 1);
1176 (void)luaL_argerror(L, 1,
"pathname");
1179 if ((rp =
Realpath(pn, rp_buf)) == NULL) {
1180 (void)luaL_error(L,
"failed to resolve path via realpath(3): %s", strerror(
errno));
1183 lua_pushstring(L, (
const char *)rp);
1187 static int rpm_hostname(lua_State *L)
1191 char hostname[1024];
1192 struct hostent *hbn;
1196 (void)gethostname(hostname,
sizeof(hostname));
1197 if ((hbn = gethostbyname(hostname)) != NULL)
1202 lua_pushstring(L, (
const char *)h);
1208 static const luaL_Reg rpmlib[] = {
1209 {
"macros", rpm_macros},
1210 {
"expand", rpm_expand},
1211 {
"define", rpm_define},
1212 {
"undefine", rpm_undefine},
1213 {
"register", rpm_register},
1214 {
"unregister", rpm_unregister},
1216 {
"interactive", rpm_interactive},
1217 {
"source", rpm_source},
1219 {
"verbose", rpm_verbose},
1220 {
"debug", rpm_debug},
1221 {
"slurp", rpm_slurp},
1222 {
"sleep", rpm_sleep},
1223 {
"realpath", rpm_realpath},
1224 {
"hostname", rpm_hostname},
1229 static int luaopen_rpm(lua_State *L)
1232 #if defined(LUA_GLOBALSINDEX)
1233 lua_pushvalue(L, LUA_GLOBALSINDEX);
1235 lua_pushglobaltable(L);
1237 luaL_newlib(L, rpmlib);
void rpmluavGetKey(rpmluav var, rpmluavType *type, void **value)
int rpmluaCheckScript(rpmlua _lua, const char *script, const char *name)
rpmhookArgs rpmhookArgsNew(int argc)
rpmhookArgs rpmhookArgsFree(rpmhookArgs args)
enum rpmluavType_e rpmluavType
void rpmluavSetValueNum(rpmluav var, double value)
char * xstrdup(const char *str)
size_t rpmiobLen(rpmiob iob)
Return I/O buffer len.
void * rpmluavFree(rpmluav var)
char * rpmGetPath(const char *path,...)
Return (malloc'ed) expanded, canonicalized, file path.
void rpmluaSetPrintBuffer(rpmlua _lua, int flag)
void rpmluaGetVar(rpmlua _lua, rpmluav var)
void rpmluavSetListMode(rpmluav var, int flag)
rpmioItem rpmioLinkPoolItem(rpmioItem item, const char *msg, const char *fn, unsigned ln)
Increment a pool item refcount.
void rpmhookUnregister(const char *name, rpmhookFunc func, void *data)
void rpmluavSetKey(rpmluav var, rpmluavType type, const void *value)
rpmlua rpmluaGetGlobalState(void)
int Stat(const char *path, struct stat *st)
stat(2) clone.
void * rpmioFreePoolItem(rpmioItem item, const char *msg, const char *fn, unsigned ln)
Free a pool item.
void * rpmluaGetData(rpmlua _lua, const char *key)
rpmiob rpmiobFree(rpmiob iob)
Destroy a I/O buffer instance.
double rpmluavGetValueNum(rpmluav var)
static void rpmlog(int code, const char *fmt,...)
void rpmluavSetKeyNum(rpmluav var, double value)
void rpmluaPushTable(rpmlua _lua, const char *key,...)
void rpmluavSetValue(rpmluav var, rpmluavType type, const void *value)
int rpmiobSlurp(const char *fn, rpmiob *iobp)
void rpmluaPop(rpmlua _lua)
Yet Another syslog(3) API clone.
int rpmGlob(const char *patterns, int *argcPtr, const char ***argvPtr)
Return URL path(s) from a (URL prefixed) pattern glob.
double rpmluavGetKeyNum(rpmluav var)
rpmioItem rpmioGetPool(rpmioPool pool, size_t size)
Get unused item from pool, or alloc a new item.
int rpmGetMacroEntries(MacroContext mc, void *_mire, int used, const char ***avp)
Return macro entries as string array.
const char const bson * data
ARGV_t argvFree(ARGV_t argv)
Destroy an argv array.
struct rpmluav_s * rpmluav
const char * rpmluaGetPrintBuffer(rpmlua _lua)
int rpmDefineMacro(MacroContext mc, const char *macro, int level)
Define macro in context.
void * rpmluaFree(rpmlua lua)
char * rpmExpand(const char *arg,...)
Return (malloc'ed) concatenated macro expansion(s).
void rpmluaInteractive(rpmlua _lua)
void rpmluaDelVar(rpmlua _lua, const char *key,...)
void rpmluaSetData(rpmlua _lua, const char *key, const void *data)
char * rpmiobStr(rpmiob iob)
Return I/O buffer (as string).
const char const bson * key
static int vsnprintf(char *buf, int nb, const char *fmt, va_list ap)
rpmioPool rpmioNewPool(const char *name, size_t size, int limit, int flags, char *(*dbg)(void *item), void(*init)(void *item), void(*fini)(void *item))
Create a memory pool.
int rpmluaVarExists(rpmlua _lua, const char *key,...)
void rpmluaSetVar(rpmlua _lua, rpmluav var)
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
int rpmluavKeyIsNum(rpmluav var)
int rpmSecuritySaneFile(const char *filename)
Check whether configuration file is moderately secure to load.
int rpmluavValueIsNum(rpmluav var)
void rpmhookRegister(const char *name, rpmhookFunc func, void *data)
void rpmhookCallArgs(const char *name, rpmhookArgs args)
int rpmluaRunScriptFile(rpmlua _lua, const char *filename)
void rpmluavGetValue(rpmluav var, rpmluavType *type, void **value)
int rpmLoadMacroFile(MacroContext mc, const char *fn, int nesting)
Load macro context from a macro file.
char * Realpath(const char *path, char *resolved_path)
realpath(3) clone.
int rpmluaRunScript(rpmlua _lua, const char *script, const char *name)
int rpmUndefineMacro(MacroContext mc, const char *macro)
Undefine macro in context.