immunio 0.15.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (157) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +234 -0
  3. data/README.md +147 -0
  4. data/bin/immunio +5 -0
  5. data/lib/immunio.rb +29 -0
  6. data/lib/immunio/agent.rb +260 -0
  7. data/lib/immunio/authentication.rb +96 -0
  8. data/lib/immunio/blocked_app.rb +38 -0
  9. data/lib/immunio/channel.rb +432 -0
  10. data/lib/immunio/cli.rb +39 -0
  11. data/lib/immunio/context.rb +114 -0
  12. data/lib/immunio/errors.rb +43 -0
  13. data/lib/immunio/immunio_ca.crt +45 -0
  14. data/lib/immunio/logger.rb +87 -0
  15. data/lib/immunio/plugins/action_dispatch.rb +45 -0
  16. data/lib/immunio/plugins/action_view.rb +431 -0
  17. data/lib/immunio/plugins/active_record.rb +707 -0
  18. data/lib/immunio/plugins/active_record_relation.rb +370 -0
  19. data/lib/immunio/plugins/authlogic.rb +80 -0
  20. data/lib/immunio/plugins/csrf.rb +24 -0
  21. data/lib/immunio/plugins/devise.rb +40 -0
  22. data/lib/immunio/plugins/environment_reporter.rb +69 -0
  23. data/lib/immunio/plugins/eval.rb +51 -0
  24. data/lib/immunio/plugins/exception_handler.rb +55 -0
  25. data/lib/immunio/plugins/gems_tracker.rb +5 -0
  26. data/lib/immunio/plugins/haml.rb +36 -0
  27. data/lib/immunio/plugins/http_finisher.rb +50 -0
  28. data/lib/immunio/plugins/http_tracker.rb +203 -0
  29. data/lib/immunio/plugins/io.rb +96 -0
  30. data/lib/immunio/plugins/redirect.rb +42 -0
  31. data/lib/immunio/plugins/warden.rb +66 -0
  32. data/lib/immunio/processor.rb +234 -0
  33. data/lib/immunio/rails.rb +26 -0
  34. data/lib/immunio/request.rb +139 -0
  35. data/lib/immunio/rufus_lua_ext/ref.rb +27 -0
  36. data/lib/immunio/rufus_lua_ext/state.rb +157 -0
  37. data/lib/immunio/rufus_lua_ext/table.rb +137 -0
  38. data/lib/immunio/rufus_lua_ext/utils.rb +13 -0
  39. data/lib/immunio/version.rb +5 -0
  40. data/lib/immunio/vm.rb +291 -0
  41. data/lua-hooks/ext/all.c +78 -0
  42. data/lua-hooks/ext/bitop/README +22 -0
  43. data/lua-hooks/ext/bitop/bit.c +189 -0
  44. data/lua-hooks/ext/extconf.rb +38 -0
  45. data/lua-hooks/ext/libinjection/COPYING +37 -0
  46. data/lua-hooks/ext/libinjection/libinjection.h +65 -0
  47. data/lua-hooks/ext/libinjection/libinjection_html5.c +847 -0
  48. data/lua-hooks/ext/libinjection/libinjection_html5.h +54 -0
  49. data/lua-hooks/ext/libinjection/libinjection_sqli.c +2301 -0
  50. data/lua-hooks/ext/libinjection/libinjection_sqli.h +295 -0
  51. data/lua-hooks/ext/libinjection/libinjection_sqli_data.h +9349 -0
  52. data/lua-hooks/ext/libinjection/libinjection_xss.c +531 -0
  53. data/lua-hooks/ext/libinjection/libinjection_xss.h +21 -0
  54. data/lua-hooks/ext/libinjection/lualib.c +109 -0
  55. data/lua-hooks/ext/lpeg/HISTORY +90 -0
  56. data/lua-hooks/ext/lpeg/lpcap.c +537 -0
  57. data/lua-hooks/ext/lpeg/lpcap.h +43 -0
  58. data/lua-hooks/ext/lpeg/lpcode.c +986 -0
  59. data/lua-hooks/ext/lpeg/lpcode.h +34 -0
  60. data/lua-hooks/ext/lpeg/lpeg-128.gif +0 -0
  61. data/lua-hooks/ext/lpeg/lpeg.html +1429 -0
  62. data/lua-hooks/ext/lpeg/lpprint.c +244 -0
  63. data/lua-hooks/ext/lpeg/lpprint.h +35 -0
  64. data/lua-hooks/ext/lpeg/lptree.c +1238 -0
  65. data/lua-hooks/ext/lpeg/lptree.h +77 -0
  66. data/lua-hooks/ext/lpeg/lptypes.h +149 -0
  67. data/lua-hooks/ext/lpeg/lpvm.c +355 -0
  68. data/lua-hooks/ext/lpeg/lpvm.h +58 -0
  69. data/lua-hooks/ext/lpeg/makefile +55 -0
  70. data/lua-hooks/ext/lpeg/re.html +498 -0
  71. data/lua-hooks/ext/lpeg/test.lua +1409 -0
  72. data/lua-hooks/ext/lua-cmsgpack/CMakeLists.txt +45 -0
  73. data/lua-hooks/ext/lua-cmsgpack/README.md +115 -0
  74. data/lua-hooks/ext/lua-cmsgpack/lua_cmsgpack.c +957 -0
  75. data/lua-hooks/ext/lua-cmsgpack/test.lua +570 -0
  76. data/lua-hooks/ext/lua-snapshot/LICENSE +7 -0
  77. data/lua-hooks/ext/lua-snapshot/Makefile +12 -0
  78. data/lua-hooks/ext/lua-snapshot/README.md +18 -0
  79. data/lua-hooks/ext/lua-snapshot/dump.lua +15 -0
  80. data/lua-hooks/ext/lua-snapshot/snapshot.c +455 -0
  81. data/lua-hooks/ext/lua/COPYRIGHT +34 -0
  82. data/lua-hooks/ext/lua/lapi.c +1087 -0
  83. data/lua-hooks/ext/lua/lapi.h +16 -0
  84. data/lua-hooks/ext/lua/lauxlib.c +652 -0
  85. data/lua-hooks/ext/lua/lauxlib.h +174 -0
  86. data/lua-hooks/ext/lua/lbaselib.c +659 -0
  87. data/lua-hooks/ext/lua/lcode.c +831 -0
  88. data/lua-hooks/ext/lua/lcode.h +76 -0
  89. data/lua-hooks/ext/lua/ldblib.c +398 -0
  90. data/lua-hooks/ext/lua/ldebug.c +638 -0
  91. data/lua-hooks/ext/lua/ldebug.h +33 -0
  92. data/lua-hooks/ext/lua/ldo.c +519 -0
  93. data/lua-hooks/ext/lua/ldo.h +57 -0
  94. data/lua-hooks/ext/lua/ldump.c +164 -0
  95. data/lua-hooks/ext/lua/lfunc.c +174 -0
  96. data/lua-hooks/ext/lua/lfunc.h +34 -0
  97. data/lua-hooks/ext/lua/lgc.c +710 -0
  98. data/lua-hooks/ext/lua/lgc.h +110 -0
  99. data/lua-hooks/ext/lua/linit.c +38 -0
  100. data/lua-hooks/ext/lua/liolib.c +556 -0
  101. data/lua-hooks/ext/lua/llex.c +463 -0
  102. data/lua-hooks/ext/lua/llex.h +81 -0
  103. data/lua-hooks/ext/lua/llimits.h +128 -0
  104. data/lua-hooks/ext/lua/lmathlib.c +263 -0
  105. data/lua-hooks/ext/lua/lmem.c +86 -0
  106. data/lua-hooks/ext/lua/lmem.h +49 -0
  107. data/lua-hooks/ext/lua/loadlib.c +705 -0
  108. data/lua-hooks/ext/lua/loadlib_rel.c +760 -0
  109. data/lua-hooks/ext/lua/lobject.c +214 -0
  110. data/lua-hooks/ext/lua/lobject.h +381 -0
  111. data/lua-hooks/ext/lua/lopcodes.c +102 -0
  112. data/lua-hooks/ext/lua/lopcodes.h +268 -0
  113. data/lua-hooks/ext/lua/loslib.c +243 -0
  114. data/lua-hooks/ext/lua/lparser.c +1339 -0
  115. data/lua-hooks/ext/lua/lparser.h +82 -0
  116. data/lua-hooks/ext/lua/lstate.c +214 -0
  117. data/lua-hooks/ext/lua/lstate.h +169 -0
  118. data/lua-hooks/ext/lua/lstring.c +111 -0
  119. data/lua-hooks/ext/lua/lstring.h +31 -0
  120. data/lua-hooks/ext/lua/lstrlib.c +871 -0
  121. data/lua-hooks/ext/lua/ltable.c +588 -0
  122. data/lua-hooks/ext/lua/ltable.h +40 -0
  123. data/lua-hooks/ext/lua/ltablib.c +287 -0
  124. data/lua-hooks/ext/lua/ltm.c +75 -0
  125. data/lua-hooks/ext/lua/ltm.h +54 -0
  126. data/lua-hooks/ext/lua/lua.c +392 -0
  127. data/lua-hooks/ext/lua/lua.def +131 -0
  128. data/lua-hooks/ext/lua/lua.h +388 -0
  129. data/lua-hooks/ext/lua/lua.rc +28 -0
  130. data/lua-hooks/ext/lua/lua_dll.rc +26 -0
  131. data/lua-hooks/ext/lua/luac.c +200 -0
  132. data/lua-hooks/ext/lua/luac.rc +1 -0
  133. data/lua-hooks/ext/lua/luaconf.h +763 -0
  134. data/lua-hooks/ext/lua/luaconf.h.in +724 -0
  135. data/lua-hooks/ext/lua/luaconf.h.orig +763 -0
  136. data/lua-hooks/ext/lua/lualib.h +53 -0
  137. data/lua-hooks/ext/lua/lundump.c +227 -0
  138. data/lua-hooks/ext/lua/lundump.h +36 -0
  139. data/lua-hooks/ext/lua/lvm.c +767 -0
  140. data/lua-hooks/ext/lua/lvm.h +36 -0
  141. data/lua-hooks/ext/lua/lzio.c +82 -0
  142. data/lua-hooks/ext/lua/lzio.h +67 -0
  143. data/lua-hooks/ext/lua/print.c +227 -0
  144. data/lua-hooks/ext/luautf8/README.md +152 -0
  145. data/lua-hooks/ext/luautf8/lutf8lib.c +1274 -0
  146. data/lua-hooks/ext/luautf8/unidata.h +3064 -0
  147. data/lua-hooks/lib/boot.lua +254 -0
  148. data/lua-hooks/lib/encode.lua +4 -0
  149. data/lua-hooks/lib/lexers/LICENSE +21 -0
  150. data/lua-hooks/lib/lexers/bash.lua +134 -0
  151. data/lua-hooks/lib/lexers/bash_dqstr.lua +62 -0
  152. data/lua-hooks/lib/lexers/css.lua +216 -0
  153. data/lua-hooks/lib/lexers/html.lua +106 -0
  154. data/lua-hooks/lib/lexers/javascript.lua +68 -0
  155. data/lua-hooks/lib/lexers/lexer.lua +1575 -0
  156. data/lua-hooks/lib/lexers/markers.lua +33 -0
  157. metadata +308 -0
