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 > 501
70 #define luaL_reg luaL_Reg
71 #define lua_strlen lua_rawlen
72 #define luaL_getn luaL_len
73 static int luaL_typerror(lua_State *
L,
int narg,
const char *tname)
75 const char *msg = lua_pushfstring(L,
"%s expected, got %s",
76 tname, luaL_typename(L, narg));
77 return luaL_argerror(L, narg, msg);
79 LUALIB_API
void luaL_openlib (lua_State *
L,
const char *libname,
80 const luaL_Reg *l,
int nup);
81 #define luaopen_posix luaopen_posix_c
83 #define lua_open() luaL_newstate()
86 #if !defined(HAVE_VSNPRINTF)
87 static inline int vsnprintf(
char * buf,
size_t nb,
88 const char * fmt, va_list ap)
90 return vsprintf(buf, fmt, ap);
94 #define INITSTATE(_lua, lua) \
95 rpmlua lua = _lua ? _lua : \
96 (globalLuaState ? globalLuaState : \
98 (globalLuaState = rpmluaNew()) \
103 static rpmlua globalLuaState;
105 static int luaopen_rpm(lua_State *
L)
107 static int rpm_print(lua_State *
L)
120 return globalLuaState;
124 static void rpmluaFini(
void * _lua)
130 if (lua->L) lua_close(lua->L);
132 lua->printbuf =
_free(lua->printbuf);
141 if (_rpmluaPool == NULL) {
143 NULL, NULL, rpmluaFini);
151 if (lua == NULL) lua = globalLuaState;
153 if (lua == globalLuaState) globalLuaState = NULL;
160 rpmlua lua = rpmluaGetPool(_rpmluaPool);
161 lua_State *
L = lua_open();
164 static const luaL_reg lualibs[] = {
168 #if defined(LUA_COLIBNAME) && LUA_VERSION_NUM > 501
169 {LUA_COLIBNAME, luaopen_coroutine},
171 #if defined(LUA_TABLIBNAME)
172 {LUA_TABLIBNAME, luaopen_table},
174 #if defined(LUA_IOLIBNAME)
175 {LUA_IOLIBNAME, luaopen_io},
177 #if defined(LUA_OSLIBNAME)
178 {LUA_OSLIBNAME, luaopen_os},
180 #if defined(LUA_STRLIBNAME)
181 {LUA_STRLIBNAME, luaopen_string},
183 #if defined(LUA_BITLIBNAME)
184 {LUA_BITLIBNAME, luaopen_bit32},
186 #if defined(LUA_MATHLIBNAME)
187 {LUA_MATHLIBNAME, luaopen_math},
189 #if defined(LUA_DBLIBNAME)
190 {LUA_DBLIBNAME, luaopen_debug},
192 #if defined(LUA_LOADLIBNAME)
193 {LUA_LOADLIBNAME, luaopen_package},
196 {
"lsyck", luaopen_syck},
199 #ifdef WITH_LUA_INTERNAL
200 {
"posix", luaopen_posix},
201 {
"rex_posix", luaopen_rex_posix},
202 {
"rex_pcre", luaopen_rex_pcre},
203 {
"uuid", luaopen_uuid},
204 {
"wrs", luaopen_wrs},
205 #ifdef USE_LUA_CRYPTO
206 {
"crypto", luaopen_crypto},
207 {
"lxp", luaopen_lxp},
209 #ifdef USE_LUA_SOCKET
210 {
"socket", luaopen_socket_core},
212 {
"local", luaopen_local},
214 {
"rpm", luaopen_rpm},
219 const luaL_reg *lib = lualibs;
228 lua->printbufsize = 0;
229 lua->printbufused = 0;
230 lua->printbuf = NULL;
232 for (; lib->name; lib++) {
234 lua_pushcfunction(L, lib->func);
235 lua_pushstring(L, lib->name);
239 {
const char * _lua_path =
rpmGetPath(rpmluaPath, NULL);
240 if (_lua_path != NULL) {
241 lua_pushliteral(L,
"LUA_PATH");
242 lua_pushstring(L, _lua_path);
243 _lua_path =
_free(_lua_path);
246 #if defined(LUA_GLOBALSINDEX)
247 lua_rawset(L, LUA_GLOBALSINDEX);
249 lua_pushglobaltable(L);
251 lua_pushliteral(L,
"print");
252 lua_pushcfunction(L, rpm_print);
253 #if defined(LUA_GLOBALSINDEX)
254 lua_rawset(L, LUA_GLOBALSINDEX);
256 lua_pushglobaltable(L);
261 path_buf =
xstrdup(rpmluaFiles);
262 for (path = path_buf; path != NULL && *path !=
'\0'; path = path_next) {
268 path_next = strchr(path,
':');
269 if (path_next != NULL && *path_next ==
':')
272 path_next = path + strlen(path);
277 if ((i =
rpmGlob(path, &ac, &av)) != 0)
281 for (i = 0; i < ac; i++) {
282 const char *fn = av[i];
285 #if defined(RPM_VENDOR_OPENPKG) || \
286 !defined(POPT_ERROR_BADCONFIG)
289 if (!poptSaneFile(fn))
292 rpmlog(
RPMLOG_WARNING,
"existing RPM Lua script file \"%s\" considered INSECURE -- not loaded\n", fn);
296 if (
Stat(fn, &st) != -1)
298 av[i] =
_free(av[i]);
302 path_buf =
_free(path_buf);
310 INITSTATE(_lua, lua);
311 lua_State *L = lua->L;
312 lua_pushliteral(L,
"rpm_");
313 lua_pushstring(L, key);
318 lua_pushlightuserdata(L, (
void *)data);
319 lua_rawset(L, LUA_REGISTRYINDEX);
323 static void *getdata(lua_State *L,
const char *key)
327 lua_pushliteral(L,
"rpm_");
328 lua_pushstring(L, key);
330 lua_rawget(L, LUA_REGISTRYINDEX);
331 if (lua_islightuserdata(L, -1))
332 ret = lua_touserdata(L, -1);
339 INITSTATE(_lua, lua);
340 return getdata(lua->L, key);
345 INITSTATE(_lua, lua);
346 lua->storeprint = flag;
347 lua->printbuf =
_free(lua->printbuf);
348 lua->printbufsize = 0;
349 lua->printbufused = 0;
354 INITSTATE(_lua, lua);
355 return lua->printbuf;
358 static int pushvar(lua_State *L,
rpmluavType type,
void *value)
367 lua_pushstring(L, *((
char **)value));
370 lua_pushnumber(L, *((
double *)value));
381 INITSTATE(_lua, lua);
382 lua_State *L = lua->L;
383 if (var->listmode && lua->pushsize > 0) {
384 if (var->keyType !=
RPMLUAV_NUMBER || var->key.num == (
double)0) {
386 var->key.num = (double) luaL_getn(L, -1);
390 if (!var->listmode || lua->pushsize > 0) {
391 #if defined(LUA_GLOBALSINDEX)
392 if (lua->pushsize == 0)
393 lua_pushvalue(L, LUA_GLOBALSINDEX);
395 if (pushvar(L, var->keyType, &var->key) != -1) {
396 if (pushvar(L, var->valueType, &var->value) != -1)
401 if (lua->pushsize == 0)
406 static void popvar(lua_State *L,
rpmluavType *type,
void *value)
409 switch (lua_type(L, -1)) {
413 *((
const char **)value) = lua_tostring(L, -1);
418 *((
double *)value) = lua_tonumber(L, -1);
422 *((
void **)value) = NULL;
430 INITSTATE(_lua, lua);
431 lua_State *L = lua->L;
432 if (!var->listmode) {
433 #if defined(LUA_GLOBALSINDEX)
434 if (lua->pushsize == 0)
435 lua_pushvalue(L, LUA_GLOBALSINDEX);
437 if (lua->pushsize == 0)
438 lua_pushglobaltable(L);
440 if (pushvar(L, var->keyType, &var->key) != -1) {
442 popvar(L, &var->valueType, &var->value);
444 if (lua->pushsize == 0)
446 }
else if (lua->pushsize > 0) {
447 (void) pushvar(L, var->keyType, &var->key);
448 if (lua_next(L, -2) != 0)
449 popvar(L, &var->valueType, &var->value);
453 #define FINDKEY_RETURN 0
454 #define FINDKEY_CREATE 1
455 #define FINDKEY_REMOVE 2
456 static int findkey(lua_State *L,
int oper,
const char *key, va_list va)
462 (void)
vsnprintf(buf,
sizeof(buf), key, va);
464 #if defined(LUA_GLOBALSINDEX)
465 lua_pushvalue(L, LUA_GLOBALSINDEX);
467 lua_pushglobaltable(L);
470 if (*e ==
'\0' || *e ==
'.') {
472 lua_pushlstring(L, s, e-s);
488 if (!lua_istable(L, -1)) {
491 lua_pushlstring(L, s, e-s);
492 lua_pushvalue(L, -2);
501 if (!lua_istable(L, -1)) {
516 INITSTATE(_lua, lua);
519 (void) findkey(lua->L, FINDKEY_REMOVE, key, va);
525 INITSTATE(_lua, lua);
526 lua_State *L = lua->L;
530 if (findkey(L, FINDKEY_RETURN, key, va) == 0) {
531 if (!lua_isnil(L, -1))
541 INITSTATE(_lua, lua);
544 (void) findkey(lua->L, FINDKEY_CREATE, key, va);
549 void rpmluaPop(
rpmlua _lua)
551 INITSTATE(_lua, lua);
552 assert(lua->pushsize > 0);
569 if (_rpmluavPool == NULL) {
579 rpmluav var = rpmluavGetPool(_rpmluavPool);
583 var->value.ptr = NULL;
590 var->listmode = flag;
600 var->key.num = *((
double *)value);
603 var->key.str = (
char *)value;
613 var->valueType = type;
617 var->value.num = *((
const double *)value);
620 var->value.str = (
const char *)value;
630 *type = var->keyType;
632 switch (var->keyType) {
634 *((
double **)value) = &var->key.num;
637 *((
const char **)value) = var->key.str;
647 *type = var->valueType;
649 switch (var->valueType) {
651 *((
double **)value) = &var->value.num;
654 *((
const char **)value) = var->value.str;
678 return *((
double *)value);
688 return *((
double *)value);
704 INITSTATE(_lua, lua);
705 lua_State *L = lua->L;
709 if (luaL_loadbuffer(L, script, strlen(script), name) != 0) {
711 _(
"invalid syntax in Lua scriptlet: %s\n"),
712 lua_tostring(L, -1));
721 INITSTATE(_lua, lua);
722 lua_State *L = lua->L;
726 if (luaL_loadbuffer(L, script, strlen(script), name) != 0) {
728 lua_tostring(L, -1));
731 }
else if (lua_pcall(L, 0, 0, 0) != 0) {
733 lua_tostring(L, -1));
742 INITSTATE(_lua, lua);
743 lua_State *L = lua->L;
745 if (luaL_loadfile(L, filename) != 0) {
747 lua_tostring(L, -1));
750 }
else if (lua_pcall(L, 0, 0, 0) != 0) {
752 lua_tostring(L, -1));
760 static int rpmluaReadline(lua_State *L,
const char *prompt)
764 static char buffer[1024];
766 (void) fputs(prompt, stdout);
767 (void) fflush(stdout);
769 if (fgets(buffer, (
int)
sizeof(buffer), stdin) == NULL) {
772 lua_pushstring(L, buffer);
778 static void _rpmluaInteractive(lua_State *L)
782 (void) fputs(
"\n", stdout);
783 printf(
"RPM Interactive %s Interpreter\n", LUA_VERSION);
787 if (rpmluaReadline(L,
"> ") == 0)
789 if (lua_tostring(L, -1)[0] ==
'=') {
791 (void) lua_pushfstring(L,
"print(%s)", lua_tostring(L, -1)+1);
797 rc = luaL_loadbuffer(L, lua_tostring(L, -1),
798 lua_strlen(L, -1),
"<lua>");
800 if (rc == LUA_ERRSYNTAX &&
801 strstr(lua_tostring(L, -1),
"near `<eof>'") != NULL) {
802 if (rpmluaReadline(L,
">> ") == 0)
811 rc = lua_pcall(L, 0, 0, 0);
814 fprintf(stderr,
"%s\n", lua_tostring(L, -1));
820 (void) fputs(
"\n", stdout);
826 INITSTATE(_lua, lua);
827 _rpmluaInteractive(lua->L);
834 static int rpm_macros(lua_State *L)
837 const char ** av = NULL;
850 for (i = 0; i < ac; i++) {
857 o = ((b > n && b[-1] ==
')') ? strchr(n,
'(') : NULL);
859 if (o != NULL && *o ==
'(') {
869 lua_pushstring(L, n);
872 lua_pushstring(L,
"opts");
873 lua_pushstring(L, o);
877 lua_pushstring(L,
"body");
878 lua_pushstring(L, b);
888 static int rpm_expand(lua_State *L)
892 const char *str = luaL_checkstring(L, 1);
897 static int rpm_define(lua_State *L)
901 const char *str = luaL_checkstring(L, 1);
906 static int rpm_undefine(lua_State *L)
910 const char *str = luaL_checkstring(L, 1);
915 static int rpm_interactive(lua_State *L)
919 _rpmluaInteractive(L);
923 typedef struct rpmluaHookData_s {
930 static int rpmluaHookWrapper(
rpmhookArgs args,
void *data)
933 rpmluaHookData hookdata = (rpmluaHookData)data;
934 lua_State *L = hookdata->L;
937 lua_rawgeti(L, LUA_REGISTRYINDEX, hookdata->funcRef);
939 for (i = 0; i != args->
argc; i++) {
940 switch (args->
argt[i]) {
942 lua_pushstring(L, args->
argv[i].
s);
943 lua_rawseti(L, -2, i+1);
946 lua_pushnumber(L, (lua_Number)args->
argv[i].
i);
947 lua_rawseti(L, -2, i+1);
950 lua_pushnumber(L, (lua_Number)args->
argv[i].
f);
951 lua_rawseti(L, -2, i+1);
954 lua_pushlightuserdata(L, args->
argv[i].
p);
955 lua_rawseti(L, -2, i+1);
958 (void) luaL_error(L,
"unsupported type '%c' as "
959 "a hook argument\n", args->
argt[i]);
963 if (lua_pcall(L, 1, 1, 0) != 0) {
965 lua_tostring(L, -1));
968 if (lua_isnumber(L, -1))
969 ret = (int)lua_tonumber(L, -1);
975 static int rpm_register(lua_State *L)
979 if (!lua_isstring(L, 1)) {
980 (void) luaL_argerror(L, 1,
"hook name expected");
981 }
else if (!lua_isfunction(L, 2)) {
982 (void) luaL_argerror(L, 2,
"function expected");
984 rpmluaHookData hookdata = (rpmluaHookData)
985 lua_newuserdata(L,
sizeof(
struct rpmluaHookData_s));
986 lua_pushvalue(L, -1);
987 hookdata->dataRef = luaL_ref(L, LUA_REGISTRYINDEX);
989 hookdata->funcRef = luaL_ref(L, LUA_REGISTRYINDEX);
999 static int rpm_unregister(lua_State *L)
1002 if (!lua_isstring(L, 1)) {
1003 (void) luaL_argerror(L, 1,
"hook name expected");
1004 }
else if (!lua_islightuserdata(L, 2)) {
1005 (void) luaL_argerror(L, 2,
"hook information expected");
1007 rpmluaHookData hookdata = (rpmluaHookData)lua_touserdata(L, 2);
1008 luaL_unref(L, LUA_REGISTRYINDEX, hookdata->funcRef);
1009 luaL_unref(L, LUA_REGISTRYINDEX, hookdata->dataRef);
1015 static int rpm_call(lua_State *L)
1019 if (!lua_isstring(L, 1)) {
1020 (void) luaL_argerror(L, 1,
"hook name expected");
1023 const char *name = lua_tostring(L, 1);
1026 for (i = 0; i != args->
argc; i++) {
1027 switch (lua_type(L, i+1)) {
1030 args->
argv[i].
p = NULL;
1033 float f = (float)lua_tonumber(L, i+1);
1037 args->
argv[i].
i = (int)f;
1040 args->
argv[i].
f = f;
1046 args->
argv[i].
s = lua_tostring(L, i+1);
1049 case LUA_TLIGHTUSERDATA:
1051 args->
argv[i].
p = lua_touserdata(L, i+1);
1054 (void) luaL_error(L,
"unsupported Lua type passed to hook");
1056 args->
argv[i].
p = NULL;
1071 static int rpm_print (lua_State *L)
1076 int n = lua_gettop(L);
1079 lua_getglobal(L,
"tostring");
1080 for (i = 1; i <= n; i++) {
1082 lua_pushvalue(L, -1);
1083 lua_pushvalue(L, i);
1085 s = lua_tostring(L, -1);
1087 return luaL_error(L,
"`tostring' must return a string to `print'");
1088 if (lua->storeprint) {
1089 size_t sl = lua_strlen(L, -1);
1090 if ((
size_t)(lua->printbufused+sl+1) > lua->printbufsize) {
1091 lua->printbufsize += sl+512;
1092 lua->printbuf = (
char *)
xrealloc(lua->printbuf, lua->printbufsize);
1095 lua->printbuf[lua->printbufused++] =
'\t';
1096 memcpy(lua->printbuf+lua->printbufused, s, sl+1);
1097 lua->printbufused += sl;
1100 (void) fputs(
"\t", stdout);
1101 (void) fputs(s, stdout);
1105 if (!lua->storeprint) {
1106 (void) fputs(
"\n", stdout);
1108 if ((
size_t)(lua->printbufused+1) > lua->printbufsize) {
1109 lua->printbufsize += 512;
1110 lua->printbuf = (
char *)
xrealloc(lua->printbuf, lua->printbufsize);
1112 lua->printbuf[lua->printbufused] =
'\0';
1117 static int rpm_source(lua_State *L)
1121 if (!lua_isstring(L, 1)) {
1122 (void)luaL_argerror(L, 1,
"filename expected");
1125 const char *filename = lua_tostring(L, 1);
1132 static int rpm_load(lua_State *L)
1136 if (!lua_isstring(L, 1)) {
1137 (void)luaL_argerror(L, 1,
"filename expected");
1139 const char *filename = lua_tostring(L, 1);
1147 static int rpm_verbose(lua_State *L)
1155 static int rpm_debug(lua_State *L)
1163 static int rpm_slurp(lua_State *L)
1171 if (lua_isstring(L, 1))
1172 fn = lua_tostring(L, 1);
1174 (void)luaL_argerror(L, 1,
"filename");
1180 if (rc || iob == NULL) {
1181 (void)luaL_error(L,
"failed to slurp data");
1189 static int rpm_sleep(lua_State *L)
1195 if (lua_isnumber(L, 1))
1196 sec = (unsigned) lua_tonumber(L, 1);
1198 (void)luaL_argerror(L, 1,
"seconds");
1205 static int rpm_realpath(lua_State *L)
1211 char *rp = (
char *)
"";
1213 if (lua_isstring(L, 1))
1214 pn = lua_tostring(L, 1);
1216 (void)luaL_argerror(L, 1,
"pathname");
1219 if ((rp =
Realpath(pn, rp_buf)) == NULL) {
1220 (void)luaL_error(L,
"failed to resolve path via realpath(3): %s", strerror(errno));
1223 lua_pushstring(L, (
const char *)rp);
1227 static int rpm_hostname(lua_State *L)
1231 char hostname[1024];
1232 struct hostent *hbn;
1236 (void)gethostname(hostname,
sizeof(hostname));
1237 if ((hbn = gethostbyname(hostname)) != NULL)
1242 lua_pushstring(L, (
const char *)h);
1248 static const luaL_reg rpmlib[] = {
1249 {
"macros", rpm_macros},
1250 {
"expand", rpm_expand},
1251 {
"define", rpm_define},
1252 {
"undefine", rpm_undefine},
1253 {
"register", rpm_register},
1254 {
"unregister", rpm_unregister},
1256 {
"interactive", rpm_interactive},
1257 {
"source", rpm_source},
1259 {
"verbose", rpm_verbose},
1260 {
"debug", rpm_debug},
1261 {
"slurp", rpm_slurp},
1262 {
"sleep", rpm_sleep},
1263 {
"realpath", rpm_realpath},
1264 {
"hostname", rpm_hostname},
1269 static int luaopen_rpm(lua_State *L)
1272 #if defined(LUA_GLOBALSINDEX)
1273 lua_pushvalue(L, LUA_GLOBALSINDEX);
1275 lua_pushglobaltable(L);
1277 luaL_openlib(L,
"rpm", rpmlib, 0);