rpm  5.4.15
rpmlua.c
Go to the documentation of this file.
1 /*@-moduncon -mustmod -realcompare -sizeoftype @*/
2 #include "system.h"
3 
4 #ifdef WITH_LUA
5 #define _RPMIOB_INTERNAL
6 #include <rpmiotypes.h>
7 #include <rpmio.h>
8 #include <rpmmacro.h>
9 #include <rpmlog.h>
10 #include <rpmurl.h>
11 #include <rpmhook.h>
12 #include <rpmcb.h>
13 #include <argv.h>
14 #include <popt.h> /* XXX poptSaneFile test */
15 
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19 
20 #include <lauxlib.h>
21 #include <lualib.h>
22 
23 #ifdef WITH_SYCK
24 LUALIB_API int luaopen_syck(lua_State *L)
25  /*@modifies L @*/;
26 #endif /* WITH_SYCK */
27 #ifdef WITH_LUA_INTERNAL
28 #include <llocal.h>
29 #include <lposix.h>
30 #include <lrexlib.h>
31 #include <luuid.h>
32 #include <lwrs.h>
33 #ifdef USE_LUA_CRYPTO /* XXX external lua modules instead. */
34 #include <lcrypto.h>
35 #include <lxplib.h>
36 #endif
37 #ifdef USE_LUA_SOCKET /* XXX external lua modules instead. */
38 #include <luasocket.h>
39 #endif
40 #endif
41 
42 #ifdef __cplusplus
43 }
44 #endif
45 
46 #define _RPMLUA_INTERNAL
47 #include "rpmlua.h"
48 
49 #include "debug.h"
50 
51 /*@access rpmiob @*/
52 
53 #else /* WITH_LUA */
54 #include <rpmio.h>
55 #endif
56 
57 /*@unchecked@*/
58 int _rpmlua_debug = 0;
59 
60 /*@unchecked@*/ /*@only@*/ /*@null@*/
62 
63 /*@unchecked@*/ /*@only@*/ /*@null@*/
65 
66 #ifdef WITH_LUA
67 
68 /* XXX lua-5.2.0 retrofit destruction area. */
69 #if LUA_VERSION_NUM >= 502
70 LUALIB_API int luaopen_posix_c (lua_State *L);
71 #endif
72 
73 #if !defined(HAVE_VSNPRINTF)
74 static inline int vsnprintf(char * buf, /*@unused@*/ size_t nb,
75  const char * fmt, va_list ap)
76 {
77  return vsprintf(buf, fmt, ap);
78 }
79 #endif
80 
81 #define INITSTATE(_lua, lua) \
82  rpmlua lua = _lua ? _lua : \
83  (globalLuaState ? globalLuaState : \
84  /*@-mods@*/ \
85  (globalLuaState = rpmluaNew()) \
86  /*@=mods@*/ \
87  )
88 
89 /*@only@*/ /*@unchecked@*/ /*@relnull@*/
90 static rpmlua globalLuaState;
91 
92 static int luaopen_rpm(lua_State *L)
93  /*@modifies L @*/;
94 static int rpm_print(lua_State *L)
95  /*@globals fileSystem @*/
96  /*@modifies L, fileSystem @*/;
97 
98 /*@unchecked@*/ /*@observer@*/
99 const char * rpmluaFiles = RPMLUAFILES;
100 
101 /*@unchecked@*/ /*@observer@*/
102 const char * rpmluaPath = "%{?_rpmhome}%{!?_rpmhome:" USRLIBRPM "}/lua/?.lua";
103 
105 {
106 /*@-globstate@*/
107  return globalLuaState;
108 /*@=globstate@*/
109 }
110 
111 static void rpmluaFini(void * _lua)
112  /*@globals globalLuaState @*/
113  /*@modifies globalLuaState @*/
114 {
115  rpmlua lua = (rpmlua) _lua;
116 
117  if (lua->L) lua_close(lua->L);
118  lua->L = NULL;
119  lua->printbuf = _free(lua->printbuf);
120 }
121 
122 static rpmlua rpmluaGetPool(/*@null@*/ rpmioPool pool)
123  /*@globals _rpmluaPool, fileSystem @*/
124  /*@modifies pool, _rpmluaPool, fileSystem @*/
125 {
126  rpmlua lua;
127 
128  if (_rpmluaPool == NULL) {
129  _rpmluaPool = rpmioNewPool("lua", sizeof(*lua), -1, _rpmlua_debug,
130  NULL, NULL, rpmluaFini);
131  pool = _rpmluaPool;
132  }
133  return (rpmlua) rpmioGetPool(pool, sizeof(*lua));
134 }
135 
136 void *rpmluaFree(rpmlua lua)
137 {
138  if (lua == NULL) lua = globalLuaState;
139  (void)rpmioFreePoolItem((rpmioItem)lua, __FUNCTION__, __FILE__, __LINE__);
140  if (lua == globalLuaState) globalLuaState = NULL;
141  return NULL;
142 }
143 
144 /*@-globs -mods@*/ /* XXX hide rpmGlobalMacroContext mods for now. */
145 rpmlua rpmluaNew(void)
146 {
147  rpmlua lua = rpmluaGetPool(_rpmluaPool);
148  lua_State *L = luaL_newstate();
149  /*@-readonlytrans -nullassign @*/
150  /*@observer@*/ /*@unchecked@*/
151  static const luaL_Reg lualibs[] = {
152 #ifdef WITH_SYCK
153  {"lsyck", luaopen_syck},
154 #endif /* WITH_SYCK */
155  /* local LUA libraries (RPM only) */
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},
161 #ifdef DYING /* XXX not currently internal */
162  {"wrs", luaopen_wrs},
163 #endif
164 #ifdef USE_LUA_CRYPTO /* XXX external lua modules instead. */
165  {"crypto", luaopen_crypto},
166  {"lxp", luaopen_lxp},
167 #endif
168 #ifdef USE_LUA_SOCKET /* XXX external lua modules instead. */
169  {"socket", luaopen_socket_core},
170 #endif
171  {"local", luaopen_local},
172 #endif
173  {"rpm", luaopen_rpm},
174  {NULL, NULL},
175  };
176  /*@=readonlytrans =nullassign @*/
177  /*@observer@*/ /*@unchecked@*/
178  const luaL_Reg *lib = lualibs;
179  char *path_buf;
180  char *path_next;
181  char *path;
182 
183  lua->L = L;
184  lua->pushsize = 0;
185  lua->storeprint = 0;
186  /* XXX TODO: use an rpmiob here. */
187  lua->printbufsize = 0;
188  lua->printbufused = 0;
189  lua->printbuf = NULL;
190 
191  luaL_openlibs(L);
192 
193  for (; lib->name; lib++) {
194  luaL_requiref(L, lib->name, lib->func, 1);
195  }
196 
197  { const char * _lua_path = rpmGetPath(rpmluaPath, NULL);
198  if (_lua_path != NULL) {
199  lua_pushliteral(L, "LUA_PATH");
200  lua_pushstring(L, _lua_path);
201  _lua_path = _free(_lua_path);
202  }
203  }
204 
205 #if defined(LUA_GLOBALSINDEX)
206  lua_rawset(L, LUA_GLOBALSINDEX);
207 #else
208  lua_pushglobaltable(L);
209 #endif
210  lua_pushcfunction(L, rpm_print);
211  lua_setglobal(L, "print");
212 
213 #if defined(LUA_GLOBALSINDEX)
214  lua_rawset(L, LUA_GLOBALSINDEX);
215 #else
216  lua_pushglobaltable(L);
217 #endif
218  rpmluaSetData(lua, "lua", lua);
219 
220  /* load all standard RPM Lua script files */
221  path_buf = xstrdup(rpmluaFiles);
222  for (path = path_buf; path != NULL && *path != '\0'; path = path_next) {
223  const char **av;
224  struct stat st;
225  int ac, i;
226 
227  /* locate start of next path element */
228  path_next = strchr(path, ':');
229  if (path_next != NULL && *path_next == ':')
230  *path_next++ = '\0';
231  else
232  path_next = path + strlen(path);
233 
234  /* glob-expand the path element */
235  ac = 0;
236  av = NULL;
237  if ((i = rpmGlob(path, &ac, &av)) != 0)
238  continue;
239 
240  /* work-off each resulting file from the path element */
241  for (i = 0; i < ac; i++) {
242  const char *fn = av[i];
243  if (fn[0] == '@' /* attention */) {
244  fn++;
245 #if defined(RPM_VENDOR_OPENPKG) /* stick-with-rpm-file-sanity-checking */ || \
246  !defined(POPT_ERROR_BADCONFIG) /* XXX POPT 1.15 retrofit */
247  if (!rpmSecuritySaneFile(fn))
248 #else
249  if (!poptSaneFile(fn))
250 #endif
251  {
252  rpmlog(RPMLOG_WARNING, "existing RPM Lua script file \"%s\" considered INSECURE -- not loaded\n", fn);
253  /*@innercontinue@*/ continue;
254  }
255  }
256  if (Stat(fn, &st) != -1)
257  (void)rpmluaRunScriptFile(lua, fn);
258  av[i] = _free(av[i]);
259  }
260  av = _free(av);
261  }
262  path_buf = _free(path_buf);
263 
264  return ((rpmlua)rpmioLinkPoolItem((rpmioItem)lua, __FUNCTION__, __FILE__, __LINE__));
265 }
266 /*@=globs =mods@*/
267 
268 void rpmluaSetData(rpmlua _lua, const char *key, const void *data)
269 {
270  INITSTATE(_lua, lua);
271  lua_State *L = lua->L;
272  lua_pushliteral(L, "rpm_");
273  lua_pushstring(L, key);
274  lua_concat(L, 2);
275  if (data == NULL)
276  lua_pushnil(L);
277  else
278  lua_pushlightuserdata(L, (void *)data);
279  lua_rawset(L, LUA_REGISTRYINDEX);
280 }
281 
282 /*@null@*/
283 static void *getdata(lua_State *L, const char *key)
284  /*@modifies L @*/
285 {
286  void *ret = NULL;
287  lua_pushliteral(L, "rpm_");
288  lua_pushstring(L, key);
289  lua_concat(L, 2);
290  lua_rawget(L, LUA_REGISTRYINDEX);
291  if (lua_islightuserdata(L, -1))
292  ret = lua_touserdata(L, -1);
293  lua_pop(L, 1);
294  return ret;
295 }
296 
297 void *rpmluaGetData(rpmlua _lua, const char *key)
298 {
299  INITSTATE(_lua, lua);
300  return getdata(lua->L, key);
301 }
302 
303 void rpmluaSetPrintBuffer(rpmlua _lua, int flag)
304 {
305  INITSTATE(_lua, lua);
306  lua->storeprint = flag;
307  lua->printbuf = _free(lua->printbuf);
308  lua->printbufsize = 0;
309  lua->printbufused = 0;
310 }
311 
312 const char *rpmluaGetPrintBuffer(rpmlua _lua)
313 {
314  INITSTATE(_lua, lua);
315  return lua->printbuf;
316 }
317 
318 static int pushvar(lua_State *L, rpmluavType type, void *value)
319  /*@modifies L @*/
320 {
321  int ret = 0;
322  switch (type) {
323  case RPMLUAV_NIL:
324  lua_pushnil(L);
325  break;
326  case RPMLUAV_STRING:
327  lua_pushstring(L, *((char **)value));
328  break;
329  case RPMLUAV_NUMBER:
330  lua_pushnumber(L, *((double *)value));
331  break;
332  default:
333  ret = -1;
334  break;
335  }
336  return ret;
337 }
338 
339 void rpmluaSetVar(rpmlua _lua, rpmluav var)
340 {
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) {
345  var->keyType = RPMLUAV_NUMBER;
346  var->key.num = (double) lua_rawlen(L, -1);
347  }
348  var->key.num++;
349  }
350  if (!var->listmode || lua->pushsize > 0) {
351 #if defined(LUA_GLOBALSINDEX)
352  if (lua->pushsize == 0)
353  lua_pushvalue(L, LUA_GLOBALSINDEX);
354 #endif
355  if (pushvar(L, var->keyType, &var->key) != -1) {
356  if (pushvar(L, var->valueType, &var->value) != -1)
357  lua_rawset(L, -3);
358  else
359  lua_pop(L, 1);
360  }
361  if (lua->pushsize == 0)
362  lua_pop(L, 1);
363  }
364 }
365 
366 static void popvar(lua_State *L, rpmluavType *type, void *value)
367  /*@modifies L, *type, *value @*/
368 {
369  switch (lua_type(L, -1)) {
370  case LUA_TSTRING:
371  *type = RPMLUAV_STRING;
372 /*@-observertrans -dependenttrans @*/
373  *((const char **)value) = lua_tostring(L, -1);
374 /*@=observertrans =dependenttrans @*/
375  break;
376  case LUA_TNUMBER:
377  *type = RPMLUAV_NUMBER;
378  *((double *)value) = lua_tonumber(L, -1);
379  break;
380  default:
381  *type = RPMLUAV_NIL;
382  *((void **)value) = NULL;
383  break;
384  }
385  lua_pop(L, 1);
386 }
387 
388 void rpmluaGetVar(rpmlua _lua, rpmluav var)
389 {
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);
396 #else
397  if (lua->pushsize == 0)
398  lua_pushglobaltable(L);
399 #endif
400  if (pushvar(L, var->keyType, &var->key) != -1) {
401  lua_rawget(L, -2);
402  popvar(L, &var->valueType, &var->value);
403  }
404  if (lua->pushsize == 0)
405  lua_pop(L, 1);
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);
410  }
411 }
412 
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)
417  /*@modifies L @*/
418 {
419  char buf[BUFSIZ];
420  const char *s, *e;
421  int ret = 0;
422  (void) vsnprintf(buf, sizeof(buf), key, va);
423  s = e = buf;
424 #if defined(LUA_GLOBALSINDEX)
425  lua_pushvalue(L, LUA_GLOBALSINDEX);
426 #else
427  lua_pushglobaltable(L);
428 #endif
429  for (;;) {
430  if (*e == '\0' || *e == '.') {
431  if (e != s) {
432  lua_pushlstring(L, s, e-s);
433  switch (oper) {
434  case FINDKEY_REMOVE:
435  if (*e == '\0') {
436  lua_pushnil(L);
437  lua_rawset(L, -3);
438  lua_pop(L, 1);
439  /*@switchbreak@*/ break;
440  }
441  /*@fallthrough@*/
442  case FINDKEY_RETURN:
443  lua_rawget(L, -2);
444  lua_remove(L, -2);
445  /*@switchbreak@*/ break;
446  case FINDKEY_CREATE:
447  lua_rawget(L, -2);
448  if (!lua_istable(L, -1)) {
449  lua_pop(L, 1);
450  lua_newtable(L);
451  lua_pushlstring(L, s, e-s);
452  lua_pushvalue(L, -2);
453  lua_rawset(L, -4);
454  }
455  lua_remove(L, -2);
456  /*@switchbreak@*/ break;
457  }
458  }
459  if (*e == '\0')
460  break;
461  if (!lua_istable(L, -1)) {
462  lua_pop(L, 1);
463  ret = -1;
464  break;
465  }
466  s = e+1;
467  }
468  e++;
469  }
470 
471  return ret;
472 }
473 
474 void rpmluaDelVar(rpmlua _lua, const char *key, ...)
475 {
476  INITSTATE(_lua, lua);
477  va_list va;
478  va_start(va, key);
479  (void) findkey(lua->L, FINDKEY_REMOVE, key, va);
480  va_end(va);
481 }
482 
483 int rpmluaVarExists(rpmlua _lua, const char *key, ...)
484 {
485  INITSTATE(_lua, lua);
486  lua_State *L = lua->L;
487  int ret = 0;
488  va_list va;
489  va_start(va, key);
490  if (findkey(L, FINDKEY_RETURN, key, va) == 0) {
491  if (!lua_isnil(L, -1))
492  ret = 1;
493  lua_pop(L, 1);
494  }
495  va_end(va);
496  return ret;
497 }
498 
499 void rpmluaPushTable(rpmlua _lua, const char *key, ...)
500 {
501  INITSTATE(_lua, lua);
502  va_list va;
503  va_start(va, key);
504  (void) findkey(lua->L, FINDKEY_CREATE, key, va);
505  lua->pushsize++;
506  va_end(va);
507 }
508 
509 void rpmluaPop(rpmlua _lua)
510 {
511  INITSTATE(_lua, lua);
512  assert(lua->pushsize > 0);
513  lua->pushsize--;
514  lua_pop(lua->L, 1);
515 }
516 
517 void *rpmluavFree(rpmluav var)
518 {
519  (void)rpmioFreePoolItem((rpmioItem)var, __FUNCTION__, __FILE__, __LINE__);
520  return NULL;
521 }
522 
523 static rpmluav rpmluavGetPool(/*@null@*/ rpmioPool pool)
524  /*@globals _rpmluavPool, fileSystem @*/
525  /*@modifies pool, _rpmluavPool, fileSystem @*/
526 {
527  rpmluav luav;
528 
529  if (_rpmluavPool == NULL) {
530  _rpmluavPool = rpmioNewPool("luav", sizeof(*luav), -1, _rpmlua_debug,
531  NULL, NULL, NULL);
532  pool = _rpmluavPool;
533  }
534  return (rpmluav) rpmioGetPool(pool, sizeof(*luav));
535 }
536 
537 rpmluav rpmluavNew(void)
538 {
539  rpmluav var = rpmluavGetPool(_rpmluavPool);
540  var->keyType = RPMLUAV_NIL;
541  var->valueType = RPMLUAV_NIL;
542  var->key.ptr = NULL;
543  var->value.ptr = NULL;
544  var->listmode = 0;
545  return ((rpmluav)rpmioLinkPoolItem((rpmioItem)var, __FUNCTION__, __FILE__, __LINE__));
546 }
547 
548 void rpmluavSetListMode(rpmluav var, int flag)
549 {
550  var->listmode = flag;
551  var->keyType = RPMLUAV_NIL;
552 }
553 
554 void rpmluavSetKey(rpmluav var, rpmluavType type, const void *value)
555 {
556  var->keyType = type;
557 /*@-assignexpose -temptrans @*/
558  switch (type) {
559  case RPMLUAV_NUMBER:
560  var->key.num = *((double *)value);
561  break;
562  case RPMLUAV_STRING:
563  var->key.str = (char *)value;
564  break;
565  default:
566  break;
567  }
568 /*@=assignexpose =temptrans @*/
569 }
570 
571 void rpmluavSetValue(rpmluav var, rpmluavType type, const void *value)
572 {
573  var->valueType = type;
574 /*@-assignexpose -temptrans @*/
575  switch (type) {
576  case RPMLUAV_NUMBER:
577  var->value.num = *((const double *)value);
578  break;
579  case RPMLUAV_STRING:
580  var->value.str = (const char *)value;
581  break;
582  default:
583  break;
584  }
585 /*@=assignexpose =temptrans @*/
586 }
587 
588 void rpmluavGetKey(rpmluav var, rpmluavType *type, void **value)
589 {
590  *type = var->keyType;
591 /*@-onlytrans@*/
592  switch (var->keyType) {
593  case RPMLUAV_NUMBER:
594  *((double **)value) = &var->key.num;
595  break;
596  case RPMLUAV_STRING:
597  *((const char **)value) = var->key.str;
598  break;
599  default:
600  break;
601  }
602 /*@=onlytrans@*/
603 }
604 
605 void rpmluavGetValue(rpmluav var, rpmluavType *type, void **value)
606 {
607  *type = var->valueType;
608 /*@-onlytrans@*/
609  switch (var->valueType) {
610  case RPMLUAV_NUMBER:
611  *((double **)value) = &var->value.num;
612  break;
613  case RPMLUAV_STRING:
614  *((const char **)value) = var->value.str;
615  break;
616  default:
617  break;
618  }
619 /*@=onlytrans@*/
620 }
621 
622 void rpmluavSetKeyNum(rpmluav var, double value)
623 {
624  rpmluavSetKey(var, RPMLUAV_NUMBER, &value);
625 }
626 
627 void rpmluavSetValueNum(rpmluav var, double value)
628 {
629  rpmluavSetValue(var, RPMLUAV_NUMBER, &value);
630 }
631 
632 double rpmluavGetKeyNum(rpmluav var)
633 {
635  void *value;
636  rpmluavGetKey(var, &type, &value);
637  if (type == RPMLUAV_NUMBER)
638  return *((double *)value);
639  return (double) 0;
640 }
641 
642 double rpmluavGetValueNum(rpmluav var)
643 {
645  void *value;
646  rpmluavGetValue(var, &type, &value);
647  if (type == RPMLUAV_NUMBER)
648  return *((double *)value);
649  return (double) 0;
650 }
651 
652 int rpmluavKeyIsNum(rpmluav var)
653 {
654  return (var->keyType == RPMLUAV_NUMBER) ? 1 : 0;
655 }
656 
657 int rpmluavValueIsNum(rpmluav var)
658 {
659  return (var->valueType == RPMLUAV_NUMBER) ? 1 : 0;
660 }
661 
662 int rpmluaCheckScript(rpmlua _lua, const char *script, const char *name)
663 {
664  INITSTATE(_lua, lua);
665  lua_State *L = lua->L;
666  int ret = 0;
667  if (name == NULL)
668  name = "<lua>";
669  if (luaL_loadbuffer(L, script, strlen(script), name) != 0) {
671  _("invalid syntax in Lua scriptlet: %s\n"),
672  lua_tostring(L, -1));
673  ret = -1;
674  }
675  lua_pop(L, 1); /* Error or chunk. */
676  return ret;
677 }
678 
679 int rpmluaRunScript(rpmlua _lua, const char *script, const char *name)
680 {
681  INITSTATE(_lua, lua);
682  lua_State *L = lua->L;
683  int ret = 0;
684  if (name == NULL)
685  name = "<lua>";
686  if (luaL_loadbuffer(L, script, strlen(script), name) != 0) {
687  rpmlog(RPMLOG_ERR, _("invalid syntax in Lua script: %s\n"),
688  lua_tostring(L, -1));
689  lua_pop(L, 1);
690  ret = -1;
691  } else if (lua_pcall(L, 0, 0, 0) != 0) {
692  rpmlog(RPMLOG_ERR, _("Lua script failed: %s\n"),
693  lua_tostring(L, -1));
694  lua_pop(L, 1);
695  ret = -1;
696  }
697  return ret;
698 }
699 
700 int rpmluaRunScriptFile(rpmlua _lua, const char *filename)
701 {
702  INITSTATE(_lua, lua);
703  lua_State *L = lua->L;
704  int ret = 0;
705  if (luaL_loadfile(L, filename) != 0) {
706  rpmlog(RPMLOG_ERR, _("invalid syntax in Lua file: %s\n"),
707  lua_tostring(L, -1));
708  lua_pop(L, 1);
709  ret = -1;
710  } else if (lua_pcall(L, 0, 0, 0) != 0) {
711  rpmlog(RPMLOG_ERR, _("Lua script failed: %s\n"),
712  lua_tostring(L, -1));
713  lua_pop(L, 1);
714  ret = -1;
715  }
716  return ret;
717 }
718 
719 /* From lua.c */
720 static int rpmluaReadline(lua_State *L, const char *prompt)
721  /*@globals fileSystem @*/
722  /*@modifies L, fileSystem @*/
723 {
724  static char buffer[1024];
725  if (prompt) {
726  (void) fputs(prompt, stdout);
727  (void) fflush(stdout);
728  }
729  if (fgets(buffer, (int)sizeof(buffer), stdin) == NULL) {
730  return 0; /* read fails */
731  } else {
732  lua_pushstring(L, buffer);
733  return 1;
734  }
735 }
736 
737 /* Based on lua.c */
738 static void _rpmluaInteractive(lua_State *L)
739  /*@globals fileSystem @*/
740  /*@modifies L, fileSystem @*/
741 {
742  (void) fputs("\n", stdout);
743  printf("RPM Interactive %s Interpreter\n", LUA_VERSION);
744  for (;;) {
745  int rc = 0;
746 
747  if (rpmluaReadline(L, "> ") == 0)
748  break;
749  if (lua_tostring(L, -1)[0] == '=') {
750 /*@-evalorder@*/
751  (void) lua_pushfstring(L, "print(%s)", lua_tostring(L, -1)+1);
752 /*@=evalorder@*/
753  lua_remove(L, -2);
754  }
755  for (;;) {
756 /*@-evalorder@*/
757  rc = luaL_loadbuffer(L, lua_tostring(L, -1),
758  lua_rawlen(L, -1), "<lua>");
759 /*@=evalorder@*/
760  if (rc == LUA_ERRSYNTAX &&
761  strstr(lua_tostring(L, -1), "near `<eof>'") != NULL) {
762  if (rpmluaReadline(L, ">> ") == 0)
763  /*@innerbreak@*/ break;
764  lua_remove(L, -2); /* Remove error */
765  lua_concat(L, 2);
766  /*@innercontinue@*/ continue;
767  }
768  /*@innerbreak@*/ break;
769  }
770  if (rc == 0)
771  rc = lua_pcall(L, 0, 0, 0);
772  if (rc != 0) {
773 /*@-evalorderuncon@*/
774  fprintf(stderr, "%s\n", lua_tostring(L, -1));
775 /*@=evalorderuncon@*/
776  lua_pop(L, 1);
777  }
778  lua_pop(L, 1); /* Remove line */
779  }
780  (void) fputs("\n", stdout);
781 }
782 
783 /*@-mods@*/
784 void rpmluaInteractive(rpmlua _lua)
785 {
786  INITSTATE(_lua, lua);
787  _rpmluaInteractive(lua->L);
788 }
789 /*@=mods@*/
790 
791 /* ------------------------------------------------------------------ */
792 /* Lua API */
793 
794 static int rpm_macros(lua_State *L)
795  /*@modifies L @*/
796 {
797  const char ** av = NULL;
798  int ac = 0;
799  int i;
800 
801 /*@-modunconnomods@*/
802  lua_newtable(L);
803 /*@=modunconnomods@*/
804 
805 /*@-globs@*/
806  ac = rpmGetMacroEntries(NULL, NULL, -1, &av);
807 /*@=globs@*/
808 
809  if (av != NULL)
810  for (i = 0; i < ac; i++) {
811  char *n, *o, *b;
812 
813  /* Parse out "%name(opts)\tbody" into n/o/b strings. */
814  n = (char *) av[i];
815  b = strchr(n, '\t');
816 assert(b != NULL);
817  o = ((b > n && b[-1] == ')') ? strchr(n, '(') : NULL);
818  if (*n == '%') n++;
819  if (o != NULL && *o == '(') {
820  b[-1] = '\0';
821  o++;
822  o[-1] = '\0';
823  }
824  else
825  b[0] = '\0';
826  b++;
827 
828 /*@-modunconnomods@*/
829  lua_pushstring(L, n);
830  lua_newtable(L);
831  if (o) {
832  lua_pushstring(L, "opts");
833  lua_pushstring(L, o);
834  lua_settable(L, -3);
835  }
836  if (b) {
837  lua_pushstring(L, "body");
838  lua_pushstring(L, b);
839  lua_settable(L, -3);
840  }
841  lua_settable(L, -3);
842 /*@=modunconnomods@*/
843  }
844  av = argvFree(av);
845  return 1;
846 }
847 
848 static int rpm_expand(lua_State *L)
849  /*@globals rpmGlobalMacroContext, h_errno, internalState @*/
850  /*@modifies L, rpmGlobalMacroContext, internalState @*/
851 {
852  const char *str = luaL_checkstring(L, 1);
853  lua_pushstring(L, rpmExpand(str, NULL));
854  return 1;
855 }
856 
857 static int rpm_define(lua_State *L)
858  /*@globals rpmGlobalMacroContext, h_errno, internalState @*/
859  /*@modifies L, rpmGlobalMacroContext, internalState @*/
860 {
861  const char *str = luaL_checkstring(L, 1);
862  (void) rpmDefineMacro(NULL, str, 0);
863  return 0;
864 }
865 
866 static int rpm_undefine(lua_State *L)
867  /*@globals rpmGlobalMacroContext, internalState @*/
868  /*@modifies L, rpmGlobalMacroContext, internalState @*/
869 {
870  const char *str = luaL_checkstring(L, 1);
871  (void) rpmUndefineMacro(NULL, str);
872  return 0;
873 }
874 
875 static int rpm_interactive(lua_State *L)
876  /*@globals fileSystem @*/
877  /*@modifies L, fileSystem @*/
878 {
879  _rpmluaInteractive(L);
880  return 0;
881 }
882 
883 typedef struct rpmluaHookData_s {
884 /*@shared@*/
885  lua_State *L;
886  int funcRef;
887  int dataRef;
888 } * rpmluaHookData;
889 
890 static int rpmluaHookWrapper(rpmhookArgs args, void *data)
891  /*@*/
892 {
893  rpmluaHookData hookdata = (rpmluaHookData)data;
894  lua_State *L = hookdata->L;
895  int ret = 0;
896  int i;
897  lua_rawgeti(L, LUA_REGISTRYINDEX, hookdata->funcRef);
898  lua_newtable(L);
899  for (i = 0; i != args->argc; i++) {
900  switch (args->argt[i]) {
901  case 's':
902  lua_pushstring(L, args->argv[i].s);
903  lua_rawseti(L, -2, i+1);
904  /*@switchbreak@*/ break;
905  case 'i':
906  lua_pushnumber(L, (lua_Number)args->argv[i].i);
907  lua_rawseti(L, -2, i+1);
908  /*@switchbreak@*/ break;
909  case 'f':
910  lua_pushnumber(L, (lua_Number)args->argv[i].f);
911  lua_rawseti(L, -2, i+1);
912  /*@switchbreak@*/ break;
913  case 'p':
914  lua_pushlightuserdata(L, args->argv[i].p);
915  lua_rawseti(L, -2, i+1);
916  /*@switchbreak@*/ break;
917  default:
918  (void) luaL_error(L, "unsupported type '%c' as "
919  "a hook argument\n", args->argt[i]);
920  /*@switchbreak@*/ break;
921  }
922  }
923  if (lua_pcall(L, 1, 1, 0) != 0) {
924  rpmlog(RPMLOG_ERR, _("lua hook failed: %s\n"),
925  lua_tostring(L, -1));
926  lua_pop(L, 1);
927  } else {
928  if (lua_isnumber(L, -1))
929  ret = (int)lua_tonumber(L, -1);
930  lua_pop(L, 1);
931  }
932  return ret;
933 }
934 
935 static int rpm_register(lua_State *L)
936  /*@globals internalState @*/
937  /*@modifies L, internalState @*/
938 {
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");
943  } else {
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);
948  lua_pushvalue(L, 2);
949  hookdata->funcRef = luaL_ref(L, LUA_REGISTRYINDEX);
950 /*@-temptrans@*/
951  hookdata->L = L;
952 /*@=temptrans@*/
953  rpmhookRegister(lua_tostring(L, 1), rpmluaHookWrapper, hookdata);
954  return 1;
955  }
956  return 0;
957 }
958 
959 static int rpm_unregister(lua_State *L)
960  /*@modifies L @*/
961 {
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");
966  } else {
967  rpmluaHookData hookdata = (rpmluaHookData)lua_touserdata(L, 2);
968  luaL_unref(L, LUA_REGISTRYINDEX, hookdata->funcRef);
969  luaL_unref(L, LUA_REGISTRYINDEX, hookdata->dataRef);
970  rpmhookUnregister(lua_tostring(L, 1), rpmluaHookWrapper, hookdata);
971  }
972  return 0;
973 }
974 
975 static int rpm_call(lua_State *L)
976  /*@globals internalState @*/
977  /*@modifies L, internalState @*/
978 {
979  if (!lua_isstring(L, 1)) {
980  (void) luaL_argerror(L, 1, "hook name expected");
981  } else {
982  rpmhookArgs args = rpmhookArgsNew(lua_gettop(L)-1);
983  const char *name = lua_tostring(L, 1);
984  char *argt = (char *)xmalloc(args->argc+1);
985  int i;
986  for (i = 0; i != args->argc; i++) {
987  switch (lua_type(L, i+1)) {
988  case LUA_TNIL:
989  argt[i] = 'p';
990  args->argv[i].p = NULL;
991  /*@switchbreak@*/ break;
992  case LUA_TNUMBER: {
993  float f = (float)lua_tonumber(L, i+1);
994 /*@+relaxtypes@*/
995  if (f == (int)f) {
996  argt[i] = 'i';
997  args->argv[i].i = (int)f;
998  } else {
999  argt[i] = 'f';
1000  args->argv[i].f = f;
1001  }
1002 /*@=relaxtypes@*/
1003  } /*@switchbreak@*/ break;
1004  case LUA_TSTRING:
1005  argt[i] = 's';
1006  args->argv[i].s = lua_tostring(L, i+1);
1007  /*@switchbreak@*/ break;
1008  case LUA_TUSERDATA:
1009  case LUA_TLIGHTUSERDATA:
1010  argt[i] = 'p';
1011  args->argv[i].p = lua_touserdata(L, i+1);
1012  /*@switchbreak@*/ break;
1013  default:
1014  (void) luaL_error(L, "unsupported Lua type passed to hook");
1015  argt[i] = 'p';
1016  args->argv[i].p = NULL;
1017  /*@switchbreak@*/ break;
1018  }
1019  }
1020 /*@-compdef -kepttrans -usereleased @*/
1021  args->argt = argt;
1022  rpmhookCallArgs(name, args);
1023  argt = _free(argt);
1024  (void) rpmhookArgsFree(args);
1025 /*@=compdef =kepttrans =usereleased @*/
1026  }
1027  return 0;
1028 }
1029 
1030 /* Based on luaB_print. */
1031 static int rpm_print (lua_State *L)
1032  /*@globals fileSystem @*/
1033  /*@modifies L, fileSystem @*/
1034 {
1035  rpmlua lua = (rpmlua)getdata(L, "lua");
1036  int n = lua_gettop(L); /* number of arguments */
1037  int i;
1038  if (!lua) return 0;
1039  lua_getglobal(L, "tostring");
1040  for (i = 1; i <= n; i++) {
1041  const char *s;
1042  lua_pushvalue(L, -1); /* function to be called */
1043  lua_pushvalue(L, i); /* value to print */
1044  lua_call(L, 1, 1);
1045  s = lua_tostring(L, -1); /* get result */
1046  if (s == NULL)
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);
1053  }
1054  if (i > 1)
1055  lua->printbuf[lua->printbufused++] = '\t';
1056  memcpy(lua->printbuf+lua->printbufused, s, sl+1);
1057  lua->printbufused += sl;
1058  } else {
1059  if (i > 1)
1060  (void) fputs("\t", stdout);
1061  (void) fputs(s, stdout);
1062  }
1063  lua_pop(L, 1); /* pop result */
1064  }
1065  if (!lua->storeprint) {
1066  (void) fputs("\n", stdout);
1067  } else {
1068  if ((size_t)(lua->printbufused+1) > lua->printbufsize) {
1069  lua->printbufsize += 512;
1070  lua->printbuf = (char *) xrealloc(lua->printbuf, lua->printbufsize);
1071  }
1072  lua->printbuf[lua->printbufused] = '\0';
1073  }
1074  return 0;
1075 }
1076 
1077 static int rpm_source(lua_State *L)
1078  /*@globals fileSystem, internalState @*/
1079  /*@modifies L, fileSystem, internalState @*/
1080 {
1081  if (!lua_isstring(L, 1)) {
1082  (void)luaL_argerror(L, 1, "filename expected");
1083  } else {
1084  rpmlua lua = (rpmlua)getdata(L, "lua");
1085  const char *filename = lua_tostring(L, 1);
1086  (void)rpmluaRunScriptFile(lua, filename);
1087  }
1088  return 0;
1089 }
1090 
1091 extern int _max_load_depth; /* Maximum load nesting depth. */
1092 static int rpm_load(lua_State *L)
1093  /*@globals rpmGlobalMacroContext, fileSystem, internalState @*/
1094  /*@modifies L, rpmGlobalMacroContext, fileSystem, internalState @*/
1095 {
1096  if (!lua_isstring(L, 1)) {
1097  (void)luaL_argerror(L, 1, "filename expected");
1098  } else {
1099  const char *filename = lua_tostring(L, 1);
1100 /*@-globs@*/
1101  (void)rpmLoadMacroFile(NULL, filename, _max_load_depth);
1102 /*@=globs@*/
1103  }
1104  return 0;
1105 }
1106 
1107 static int rpm_verbose(lua_State *L)
1108  /*@globals internalState @*/
1109  /*@modifies L, internalState @*/
1110 {
1111  lua_pushboolean(L, rpmIsVerbose());
1112  return 1;
1113 }
1114 
1115 static int rpm_debug(lua_State *L)
1116  /*@globals internalState @*/
1117  /*@modifies L, internalState @*/
1118 {
1119  lua_pushboolean(L, rpmIsDebug());
1120  return 1;
1121 }
1122 
1123 static int rpm_slurp(lua_State *L)
1124  /*@globals fileSystem, internalState @*/
1125  /*@modifies L, fileSystem, internalState @*/
1126 {
1127  rpmiob iob = NULL;
1128  const char *fn;
1129  int rc;
1130 
1131  if (lua_isstring(L, 1))
1132  fn = lua_tostring(L, 1);
1133  else {
1134  (void)luaL_argerror(L, 1, "filename");
1135  return 0;
1136  }
1137 /*@-globs@*/
1138  rc = rpmiobSlurp(fn, &iob);
1139 /*@=globs@*/
1140  if (rc || iob == NULL) {
1141  (void)luaL_error(L, "failed to slurp data");
1142  return 0;
1143  }
1144  lua_pushlstring(L, (const char *)rpmiobStr(iob), rpmiobLen(iob));
1145  iob = rpmiobFree(iob);
1146  return 1;
1147 }
1148 
1149 static int rpm_sleep(lua_State *L)
1150  /*@globals fileSystem, internalState @*/
1151  /*@modifies L, fileSystem, internalState @*/
1152 {
1153  unsigned sec;
1154 
1155  if (lua_isnumber(L, 1))
1156  sec = (unsigned) lua_tonumber(L, 1);
1157  else {
1158  (void)luaL_argerror(L, 1, "seconds");
1159  return 0;
1160  }
1161  (void) sleep(sec);
1162  return 0;
1163 }
1164 
1165 static int rpm_realpath(lua_State *L)
1166  /*@globals fileSystem, internalState @*/
1167  /*@modifies L, fileSystem, internalState @*/
1168 {
1169  const char *pn;
1170  char rp_buf[PATH_MAX];
1171  char *rp = (char *) "";
1172 
1173  if (lua_isstring(L, 1))
1174  pn = lua_tostring(L, 1);
1175  else {
1176  (void)luaL_argerror(L, 1, "pathname");
1177  return 0;
1178  }
1179  if ((rp = Realpath(pn, rp_buf)) == NULL) {
1180  (void)luaL_error(L, "failed to resolve path via realpath(3): %s", strerror(errno));
1181  return 0;
1182  }
1183  lua_pushstring(L, (const char *)rp);
1184  return 1;
1185 }
1186 
1187 static int rpm_hostname(lua_State *L)
1188  /*@globals h_errno, internalState @*/
1189  /*@modifies L, h_errno, internalState @*/
1190 {
1191  char hostname[1024];
1192  struct hostent *hbn;
1193  char *h;
1194 
1195 /*@-multithreaded@*/
1196  (void)gethostname(hostname, sizeof(hostname));
1197  if ((hbn = gethostbyname(hostname)) != NULL)
1198  h = hbn->h_name;
1199  else
1200  h = hostname;
1201 /*@=multithreaded@*/
1202  lua_pushstring(L, (const char *)h);
1203  return 1;
1204 }
1205 
1206 /*@-readonlytrans -nullassign @*/
1207 /*@observer@*/ /*@unchecked@*/
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},
1215  {"call", rpm_call},
1216  {"interactive", rpm_interactive},
1217  {"source", rpm_source},
1218  {"load", rpm_load},
1219  {"verbose", rpm_verbose},
1220  {"debug", rpm_debug},
1221  {"slurp", rpm_slurp},
1222  {"sleep", rpm_sleep},
1223  {"realpath", rpm_realpath},
1224  {"hostname", rpm_hostname},
1225  {NULL, NULL}
1226 };
1227 /*@=readonlytrans =nullassign @*/
1228 
1229 static int luaopen_rpm(lua_State *L)
1230  /*@modifies L @*/
1231 {
1232 #if defined(LUA_GLOBALSINDEX)
1233  lua_pushvalue(L, LUA_GLOBALSINDEX);
1234 #else
1235  lua_pushglobaltable(L);
1236 #endif
1237  luaL_newlib(L, rpmlib);
1238  return 1;
1239 }
1240 #endif /* WITH_LUA */
1241 
1242 /*@=moduncon =mustmod =realcompare =sizeoftype @*/
const bson * b
Definition: bson.h:280
#define RPMLUAFILES
Definition: config.h:1153
void rpmluavGetKey(rpmluav var, rpmluavType *type, void **value)
int rpmluaCheckScript(rpmlua _lua, const char *script, const char *name)
rpmhookArgs rpmhookArgsNew(int argc)
Definition: rpmhook.c:34
rpmhookArgs rpmhookArgsFree(rpmhookArgs args)
Definition: rpmhook.c:42
enum rpmluavType_e rpmluavType
const char * rpmluaPath
void rpmluavSetValueNum(rpmluav var, double value)
char * xstrdup(const char *str)
Definition: rpmmalloc.c:321
size_t rpmiobLen(rpmiob iob)
Return I/O buffer len.
Definition: rpmiob.c:122
void * rpmluavFree(rpmluav var)
char * rpmGetPath(const char *path,...)
Return (malloc'ed) expanded, canonicalized, file path.
Definition: macro.c:3443
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.
Definition: rpmmalloc.c:165
int _max_load_depth
Definition: macro.c:168
void rpmhookUnregister(const char *name, rpmhookFunc func, void *data)
Definition: rpmhook.c:249
void rpmluavSetKey(rpmluav var, rpmluavType type, const void *value)
rpmlua rpmluaGetGlobalState(void)
int Stat(const char *path, struct stat *st)
stat(2) clone.
Definition: rpmrpc.c:1361
const char * s
Definition: rpmhook.h:6
void * rpmioFreePoolItem(rpmioItem item, const char *msg, const char *fn, unsigned ln)
Free a pool item.
Definition: rpmmalloc.c:186
int errno
void * rpmluaGetData(rpmlua _lua, const char *key)
rpmiob rpmiobFree(rpmiob iob)
Destroy a I/O buffer instance.
double rpmluavGetValueNum(rpmluav var)
const char * buffer
Definition: bson.h:289
static void rpmlog(int code, const char *fmt,...)
Definition: rpmlog.h:299
void rpmluavSetKeyNum(rpmluav var, double value)
int _rpmlua_debug
Definition: rpmlua.c:58
int i
Definition: rpmhook.h:7
void rpmluaPushTable(rpmlua _lua, const char *key,...)
void rpmluavSetValue(rpmluav var, rpmluavType type, const void *value)
int rpmiobSlurp(const char *fn, rpmiob *iobp)
Definition: rpmiob.c:129
void rpmluaPop(rpmlua _lua)
const char * str
Definition: bson.h:593
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.
Definition: macro.c:2609
double rpmluavGetKeyNum(rpmluav var)
rpmioItem rpmioGetPool(rpmioPool pool, size_t size)
Get unused item from pool, or alloc a new item.
Definition: rpmmalloc.c:220
int rpmGetMacroEntries(MacroContext mc, void *_mire, int used, const char ***avp)
Return macro entries as string array.
Definition: macro.c:321
float f
Definition: rpmhook.h:8
const char const bson * data
Definition: mongo.h:463
ARGV_t argvFree(ARGV_t argv)
Destroy an argv array.
Definition: argv.c:44
struct rpmluav_s * rpmluav
Definition: rpmlua.h:54
const char * rpmluaGetPrintBuffer(rpmlua _lua)
int rpmDefineMacro(MacroContext mc, const char *macro, int level)
Define macro in context.
Definition: macro.c:2851
const char * rpmluaFiles
rpmluav rpmluavNew(void)
void * rpmluaFree(rpmlua lua)
char * rpmExpand(const char *arg,...)
Return (malloc'ed) concatenated macro expansion(s).
Definition: macro.c:3250
void rpmluaInteractive(rpmlua _lua)
void rpmluaDelVar(rpmlua _lua, const char *key,...)
rpmlua rpmluaNew(void)
void * p
Definition: rpmhook.h:10
void rpmluaSetData(rpmlua _lua, const char *key, const void *data)
#define USRLIBRPM
Definition: config.h:1297
rpmioPool _rpmluaPool
Definition: rpmlua.c:61
char * rpmiobStr(rpmiob iob)
Return I/O buffer (as string).
Definition: rpmiob.c:112
#define L(CS)
Definition: fnmatch.c:161
const char * argt
Definition: rpmhook.h:15
const char const int i
Definition: bson.h:778
const char const bson * key
Definition: mongo.h:717
static int vsnprintf(char *buf, int nb, const char *fmt, va_list ap)
Definition: rpmps.c:212
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.
Definition: rpmmalloc.c:109
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.
Definition: rpmiotypes.h:756
struct rpmiob_s * rpmiob
Definition: rpmiotypes.h:60
int rpmluavKeyIsNum(rpmluav var)
int rpmSecuritySaneFile(const char *filename)
Check whether configuration file is moderately secure to load.
Definition: macro.c:2586
int rpmluavValueIsNum(rpmluav var)
#define rpmIsVerbose()
Definition: rpmcb.h:21
rpmhookArgv argv[1]
Definition: rpmhook.h:16
void rpmhookRegister(const char *name, rpmhookFunc func, void *data)
Definition: rpmhook.c:240
rpmioPool _rpmluavPool
Definition: rpmlua.c:64
const char char type
Definition: bson.h:908
struct rpmlua_s * rpmlua
Definition: rpmlua.h:53
void rpmhookCallArgs(const char *name, rpmhookArgs args)
Definition: rpmhook.c:282
int rpmluaRunScriptFile(rpmlua _lua, const char *filename)
static const char * name
#define rpmIsDebug()
Definition: rpmcb.h:23
#define _(Text)
Definition: system.h:29
void rpmluavGetValue(rpmluav var, rpmluavType *type, void **value)
#define xmalloc
Definition: system.h:32
int rpmLoadMacroFile(MacroContext mc, const char *fn, int nesting)
Load macro context from a macro file.
Definition: macro.c:2913
#define PATH_MAX
Definition: query.c:10
char * Realpath(const char *path, char *resolved_path)
realpath(3) clone.
Definition: rpmrpc.c:2330
#define xrealloc
Definition: system.h:35
int rpmluaRunScript(rpmlua _lua, const char *script, const char *name)
int rpmUndefineMacro(MacroContext mc, const char *macro)
Undefine macro in context.
Definition: macro.c:2865