@@ -0,0 +1,760 @@
1
+ /*
2
+ ** $Id: loadlib.c,v 1.52.1.3 2008/08/06 13:29:28 roberto Exp $
3
+ ** Dynamic library loader for Lua
4
+ ** See Copyright Notice in lua.h
5
+ **
6
+ ** This module contains an implementation of loadlib for Unix systems
7
+ ** that have dlfcn, an implementation for Darwin (Mac OS X), an
8
+ ** implementation for Windows, and a stub for other systems.
9
+ */
10
+
11
+
12
+ #include <stdlib.h>
13
+ #include <string.h>
14
+
15
+
16
+ #define loadlib_c
17
+ #define LUA_LIB
18
+
19
+ #include "lua.h"
20
+
21
+ #include "lauxlib.h"
22
+ #include "lualib.h"
23
+
24
+
25
+ /* prefix for open functions in C libraries */
26
+ #define LUA_POF "luaopen_"
27
+
28
+ /* separator for open functions in C libraries */
29
+ #define LUA_OFSEP "_"
30
+
31
+
32
+ #define LIBPREFIX "LOADLIB: "
33
+
34
+ #define POF LUA_POF
35
+ #define LIB_FAIL "open"
36
+
37
+
38
+ /* error codes for ll_loadfunc */
39
+ #define ERRLIB 1
40
+ #define ERRFUNC 2
41
+
42
+ static void ll_unloadlib (void *lib);
43
+ static void *ll_load (lua_State *L, const char *path);
44
+ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym);
45
+ static void setprogdir (lua_State *L);
46
+
47
+ /*
48
+ ** {=========================================================================
49
+ ** This determines the location of the executable for relative module loading
50
+ ** ==========================================================================
51
+ */
52
+ #if defined(_WIN32) || defined(__CYGWIN__)
53
+ #include <windows.h>
54
+ #define _PATH_MAX MAX_PATH
55
+ #else
56
+ #define _PATH_MAX PATH_MAX
57
+ #endif
58
+
59
+ #if defined(__linux__)
60
+ #include <unistd.h> /* readlink */
61
+ #endif
62
+
63
+ #if defined(__APPLE__)
64
+ #include <sys/param.h>
65
+ #include <mach-o/dyld.h>
66
+ #endif
67
+
68
+ static void setprogdir (lua_State *L) {
69
+ char progdir[_PATH_MAX + 1];
70
+ char *lb;
71
+ int nsize = sizeof(progdir)/sizeof(char);
72
+ int n;
73
+ #if defined(__CYGWIN__)
74
+ char win_buff[_PATH_MAX + 1];
75
+ GetModuleFileNameA(NULL, win_buff, nsize);
76
+ cygwin_conv_to_posix_path(win_buff, progdir);
77
+ n = strlen(progdir);
78
+ #elif defined(_WIN32)
79
+ n = GetModuleFileNameA(NULL, progdir, nsize);
80
+ #elif defined(__linux__)
81
+ n = readlink("/proc/self/exe", progdir, nsize);
82
+ if (n > 0) progdir[n] = 0;
83
+ #elif defined(__FreeBSD__)
84
+ n = readlink("/proc/curproc/file", progdir, nsize);
85
+ if (n > 0) progdir[n] = 0;
86
+ #elif defined(__APPLE__)
87
+ uint32_t nsize_apple = nsize;
88
+ if (_NSGetExecutablePath(progdir, &nsize_apple) == 0)
89
+ n = strlen(progdir);
90
+ #else
91
+ // FALLBACK
92
+ // Use 'lsof' ... should work on most UNIX systems (incl. OSX)
93
+ // lsof will list open files, this captures the 1st file listed (usually the executable)
94
+ int pid;
95
+ FILE* fd;
96
+ char cmd[80];
97
+ pid = getpid();
98
+
99
+ sprintf(cmd, "lsof -p %d | awk '{if ($5==\"REG\") { print $9 ; exit}}' 2> /dev/null", pid);
100
+ fd = popen(cmd, "r");
101
+ n = fread(progdir, 1, nsize, fd);
102
+
103
+ // remove newline
104
+ if (n > 1) progdir[--n] = '\0';
105
+ #endif
106
+ if (n == 0 || n == nsize || (lb = strrchr(progdir, (int)LUA_DIRSEP[0])) == NULL)
107
+ luaL_error(L, "unable to get process executable path");
108
+ else {
109
+ *lb = '\0';
110
+ // Set progdir global
111
+ lua_pushstring(L, progdir);
112
+ lua_setglobal(L, "_PROGDIR");
113
+
114
+ // Replace the relative path placeholder
115
+ luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, progdir);
116
+ lua_remove(L, -2);
117
+ }
118
+ }
119
+
120
+ /* }====================================================== */
121
+
122
+ #if defined(LUA_DL_DLOPEN)
123
+ /*
124
+ ** {========================================================================
125
+ ** This is an implementation of loadlib based on the dlfcn interface.
126
+ ** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
127
+ ** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least
128
+ ** as an emulation layer on top of native functions.
129
+ ** =========================================================================
130
+ */
131
+
132
+ #include <dlfcn.h>
133
+ #include <sys/stat.h>
134
+
135
+ static void ll_unloadlib (void *lib) {
136
+ dlclose(lib);
137
+ }
138
+
139
+ static void *ll_load (lua_State *L, const char *path) {
140
+ void *lib = dlopen(path, RTLD_NOW);
141
+ if (lib == NULL) lua_pushstring(L, dlerror());
142
+ return lib;
143
+ }
144
+
145
+
146
+ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
147
+ lua_CFunction f = (lua_CFunction)dlsym(lib, sym);
148
+ if (f == NULL) lua_pushstring(L, dlerror());
149
+ return f;
150
+ }
151
+
152
+ /* }====================================================== */
153
+
154
+
155
+
156
+ #elif defined(LUA_DL_DLL)
157
+ /*
158
+ ** {======================================================================
159
+ ** This is an implementation of loadlib for Windows using native functions.
160
+ ** =======================================================================
161
+ */
162
+
163
+ #include <windows.h>
164
+
165
+ static void pusherror (lua_State *L) {
166
+ int error = GetLastError();
167
+ char buffer[128];
168
+ if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
169
+ NULL, error, 0, buffer, sizeof(buffer), NULL))
170
+ lua_pushstring(L, buffer);
171
+ else
172
+ lua_pushfstring(L, "system error %d\n", error);
173
+ }
174
+
175
+ static void ll_unloadlib (void *lib) {
176
+ FreeLibrary((HINSTANCE)lib);
177
+ }
178
+
179
+
180
+ static void *ll_load (lua_State *L, const char *path) {
181
+ HINSTANCE lib = LoadLibraryA(path);
182
+ if (lib == NULL) pusherror(L);
183
+ return lib;
184
+ }
185
+
186
+
187
+ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
188
+ lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym);
189
+ if (f == NULL) pusherror(L);
190
+ return f;
191
+ }
192
+
193
+ /* }====================================================== */
194
+
195
+
196
+
197
+ #elif defined(LUA_DL_DYLD)
198
+ /*
199
+ ** {======================================================================
200
+ ** Native Mac OS X / Darwin Implementation
201
+ ** =======================================================================
202
+ */
203
+
204
+ #include <mach-o/dyld.h>
205
+
206
+
207
+ /* Mac appends a `_' before C function names */
208
+ #undef POF
209
+ #define POF "_" LUA_POF
210
+
211
+
212
+ static void pusherror (lua_State *L) {
213
+ const char *err_str;
214
+ const char *err_file;
215
+ NSLinkEditErrors err;
216
+ int err_num;
217
+ NSLinkEditError(&err, &err_num, &err_file, &err_str);
218
+ lua_pushstring(L, err_str);
219
+ }
220
+
221
+
222
+ static const char *errorfromcode (NSObjectFileImageReturnCode ret) {
223
+ switch (ret) {
224
+ case NSObjectFileImageInappropriateFile:
225
+ return "file is not a bundle";
226
+ case NSObjectFileImageArch:
227
+ return "library is for wrong CPU type";
228
+ case NSObjectFileImageFormat:
229
+ return "bad format";
230
+ case NSObjectFileImageAccess:
231
+ return "cannot access file";
232
+ case NSObjectFileImageFailure:
233
+ default:
234
+ return "unable to load library";
235
+ }
236
+ }
237
+
238
+
239
+ static void ll_unloadlib (void *lib) {
240
+ NSUnLinkModule((NSModule)lib, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES);
241
+ }
242
+
243
+
244
+ static void *ll_load (lua_State *L, const char *path) {
245
+ NSObjectFileImage img;
246
+ NSObjectFileImageReturnCode ret;
247
+ /* this would be a rare case, but prevents crashing if it happens */
248
+ if(!_dyld_present()) {
249
+ lua_pushliteral(L, "dyld not present");
250
+ return NULL;
251
+ }
252
+ ret = NSCreateObjectFileImageFromFile(path, &img);
253
+ if (ret == NSObjectFileImageSuccess) {
254
+ NSModule mod = NSLinkModule(img, path, NSLINKMODULE_OPTION_PRIVATE |
255
+ NSLINKMODULE_OPTION_RETURN_ON_ERROR);
256
+ NSDestroyObjectFileImage(img);
257
+ if (mod == NULL) pusherror(L);
258
+ return mod;
259
+ }
260
+ lua_pushstring(L, errorfromcode(ret));
261
+ return NULL;
262
+ }
263
+
264
+
265
+ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
266
+ NSSymbol nss = NSLookupSymbolInModule((NSModule)lib, sym);
267
+ if (nss == NULL) {
268
+ lua_pushfstring(L, "symbol " LUA_QS " not found", sym);
269
+ return NULL;
270
+ }
271
+ return (lua_CFunction)NSAddressOfSymbol(nss);
272
+ }
273
+
274
+ /* }====================================================== */
275
+
276
+
277
+
278
+ #else
279
+ /*
280
+ ** {======================================================
281
+ ** Fallback for other systems
282
+ ** =======================================================
283
+ */
284
+
285
+ #undef LIB_FAIL
286
+ #define LIB_FAIL "absent"
287
+
288
+
289
+ #define DLMSG "dynamic libraries not enabled; check your Lua installation"
290
+
291
+
292
+ static void ll_unloadlib (void *lib) {
293
+ (void)lib; /* to avoid warnings */
294
+ }
295
+
296
+
297
+ static void *ll_load (lua_State *L, const char *path) {
298
+ (void)path; /* to avoid warnings */
299
+ lua_pushliteral(L, DLMSG);
300
+ return NULL;
301
+ }
302
+
303
+
304
+ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
305
+ (void)lib; (void)sym; /* to avoid warnings */
306
+ lua_pushliteral(L, DLMSG);
307
+ return NULL;
308
+ }
309
+
310
+ /* }====================================================== */
311
+ #endif
312
+
313
+
314
+
315
+ static void **ll_register (lua_State *L, const char *path) {
316
+ void **plib;
317
+ lua_pushfstring(L, "%s%s", LIBPREFIX, path);
318
+ lua_gettable(L, LUA_REGISTRYINDEX); /* check library in registry? */
319
+ if (!lua_isnil(L, -1)) /* is there an entry? */
320
+ plib = (void **)lua_touserdata(L, -1);
321
+ else { /* no entry yet; create one */
322
+ lua_pop(L, 1);
323
+ plib = (void **)lua_newuserdata(L, sizeof(const void *));
324
+ *plib = NULL;
325
+ luaL_getmetatable(L, "_LOADLIB");
326
+ lua_setmetatable(L, -2);
327
+ lua_pushfstring(L, "%s%s", LIBPREFIX, path);
328
+ lua_pushvalue(L, -2);
329
+ lua_settable(L, LUA_REGISTRYINDEX);
330
+ }
331
+ return plib;
332
+ }
333
+
334
+
335
+ /*
336
+ ** __gc tag method: calls library's `ll_unloadlib' function with the lib
337
+ ** handle
338
+ */
339
+ static int gctm (lua_State *L) {
340
+ void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB");
341
+ if (*lib) ll_unloadlib(*lib);
342
+ *lib = NULL; /* mark library as closed */
343
+ return 0;
344
+ }
345
+
346
+
347
+ static int ll_loadfunc (lua_State *L, const char *path, const char *sym) {
348
+ void **reg = ll_register(L, path);
349
+ if (*reg == NULL) *reg = ll_load(L, path);
350
+ if (*reg == NULL)
351
+ return ERRLIB; /* unable to load library */
352
+ else {
353
+ lua_CFunction f = ll_sym(L, *reg, sym);
354
+ if (f == NULL)
355
+ return ERRFUNC; /* unable to find function */
356
+ lua_pushcfunction(L, f);
357
+ return 0; /* return function */
358
+ }
359
+ }
360
+
361
+
362
+ static int ll_loadlib (lua_State *L) {
363
+ const char *path = luaL_checkstring(L, 1);
364
+ const char *init = luaL_checkstring(L, 2);
365
+ int stat = ll_loadfunc(L, path, init);
366
+ if (stat == 0) /* no errors? */
367
+ return 1; /* return the loaded function */
368
+ else { /* error; error message is on stack top */
369
+ lua_pushnil(L);
370
+ lua_insert(L, -2);
371
+ lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init");
372
+ return 3; /* return nil, error message, and where */
373
+ }
374
+ }
375
+
376
+
377
+
378
+ /*
379
+ ** {======================================================
380
+ ** 'require' function
381
+ ** =======================================================
382
+ */
383
+
384
+
385
+ static int readable (const char *filename) {
386
+ FILE *f = fopen(filename, "r"); /* try to open file */
387
+ if (f == NULL) return 0; /* open failed */
388
+ fclose(f);
389
+ return 1;
390
+ }
391
+
392
+
393
+ static const char *pushnexttemplate (lua_State *L, const char *path) {
394
+ const char *l;
395
+ while (*path == *LUA_PATHSEP) path++; /* skip separators */
396
+ if (*path == '\0') return NULL; /* no more templates */
397
+ l = strchr(path, *LUA_PATHSEP); /* find next separator */
398
+ if (l == NULL) l = path + strlen(path);
399
+ lua_pushlstring(L, path, l - path); /* template */
400
+ return l;
401
+ }
402
+
403
+ // BACKPORT from lua 5.2 --ol
404
+ static const char *searchpath (lua_State *L, const char *name,
405
+ const char *path,
406
+ const char *sep,
407
+ const char *dirsep) {
408
+ luaL_Buffer msg; /* to build error message */
409
+ luaL_buffinit(L, &msg);
410
+ if (*sep != '\0') /* non-empty separator? */
411
+ name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */
412
+ while ((path = pushnexttemplate(L, path)) != NULL) {
413
+ const char *filename = luaL_gsub(L, lua_tostring(L, -1),
414
+ LUA_PATH_MARK, name);
415
+ lua_remove(L, -2); /* remove path template */
416
+ if (readable(filename)) /* does file exist and is readable? */
417
+ return filename; /* return that file name */
418
+ lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
419
+ lua_remove(L, -2); /* remove file name */
420
+ luaL_addvalue(&msg); /* concatenate error msg. entry */
421
+ }
422
+ luaL_pushresult(&msg); /* create error message */
423
+ return NULL; /* not found */
424
+ }
425
+
426
+
427
+ static int ll_searchpath (lua_State *L) {
428
+ const char *f = searchpath(L, luaL_checkstring(L, 1),
429
+ luaL_checkstring(L, 2),
430
+ luaL_optstring(L, 3, "."),
431
+ luaL_optstring(L, 4, LUA_DIRSEP));
432
+ if (f != NULL) return 1;
433
+ else { /* error message is on top of the stack */
434
+ lua_pushnil(L);
435
+ lua_insert(L, -2);
436
+ return 2; /* return nil + error message */
437
+ }
438
+ }
439
+
440
+ // END BACKPORT
441
+
442
+ static const char *findfile (lua_State *L, const char *name,
443
+ const char *pname) {
444
+ const char *path;
445
+ name = luaL_gsub(L, name, ".", LUA_DIRSEP);
446
+ lua_getfield(L, LUA_ENVIRONINDEX, pname);
447
+ path = lua_tostring(L, -1);
448
+ if (path == NULL)
449
+ luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
450
+ lua_pushliteral(L, ""); /* error accumulator */
451
+ while ((path = pushnexttemplate(L, path)) != NULL) {
452
+ const char *filename;
453
+ filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name);
454
+ lua_remove(L, -2); /* remove path template */
455
+ if (readable(filename)) /* does file exist and is readable? */
456
+ return filename; /* return that file name */
457
+ lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
458
+ lua_remove(L, -2); /* remove file name */
459
+ lua_concat(L, 2); /* add entry to possible error message */
460
+ }
461
+ return NULL; /* not found */
462
+ }
463
+
464
+
465
+ static void loaderror (lua_State *L, const char *filename) {
466
+ luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s",
467
+ lua_tostring(L, 1), filename, lua_tostring(L, -1));
468
+ }
469
+
470
+
471
+ static int loader_Lua (lua_State *L) {
472
+ const char *filename;
473
+ const char *name = luaL_checkstring(L, 1);
474
+ filename = findfile(L, name, "path");
475
+ if (filename == NULL) return 1; /* library not found in this path */
476
+ if (luaL_loadfile(L, filename) != 0)
477
+ loaderror(L, filename);
478
+ return 1; /* library loaded successfully */
479
+ }
480
+
481
+
482
+ static const char *mkfuncname (lua_State *L, const char *modname) {
483
+ const char *funcname;
484
+ const char *mark = strchr(modname, *LUA_IGMARK);
485
+ if (mark) modname = mark + 1;
486
+ funcname = luaL_gsub(L, modname, ".", LUA_OFSEP);
487
+ funcname = lua_pushfstring(L, POF"%s", funcname);
488
+ lua_remove(L, -2); /* remove 'gsub' result */
489
+ return funcname;
490
+ }
491
+
492
+
493
+ static int loader_C (lua_State *L) {
494
+ const char *funcname;
495
+ const char *name = luaL_checkstring(L, 1);
496
+ const char *filename = findfile(L, name, "cpath");
497
+ if (filename == NULL) return 1; /* library not found in this path */
498
+ funcname = mkfuncname(L, name);
499
+ if (ll_loadfunc(L, filename, funcname) != 0)
500
+ loaderror(L, filename);
501
+ return 1; /* library loaded successfully */
502
+ }
503
+
504
+
505
+ static int loader_Croot (lua_State *L) {
506
+ const char *funcname;
507
+ const char *filename;
508
+ const char *name = luaL_checkstring(L, 1);
509
+ const char *p = strchr(name, '.');
510
+ int stat;
511
+ if (p == NULL) return 0; /* is root */
512
+ lua_pushlstring(L, name, p - name);
513
+ filename = findfile(L, lua_tostring(L, -1), "cpath");
514
+ if (filename == NULL) return 1; /* root not found */
515
+ funcname = mkfuncname(L, name);
516
+ if ((stat = ll_loadfunc(L, filename, funcname)) != 0) {
517
+ if (stat != ERRFUNC) loaderror(L, filename); /* real error */
518
+ lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
519
+ name, filename);
520
+ return 1; /* function not found */
521
+ }
522
+ return 1;
523
+ }
524
+
525
+
526
+ static int loader_preload (lua_State *L) {
527
+ const char *name = luaL_checkstring(L, 1);
528
+ lua_getfield(L, LUA_ENVIRONINDEX, "preload");
529
+ if (!lua_istable(L, -1))
530
+ luaL_error(L, LUA_QL("package.preload") " must be a table");
531
+ lua_getfield(L, -1, name);
532
+ if (lua_isnil(L, -1)) /* not found? */
533
+ lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
534
+ return 1;
535
+ }
536
+
537
+
538
+ static const int sentinel_ = 0;
539
+ #define sentinel ((void *)&sentinel_)
540
+
541
+
542
+ static int ll_require (lua_State *L) {
543
+ const char *name = luaL_checkstring(L, 1);
544
+ int i;
545
+ lua_settop(L, 1); /* _LOADED table will be at index 2 */
546
+ lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
547
+ lua_getfield(L, 2, name);
548
+ if (lua_toboolean(L, -1)) { /* is it there? */
549
+ if (lua_touserdata(L, -1) == sentinel) /* check loops */
550
+ luaL_error(L, "loop or previous error loading module " LUA_QS, name);
551
+ return 1; /* package is already loaded */
552
+ }
553
+ /* else must load it; iterate over available loaders */
554
+ lua_getfield(L, LUA_ENVIRONINDEX, "loaders");
555
+ if (!lua_istable(L, -1))
556
+ luaL_error(L, LUA_QL("package.loaders") " must be a table");
557
+ lua_pushliteral(L, ""); /* error message accumulator */
558
+ for (i=1; ; i++) {
559
+ lua_rawgeti(L, -2, i); /* get a loader */
560
+ if (lua_isnil(L, -1))
561
+ luaL_error(L, "module " LUA_QS " not found:%s",
562
+ name, lua_tostring(L, -2));
563
+ lua_pushstring(L, name);
564
+ lua_call(L, 1, 1); /* call it */
565
+ if (lua_isfunction(L, -1)) /* did it find module? */
566
+ break; /* module loaded successfully */
567
+ else if (lua_isstring(L, -1)) /* loader returned error message? */
568
+ lua_concat(L, 2); /* accumulate it */
569
+ else
570
+ lua_pop(L, 1);
571
+ }
572
+ lua_pushlightuserdata(L, sentinel);
573
+ lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */
574
+ lua_pushstring(L, name); /* pass name as argument to module */
575
+ lua_call(L, 1, 1); /* run loaded module */
576
+ if (!lua_isnil(L, -1)) /* non-nil return? */
577
+ lua_setfield(L, 2, name); /* _LOADED[name] = returned value */
578
+ lua_getfield(L, 2, name);
579
+ if (lua_touserdata(L, -1) == sentinel) { /* module did not set a value? */
580
+ lua_pushboolean(L, 1); /* use true as result */
581
+ lua_pushvalue(L, -1); /* extra copy to be returned */
582
+ lua_setfield(L, 2, name); /* _LOADED[name] = true */
583
+ }
584
+ return 1;
585
+ }
586
+
587
+ /* }====================================================== */
588
+
589
+
590
+
591
+ /*
592
+ ** {======================================================
593
+ ** 'module' function
594
+ ** =======================================================
595
+ */
596
+
597
+
598
+ static void setfenv (lua_State *L) {
599
+ lua_Debug ar;
600
+ if (lua_getstack(L, 1, &ar) == 0 ||
601
+ lua_getinfo(L, "f", &ar) == 0 || /* get calling function */
602
+ lua_iscfunction(L, -1))
603
+ luaL_error(L, LUA_QL("module") " not called from a Lua function");
604
+ lua_pushvalue(L, -2);
605
+ lua_setfenv(L, -2);
606
+ lua_pop(L, 1);
607
+ }
608
+
609
+
610
+ static void dooptions (lua_State *L, int n) {
611
+ int i;
612
+ for (i = 2; i <= n; i++) {
613
+ lua_pushvalue(L, i); /* get option (a function) */
614
+ lua_pushvalue(L, -2); /* module */
615
+ lua_call(L, 1, 0);
616
+ }
617
+ }
618
+
619
+
620
+ static void modinit (lua_State *L, const char *modname) {
621
+ const char *dot;
622
+ lua_pushvalue(L, -1);
623
+ lua_setfield(L, -2, "_M"); /* module._M = module */
624
+ lua_pushstring(L, modname);
625
+ lua_setfield(L, -2, "_NAME");
626
+ dot = strrchr(modname, '.'); /* look for last dot in module name */
627
+ if (dot == NULL) dot = modname;
628
+ else dot++;
629
+ /* set _PACKAGE as package name (full module name minus last part) */
630
+ lua_pushlstring(L, modname, dot - modname);
631
+ lua_setfield(L, -2, "_PACKAGE");
632
+ }
633
+
634
+
635
+ static int ll_module (lua_State *L) {
636
+ const char *modname = luaL_checkstring(L, 1);
637
+ int loaded = lua_gettop(L) + 1; /* index of _LOADED table */
638
+ lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
639
+ lua_getfield(L, loaded, modname); /* get _LOADED[modname] */
640
+ if (!lua_istable(L, -1)) { /* not found? */
641
+ lua_pop(L, 1); /* remove previous result */
642
+ /* try global variable (and create one if it does not exist) */
643
+ if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL)
644
+ return luaL_error(L, "name conflict for module " LUA_QS, modname);
645
+ lua_pushvalue(L, -1);
646
+ lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */
647
+ }
648
+ /* check whether table already has a _NAME field */
649
+ lua_getfield(L, -1, "_NAME");
650
+ if (!lua_isnil(L, -1)) /* is table an initialized module? */
651
+ lua_pop(L, 1);
652
+ else { /* no; initialize it */
653
+ lua_pop(L, 1);
654
+ modinit(L, modname);
655
+ }
656
+ lua_pushvalue(L, -1);
657
+ setfenv(L);
658
+ dooptions(L, loaded - 1);
659
+ return 0;
660
+ }
661
+
662
+
663
+ static int ll_seeall (lua_State *L) {
664
+ luaL_checktype(L, 1, LUA_TTABLE);
665
+ if (!lua_getmetatable(L, 1)) {
666
+ lua_createtable(L, 0, 1); /* create new metatable */
667
+ lua_pushvalue(L, -1);
668
+ lua_setmetatable(L, 1);
669
+ }
670
+ lua_pushvalue(L, LUA_GLOBALSINDEX);
671
+ lua_setfield(L, -2, "__index"); /* mt.__index = _G */
672
+ return 0;
673
+ }
674
+
675
+
676
+ /* }====================================================== */
677
+
678
+
679
+
680
+ /* auxiliary mark (for internal use) */
681
+ #define AUXMARK "\1"
682
+
683
+ static void setpath (lua_State *L, const char *fieldname, const char *envname,
684
+ const char *def) {
685
+ const char *path = getenv(envname);
686
+ if (path == NULL) /* no environment variable? */
687
+ lua_pushstring(L, def); /* use default */
688
+ else {
689
+ /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
690
+ path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP,
691
+ LUA_PATHSEP AUXMARK LUA_PATHSEP);
692
+ luaL_gsub(L, path, AUXMARK, def);
693
+ lua_remove(L, -2);
694
+ }
695
+ setprogdir(L);
696
+ lua_setfield(L, -2, fieldname);
697
+ }
698
+
699
+
700
+ static const luaL_Reg pk_funcs[] = {
701
+ {"loadlib", ll_loadlib},
702
+ // BACKPORT from 5.2 --ol
703
+ {"searchpath", ll_searchpath},
704
+ // END BACKPORT
705
+ {"seeall", ll_seeall},
706
+ {NULL, NULL}
707
+ };
708
+
709
+
710
+ static const luaL_Reg ll_funcs[] = {
711
+ {"module", ll_module},
712
+ {"require", ll_require},
713
+ {NULL, NULL}
714
+ };
715
+
716
+
717
+ static const lua_CFunction loaders[] =
718
+ {loader_preload, loader_Lua, loader_C, loader_Croot, NULL};
719
+
720
+
721
+ LUALIB_API int luaopen_package (lua_State *L) {
722
+ int i;
723
+ /* create new type _LOADLIB */
724
+ luaL_newmetatable(L, "_LOADLIB");
725
+ lua_pushcfunction(L, gctm);
726
+ lua_setfield(L, -2, "__gc");
727
+ /* create `package' table */
728
+ luaL_register(L, LUA_LOADLIBNAME, pk_funcs);
729
+ #if defined(LUA_COMPAT_LOADLIB)
730
+ lua_getfield(L, -1, "loadlib");
731
+ lua_setfield(L, LUA_GLOBALSINDEX, "loadlib");
732
+ #endif
733
+ lua_pushvalue(L, -1);
734
+ lua_replace(L, LUA_ENVIRONINDEX);
735
+ /* create `loaders' table */
736
+ lua_createtable(L, sizeof(loaders)/sizeof(loaders[0]) - 1, 0);
737
+ /* fill it with pre-defined loaders */
738
+ for (i=0; loaders[i] != NULL; i++) {
739
+ lua_pushcfunction(L, loaders[i]);
740
+ lua_rawseti(L, -2, i+1);
741
+ }
742
+ lua_setfield(L, -2, "loaders"); /* put it in field `loaders' */
743
+ setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT); /* set field `path' */
744
+ setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT); /* set field `cpath' */
745
+ /* store config information */
746
+ lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n"
747
+ LUA_EXECDIR "\n" LUA_IGMARK);
748
+ lua_setfield(L, -2, "config");
749
+ /* set field `loaded' */
750
+ luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 2);
751
+ lua_setfield(L, -2, "loaded");
752
+ /* set field `preload' */
753
+ lua_newtable(L);
754
+ lua_setfield(L, -2, "preload");
755
+ lua_pushvalue(L, LUA_GLOBALSINDEX);
756
+ luaL_register(L, NULL, ll_funcs); /* open lib into global table */
757
+ lua_pop(L, 1);
758
+ return 1; /* return 'package' table */
759
+ }
760
+