1 /* Lua bindings for Newserv */
3 /* Copyright (C) Chris Porter 2005 */
4 /* ALL RIGHTS RESERVED. */
5 /* Don't put this into the SVN repo. */
7 #define _POSIX_C_SOURCE 200112L
8 #define _DEFAULT_SOURCE
11 #include "../core/config.h"
12 #include "../core/error.h"
13 #include "../core/hooks.h"
14 #include "../lib/array.h"
15 #include "../lib/irc_string.h"
16 #include "../core/schedule.h"
17 #include "../lib/version.h"
18 #include "../lib/strlfunc.h"
21 MODULE_VERSION(LUA_SMALLVERSION
);
23 #ifdef LUA_DEBUGSOCKET
25 #include <sys/types.h>
26 #include <sys/socket.h>
27 #include <netinet/in.h>
28 #include <arpa/inet.h>
35 void lua_startup(void *arg
);
36 void lua_loadscripts(void);
37 void lua_registercommands(lua_State
*l
);
38 void lua_initnickpusher(void);
39 void lua_initchanpusher(void);
40 void lua_loadlibs(lua_State
*l
);
41 void lua_require(lua_State
*l
, char *module);
43 void lua_startbot(void *arg
);
44 void lua_destroybot(void);
45 void lua_startcontrol(void);
46 void lua_destroycontrol(void);
48 void lua_onunload(lua_State
*l
);
49 void lua_onload(lua_State
*l
);
51 void lua_setpath(void);
53 void lua_setupdebugsocket(void);
54 void lua_freedebugsocket(void);
56 void lua_deregisternicks(lua_list
*l
);
57 void lua_registerlocalcommands(lua_State
*ps
);
58 void lua_registerdebug(lua_State
*ps
);
59 void lua_socket_closeall(lua_list
*l
);
60 void lua_scheduler_freeall(lua_list
*l
);
61 void lua_registersocketcommands(lua_State
*ps
);
62 void lua_registercryptocommands(lua_State
*ps
);
63 void lua_registerschedulercommands(lua_State
*ps
);
65 void lua_registerdbcommands(lua_list
*l
);
66 void lua_destroydb(lua_list
*l
);
68 #ifdef LUA_DEBUGSOCKET
70 struct sockaddr_in debugsocketdest
;
75 lua_list
*lua_head
= NULL
, *lua_tail
= NULL
;
77 sstring
*cpath
= NULL
, *suffix
= NULL
;
79 void *startsched
= NULL
;
83 struct rusage r_usages
;
84 struct rusage r_usagee
;
86 static const luaL_Reg ourlibs
[] = {
88 {LUA_LOADLIBNAME
, luaopen_package
},
89 {LUA_TABLIBNAME
, luaopen_table
},
90 {LUA_IOLIBNAME
, luaopen_io
},
91 {LUA_OSLIBNAME
, luaopen_os
},
92 {LUA_STRLIBNAME
, luaopen_string
},
93 {LUA_MATHLIBNAME
, luaopen_math
},
95 {LUA_JITLIBNAME
, luaopen_jit
},
103 lua_setupdebugsocket();
104 lua_initnickpusher();
105 lua_initchanpusher();
107 dummy
.name
= getsstring("???", 10);
109 Error("lua", ERR_ERROR
, "Cannot set dummy name.");
113 cpath
= getcopyconfigitem("lua", "scriptdir", "", 500);
115 if(!cpath
|| !cpath
->content
|| !cpath
->content
[0]) {
116 Error("lua", ERR_ERROR
, "Error loading path.");
120 suffix
= getcopyconfigitem("lua", "scriptsuffix", ".lua", 10);
122 Error("lua", ERR_ERROR
, "Error loading suffix.");
130 startsched
= scheduleoneshot(time(NULL
) + 1, &lua_startup
, NULL
);
133 void lua_startup(void *arg
) {
142 #ifdef BROKEN_DLCLOSE
150 deleteschedule(startsched
, &lua_startup
, NULL
);
153 lua_unloadscript(lua_head
);
156 lua_destroycontrol();
161 freesstring(dummy
.name
);
163 lua_freedebugsocket();
164 nscheckfreeall(POOL_LUA
);
167 void lua_loadscripts(void) {
170 ls
= getconfigitems("lua", "script");
172 Error("lua", ERR_INFO
, "No scripts loaded.");
174 sstring
**scripts
= (sstring
**)(ls
->content
);
176 for(i
=0;i
<ls
->cursi
;i
++)
177 lua_loadscript(scripts
[i
]->content
);
181 /* taken from the lua manual, modified to use nsmalloc */
182 static void *lua_nsmalloc(void *ud
, void *ptr
, size_t osize
, size_t nsize
) {
189 return luarealloc(ptr
, nsize
);
192 lua_State
*lua_loadscript(char *file
) {
193 char fullpath
[LUA_PATHLEN
];
200 if(!cpath
|| !suffix
)
203 strlcpy(buf
, file
, sizeof(buf
));
205 delchars(buf
, "./\\;");
207 if(lua_scriptloaded(buf
))
210 l
= lua_newstate(lua_nsmalloc
, NULL
);
214 n
= (lua_list
*)luamalloc(sizeof(lua_list
));;
216 Error("lua", ERR_ERROR
, "Error allocing list for %s.", buf
);
220 n
->name
= getsstring(buf
, LUA_PATHLEN
);
222 Error("lua", ERR_ERROR
, "Error allocing name item for %s.", buf
);
228 timerclear(&n
->ru_utime
);
229 timerclear(&n
->ru_stime
);
234 lua_registerdebug(l
);
235 lua_registercommands(l
);
236 lua_registerlocalcommands(l
);
237 lua_registerdbcommands(n
);
238 lua_registersocketcommands(l
);
239 lua_registercryptocommands(l
);
240 lua_registerschedulercommands(l
);
244 triggerhook(HOOK_LUA_LOADSCRIPT
, args
);
247 lua_require(l
, "lib/jit");
250 lua_require(l
, "lib/bootstrap");
252 snprintf(fullpath
, sizeof(fullpath
), "%s/%s%s", cpath
->content
, file
, suffix
->content
);
253 if(luaL_loadfile(l
, fullpath
)) {
254 Error("lua", ERR_ERROR
, "Error loading %s.", file
);
256 freesstring(n
->name
);
265 n
->schedulers
= NULL
;
277 if(lua_pcall(l
, 0, 0, 0)) {
278 Error("lua", ERR_ERROR
, "Error pcalling: %s.", file
);
280 freesstring(n
->name
);
287 lua_tail
->next
= NULL
;
295 Error("lua", ERR_INFO
, "Loaded %s.", file
);
301 void lua_unloadscript(lua_list
*l
) {
302 triggerhook(HOOK_LUA_UNLOADSCRIPT
, l
->l
);
305 lua_deregisternicks(l
);
306 lua_socket_closeall(l
);
307 lua_scheduler_freeall(l
);
310 freesstring(l
->name
);
312 /* well, at least it's O(1) */
314 if(!l
->prev
) { /* head */
319 lua_head
->prev
= NULL
;
322 if(!l
->next
) { /* tail */
323 lua_tail
= lua_tail
->prev
;
327 lua_tail
->next
= NULL
;
330 l
->prev
->next
= l
->next
;
331 l
->next
->prev
= l
->prev
;
338 void lua_setpath(void) {
339 char fullpath
[LUA_PATHLEN
];
341 snprintf(fullpath
, sizeof(fullpath
), "%s/?%s", cpath
->content
, suffix
->content
);
342 setenv("LUA_PATH", fullpath
, 1);
345 lua_list
*lua_scriptloaded(char *name
) {
348 for(l
=lua_head
;l
;l
=l
->next
)
349 if(!strcmp(l
->name
->content
, name
))
355 void lua_loadlibs(lua_State
*l
) {
356 const luaL_Reg
*lib
= ourlibs
;
358 for (;lib
->func
;lib
++) {
359 lua_pushcfunction(l
, lib
->func
);
360 lua_pushstring(l
, lib
->name
);
365 void lua_require(lua_State
*l
, char *module) {
366 int top
= lua_gettop(l
);
368 lua_getglobal(l
, "require");
369 lua_pushstring(l
, module);
371 if(lua_pcall(l
, 1, 1, 0))
372 Error("lua", ERR_ERROR
, "Error requiring %s: %s", module, lua_tostring(l
, -1));
377 void lua_setupdebugsocket(void) {
378 #ifdef LUA_DEBUGSOCKET
380 debugsocket
= socket(AF_INET
, SOCK_DGRAM
, 0);
381 if(debugsocket
< 0) {
383 Error("lua", ERR_ERROR
, "Cannot create debug socket.");
388 memset(&debugsocketdest
, 0, sizeof(debugsocketdest
));
390 debugsocketdest
.sin_family
= AF_INET
;
391 debugsocketdest
.sin_port
= htons(LUA_DEBUGSOCKET_PORT
);
392 debugsocketdest
.sin_addr
.s_addr
= inet_addr(LUA_DEBUGSOCKET_ADDRESS
);
397 void lua_freedebugsocket(void) {
398 #ifdef LUA_DEBUGSOCKET
400 if(debugsocket
== -1)
411 #ifdef LUA_DEBUGSOCKET
412 void lua_debugoutput(char *format
, ...) {
417 if(debugsocket
== -1)
420 va_start(va
, format
);
421 size
= vsnprintf(buf
, sizeof(buf
), format
, va
);
424 if(size
>= sizeof(buf
))
425 size
= sizeof(buf
) - 1;
428 sendto(debugsocket
, buf
, size
, 0, (struct sockaddr
*)&debugsocketdest
, sizeof(debugsocketdest
));
432 lua_list
*lua_listfromstate(lua_State
*l
) {
433 lua_list
*i
= lua_head
;
441 int lua_listexists(lua_list
*l
) {
444 for(i
=lua_head
;i
;i
=i
->next
)
451 int lua_lineok(const char *data
) {
452 if(strchr(data
, '\r') || strchr(data
, '\n'))
457 int lua_debugpcall(lua_State
*l
, char *message
, int a
, int b
, int c
) {
458 lua_list
*l2
= lua_listfromstate(l
);
461 #ifdef LUA_DEBUGSOCKET
462 DEBUGOUT("%s: %s\n", l2
->name
->content
, message
);
466 ACCOUNTING_START(l2
);
469 ret
= lua_pcall(l
, a
, b
, c
);