5 #define _RPMIOB_INTERNAL
20 LUALIB_API
int luaopen_syck(lua_State *
L)
23 #ifdef WITH_LUA_INTERNAL
34 #include <luasocket.h>
41 #define _RPMLUA_INTERNAL
63 #if !defined(HAVE_VSNPRINTF)
64 static inline int vsnprintf(
char * buf,
size_t nb,
65 const char * fmt, va_list ap)
67 return vsprintf(buf, fmt, ap);
71 #define INITSTATE(_lua, lua) \
72 rpmlua lua = _lua ? _lua : \
73 (globalLuaState ? globalLuaState : \
75 (globalLuaState = rpmluaNew()) \
80 static rpmlua globalLuaState;
82 static int luaopen_rpm(lua_State *
L)
84 static int rpm_print(lua_State *
L)
97 return globalLuaState;
101 static void rpmluaFini(
void * _lua)
107 if (lua->L) lua_close(lua->L);
109 lua->printbuf =
_free(lua->printbuf);
118 if (_rpmluaPool == NULL) {
120 NULL, NULL, rpmluaFini);
128 if (lua == NULL) lua = globalLuaState;
130 if (lua == globalLuaState) globalLuaState = NULL;
137 rpmlua lua = rpmluaGetPool(_rpmluaPool);
138 lua_State *
L = lua_open();
141 static const luaL_reg lualibs[] = {
144 {LUA_LOADLIBNAME, luaopen_package},
145 {LUA_TABLIBNAME, luaopen_table},
146 {LUA_IOLIBNAME, luaopen_io},
147 {LUA_OSLIBNAME, luaopen_os},
148 {LUA_STRLIBNAME, luaopen_string},
149 {LUA_MATHLIBNAME, luaopen_math},
150 {LUA_DBLIBNAME, luaopen_debug},
152 {
"lsyck", luaopen_syck},
155 #ifdef WITH_LUA_INTERNAL
156 {
"posix", luaopen_posix},
157 {
"rex_posix", luaopen_rex_posix},
158 {
"rex_pcre", luaopen_rex_pcre},
159 {
"uuid", luaopen_uuid},
160 {
"wrs", luaopen_wrs},
161 #ifdef USE_LUA_CRYPTO
162 {
"crypto", luaopen_crypto},
163 {
"lxp", luaopen_lxp},
165 #ifdef USE_LUA_SOCKET
166 {
"socket", luaopen_socket_core},
168 {
"local", luaopen_local},
170 {
"rpm", luaopen_rpm},
175 const luaL_reg *lib = lualibs;
181 for (; lib->name; lib++) {
183 lua_pushcfunction(L, lib->func);
184 lua_pushstring(L, lib->name);
188 {
const char * _lua_path =
rpmGetPath(rpmluaPath, NULL);
189 if (_lua_path != NULL) {
190 lua_pushliteral(L,
"LUA_PATH");
191 lua_pushstring(L, _lua_path);
192 _lua_path =
_free(_lua_path);
195 lua_rawset(L, LUA_GLOBALSINDEX);
196 lua_pushliteral(L,
"print");
197 lua_pushcfunction(L, rpm_print);
198 lua_rawset(L, LUA_GLOBALSINDEX);
202 path_buf =
xstrdup(rpmluaFiles);
203 for (path = path_buf; path != NULL && *path !=
'\0'; path = path_next) {
209 path_next = strchr(path,
':');
210 if (path_next != NULL && *path_next ==
':')
213 path_next = path + strlen(path);
218 if ((i =
rpmGlob(path, &ac, &av)) != 0)
222 for (i = 0; i < ac; i++) {
223 const char *fn = av[i];
226 #if defined(RPM_VENDOR_OPENPKG) || \
227 !defined(POPT_ERROR_BADCONFIG)
230 if (!poptSaneFile(fn))
233 rpmlog(
RPMLOG_WARNING,
"existing RPM Lua script file \"%s\" considered INSECURE -- not loaded\n", fn);
237 if (
Stat(fn, &st) != -1)
239 av[i] =
_free(av[i]);
243 path_buf =
_free(path_buf);
251 INITSTATE(_lua, lua);
252 lua_State *L = lua->L;
253 lua_pushliteral(L,
"rpm_");
254 lua_pushstring(L, key);
259 lua_pushlightuserdata(L, (
void *)data);
260 lua_rawset(L, LUA_REGISTRYINDEX);
264 static void *getdata(lua_State *L,
const char *key)
268 lua_pushliteral(L,
"rpm_");
269 lua_pushstring(L, key);
271 lua_rawget(L, LUA_REGISTRYINDEX);
272 if (lua_islightuserdata(L, -1))
273 ret = lua_touserdata(L, -1);
280 INITSTATE(_lua, lua);
281 return getdata(lua->L, key);
286 INITSTATE(_lua, lua);
287 lua->storeprint = flag;
288 lua->printbuf =
_free(lua->printbuf);
289 lua->printbufsize = 0;
290 lua->printbufused = 0;
295 INITSTATE(_lua, lua);
296 return lua->printbuf;
299 static int pushvar(lua_State *L,
rpmluavType type,
void *value)
308 lua_pushstring(L, *((
char **)value));
311 lua_pushnumber(L, *((
double *)value));
322 INITSTATE(_lua, lua);
323 lua_State *L = lua->L;
324 if (var->listmode && lua->pushsize > 0) {
325 if (var->keyType !=
RPMLUAV_NUMBER || var->key.num == (
double)0) {
327 var->key.num = (double) luaL_getn(L, -1);
331 if (!var->listmode || lua->pushsize > 0) {
332 if (lua->pushsize == 0)
333 lua_pushvalue(L, LUA_GLOBALSINDEX);
334 if (pushvar(L, var->keyType, &var->key) != -1) {
335 if (pushvar(L, var->valueType, &var->value) != -1)
340 if (lua->pushsize == 0)
345 static void popvar(lua_State *L,
rpmluavType *type,
void *value)
348 switch (lua_type(L, -1)) {
352 *((
const char **)value) = lua_tostring(L, -1);
357 *((
double *)value) = lua_tonumber(L, -1);
361 *((
void **)value) = NULL;
369 INITSTATE(_lua, lua);
370 lua_State *L = lua->L;
371 if (!var->listmode) {
372 if (lua->pushsize == 0)
373 lua_pushvalue(L, LUA_GLOBALSINDEX);
374 if (pushvar(L, var->keyType, &var->key) != -1) {
376 popvar(L, &var->valueType, &var->value);
378 if (lua->pushsize == 0)
380 }
else if (lua->pushsize > 0) {
381 (void) pushvar(L, var->keyType, &var->key);
382 if (lua_next(L, -2) != 0)
383 popvar(L, &var->valueType, &var->value);
387 #define FINDKEY_RETURN 0
388 #define FINDKEY_CREATE 1
389 #define FINDKEY_REMOVE 2
390 static int findkey(lua_State *L,
int oper,
const char *key, va_list va)
396 (void)
vsnprintf(buf,
sizeof(buf), key, va);
398 lua_pushvalue(L, LUA_GLOBALSINDEX);
400 if (*e ==
'\0' || *e ==
'.') {
402 lua_pushlstring(L, s, e-s);
418 if (!lua_istable(L, -1)) {
421 lua_pushlstring(L, s, e-s);
422 lua_pushvalue(L, -2);
431 if (!lua_istable(L, -1)) {
446 INITSTATE(_lua, lua);
449 (void) findkey(lua->L, FINDKEY_REMOVE, key, va);
455 INITSTATE(_lua, lua);
456 lua_State *L = lua->L;
460 if (findkey(L, FINDKEY_RETURN, key, va) == 0) {
461 if (!lua_isnil(L, -1))
471 INITSTATE(_lua, lua);
474 (void) findkey(lua->L, FINDKEY_CREATE, key, va);
481 INITSTATE(_lua, lua);
482 assert(lua->pushsize > 0);
499 if (_rpmluavPool == NULL) {
509 rpmluav var = rpmluavGetPool(_rpmluavPool);
515 var->listmode = flag;
525 var->key.num = *((
double *)value);
528 var->key.str = (
char *)value;
538 var->valueType = type;
542 var->value.num = *((
const double *)value);
545 var->value.str = (
const char *)value;
555 *type = var->keyType;
557 switch (var->keyType) {
559 *((
double **)value) = &var->key.num;
562 *((
const char **)value) = var->key.str;
572 *type = var->valueType;
574 switch (var->valueType) {
576 *((
double **)value) = &var->value.num;
579 *((
const char **)value) = var->value.str;
603 return *((
double *)value);
613 return *((
double *)value);
629 INITSTATE(_lua, lua);
630 lua_State *L = lua->L;
634 if (luaL_loadbuffer(L, script, strlen(script), name) != 0) {
636 _(
"invalid syntax in Lua scriptlet: %s\n"),
637 lua_tostring(L, -1));
646 INITSTATE(_lua, lua);
647 lua_State *L = lua->L;
651 if (luaL_loadbuffer(L, script, strlen(script), name) != 0) {
653 lua_tostring(L, -1));
656 }
else if (lua_pcall(L, 0, 0, 0) != 0) {
658 lua_tostring(L, -1));
667 INITSTATE(_lua, lua);
668 lua_State *L = lua->L;
670 if (luaL_loadfile(L, filename) != 0) {
672 lua_tostring(L, -1));
675 }
else if (lua_pcall(L, 0, 0, 0) != 0) {
677 lua_tostring(L, -1));
685 static int rpmluaReadline(lua_State *L,
const char *prompt)
689 static char buffer[1024];
691 (void) fputs(prompt, stdout);
692 (void) fflush(stdout);
694 if (fgets(buffer, (
int)
sizeof(buffer), stdin) == NULL) {
697 lua_pushstring(L, buffer);
703 static void _rpmluaInteractive(lua_State *L)
707 (void) fputs(
"\n", stdout);
708 printf(
"RPM Interactive %s Interpreter\n", LUA_VERSION);
712 if (rpmluaReadline(L,
"> ") == 0)
714 if (lua_tostring(L, -1)[0] ==
'=') {
716 (void) lua_pushfstring(L,
"print(%s)", lua_tostring(L, -1)+1);
722 rc = luaL_loadbuffer(L, lua_tostring(L, -1),
723 lua_strlen(L, -1),
"<lua>");
725 if (rc == LUA_ERRSYNTAX &&
726 strstr(lua_tostring(L, -1),
"near `<eof>'") != NULL) {
727 if (rpmluaReadline(L,
">> ") == 0)
736 rc = lua_pcall(L, 0, 0, 0);
739 fprintf(stderr,
"%s\n", lua_tostring(L, -1));
745 (void) fputs(
"\n", stdout);
751 INITSTATE(_lua, lua);
752 _rpmluaInteractive(lua->L);
759 static int rpm_macros(lua_State *L)
762 const char ** av = NULL;
775 for (i = 0; i < ac; i++) {
782 o = ((b > n && b[-1] ==
')') ? strchr(n,
'(') : NULL);
784 if (o != NULL && *o ==
'(') {
794 lua_pushstring(L, n);
797 lua_pushstring(L,
"opts");
798 lua_pushstring(L, o);
802 lua_pushstring(L,
"body");
803 lua_pushstring(L, b);
813 static int rpm_expand(lua_State *L)
817 const char *str = luaL_checkstring(L, 1);
822 static int rpm_define(lua_State *L)
826 const char *str = luaL_checkstring(L, 1);
831 static int rpm_undefine(lua_State *L)
835 const char *str = luaL_checkstring(L, 1);
840 static int rpm_interactive(lua_State *L)
844 _rpmluaInteractive(L);
848 typedef struct rpmluaHookData_s {
855 static int rpmluaHookWrapper(
rpmhookArgs args,
void *data)
858 rpmluaHookData hookdata = (rpmluaHookData)data;
859 lua_State *L = hookdata->L;
862 lua_rawgeti(L, LUA_REGISTRYINDEX, hookdata->funcRef);
864 for (i = 0; i != args->
argc; i++) {
865 switch (args->
argt[i]) {
867 lua_pushstring(L, args->
argv[i].
s);
868 lua_rawseti(L, -2, i+1);
871 lua_pushnumber(L, (lua_Number)args->
argv[i].
i);
872 lua_rawseti(L, -2, i+1);
875 lua_pushnumber(L, (lua_Number)args->
argv[i].
f);
876 lua_rawseti(L, -2, i+1);
879 lua_pushlightuserdata(L, args->
argv[i].
p);
880 lua_rawseti(L, -2, i+1);
883 (void) luaL_error(L,
"unsupported type '%c' as "
884 "a hook argument\n", args->
argt[i]);
888 if (lua_pcall(L, 1, 1, 0) != 0) {
890 lua_tostring(L, -1));
893 if (lua_isnumber(L, -1))
894 ret = (int)lua_tonumber(L, -1);
900 static int rpm_register(lua_State *L)
904 if (!lua_isstring(L, 1)) {
905 (void) luaL_argerror(L, 1,
"hook name expected");
906 }
else if (!lua_isfunction(L, 2)) {
907 (void) luaL_argerror(L, 2,
"function expected");
909 rpmluaHookData hookdata =
910 lua_newuserdata(L,
sizeof(
struct rpmluaHookData_s));
911 lua_pushvalue(L, -1);
912 hookdata->dataRef = luaL_ref(L, LUA_REGISTRYINDEX);
914 hookdata->funcRef = luaL_ref(L, LUA_REGISTRYINDEX);
924 static int rpm_unregister(lua_State *L)
927 if (!lua_isstring(L, 1)) {
928 (void) luaL_argerror(L, 1,
"hook name expected");
929 }
else if (!lua_islightuserdata(L, 2)) {
930 (void) luaL_argerror(L, 2,
"hook information expected");
932 rpmluaHookData hookdata = (rpmluaHookData)lua_touserdata(L, 2);
933 luaL_unref(L, LUA_REGISTRYINDEX, hookdata->funcRef);
934 luaL_unref(L, LUA_REGISTRYINDEX, hookdata->dataRef);
940 static int rpm_call(lua_State *L)
944 if (!lua_isstring(L, 1)) {
945 (void) luaL_argerror(L, 1,
"hook name expected");
948 const char *name = lua_tostring(L, 1);
951 for (i = 0; i != args->
argc; i++) {
952 switch (lua_type(L, i+1)) {
955 args->
argv[i].
p = NULL;
958 float f = (float)lua_tonumber(L, i+1);
962 args->
argv[i].
i = (int)f;
971 args->
argv[i].
s = lua_tostring(L, i+1);
974 case LUA_TLIGHTUSERDATA:
976 args->
argv[i].
p = lua_touserdata(L, i+1);
979 (void) luaL_error(L,
"unsupported Lua type passed to hook");
981 args->
argv[i].
p = NULL;
996 static int rpm_print (lua_State *L)
1001 int n = lua_gettop(L);
1004 lua_getglobal(L,
"tostring");
1005 for (i = 1; i <= n; i++) {
1007 lua_pushvalue(L, -1);
1008 lua_pushvalue(L, i);
1010 s = lua_tostring(L, -1);
1012 return luaL_error(L,
"`tostring' must return a string to `print'");
1013 if (lua->storeprint) {
1014 size_t sl = lua_strlen(L, -1);
1015 if ((
size_t)(lua->printbufused+sl+1) > lua->printbufsize) {
1016 lua->printbufsize += sl+512;
1017 lua->printbuf =
xrealloc(lua->printbuf, lua->printbufsize);
1020 lua->printbuf[lua->printbufused++] =
'\t';
1021 memcpy(lua->printbuf+lua->printbufused, s, sl+1);
1022 lua->printbufused += sl;
1025 (void) fputs(
"\t", stdout);
1026 (void) fputs(s, stdout);
1030 if (!lua->storeprint) {
1031 (void) fputs(
"\n", stdout);
1033 if ((
size_t)(lua->printbufused+1) > lua->printbufsize) {
1034 lua->printbufsize += 512;
1035 lua->printbuf =
xrealloc(lua->printbuf, lua->printbufsize);
1037 lua->printbuf[lua->printbufused] =
'\0';
1042 static int rpm_source(lua_State *L)
1046 if (!lua_isstring(L, 1)) {
1047 (void)luaL_argerror(L, 1,
"filename expected");
1050 const char *filename = lua_tostring(L, 1);
1056 static int rpm_load(lua_State *L)
1060 if (!lua_isstring(L, 1)) {
1061 (void)luaL_argerror(L, 1,
"filename expected");
1063 const char *filename = lua_tostring(L, 1);
1071 static int rpm_verbose(lua_State *L)
1079 static int rpm_debug(lua_State *L)
1087 static int rpm_slurp(lua_State *L)
1095 if (lua_isstring(L, 1))
1096 fn = lua_tostring(L, 1);
1098 (void)luaL_argerror(L, 1,
"filename");
1104 if (rc || iob == NULL) {
1105 (void)luaL_error(L,
"failed to slurp data");
1113 static int rpm_sleep(lua_State *L)
1119 if (lua_isnumber(L, 1))
1120 sec = (unsigned) lua_tonumber(L, 1);
1122 (void)luaL_argerror(L, 1,
"seconds");
1129 static int rpm_realpath(lua_State *L)
1137 if (lua_isstring(L, 1))
1138 pn = lua_tostring(L, 1);
1140 (void)luaL_argerror(L, 1,
"pathname");
1143 if ((rp =
Realpath(pn, rp_buf)) == NULL) {
1144 (void)luaL_error(L,
"failed to resolve path via realpath(3): %s", strerror(errno));
1147 lua_pushstring(L, (
const char *)rp);
1151 static int rpm_hostname(lua_State *L)
1155 char hostname[1024];
1156 struct hostent *hbn;
1160 (void)gethostname(hostname,
sizeof(hostname));
1161 if ((hbn = gethostbyname(hostname)) != NULL)
1166 lua_pushstring(L, (
const char *)h);
1172 static const luaL_reg rpmlib[] = {
1173 {
"macros", rpm_macros},
1174 {
"expand", rpm_expand},
1175 {
"define", rpm_define},
1176 {
"undefine", rpm_undefine},
1177 {
"register", rpm_register},
1178 {
"unregister", rpm_unregister},
1180 {
"interactive", rpm_interactive},
1181 {
"source", rpm_source},
1183 {
"verbose", rpm_verbose},
1184 {
"debug", rpm_debug},
1185 {
"slurp", rpm_slurp},
1186 {
"sleep", rpm_sleep},
1187 {
"realpath", rpm_realpath},
1188 {
"hostname", rpm_hostname},
1193 static int luaopen_rpm(lua_State *L)
1196 lua_pushvalue(L, LUA_GLOBALSINDEX);
1197 luaL_openlib(L,
"rpm", rpmlib, 0);