author | Tero Marttila <terom@fixme.fi> |
Mon, 04 May 2009 20:55:04 +0300 | |
branch | new-transport |
changeset 168 | a58ad50911fc |
parent 145 | a5582e1a83da |
child 180 | 22967b165692 |
permissions | -rw-r--r-- |
116 | 1 |
#include "lua_irc.h" |
143 | 2 |
#include "lua_func.h" |
116 | 3 |
|
4 |
#include <stdlib.h> |
|
5 |
#include <string.h> |
|
6 |
||
145 | 7 |
static struct lua_type lua_chan_type = LUA_TYPE("evirc.chan"); |
8 |
||
116 | 9 |
/** |
10 |
* Create a lua_chan userdata from the given irc_chan and leave it on the stack, returning 1 |
|
11 |
*/ |
|
12 |
static int lua_chan_create (lua_State *L, struct irc_chan *chan) |
|
13 |
{ |
|
14 |
// create the new obj |
|
145 | 15 |
struct lua_chan *lua_chan = lua_type_create(L, &lua_chan_type, sizeof(*lua_chan)); |
116 | 16 |
|
17 |
// initialize |
|
18 |
lua_chan->chan = chan; |
|
19 |
||
20 |
// ok |
|
21 |
return 1; |
|
22 |
} |
|
23 |
||
24 |
/** |
|
25 |
* Return the channel name as a lua string |
|
26 |
*/ |
|
145 | 27 |
static struct lua_func lua_chan__tostring_func = LUA_FUNC(&lua_chan_type, "__tostring", |
28 |
"format using channel name", |
|
29 |
||
30 |
LUA_FUNC_ARG_END |
|
31 |
); |
|
32 |
||
33 |
static int lua_chan__tostring (lua_State *L) |
|
116 | 34 |
{ |
145 | 35 |
struct lua_chan *lua_chan; |
36 |
||
37 |
lua_args_parse(L, &lua_chan__tostring_func, (void *) &lua_chan); |
|
116 | 38 |
|
39 |
lua_pushfstring(L, "<irc_chan %s>", irc_chan_name(lua_chan->chan)); |
|
40 |
||
41 |
return 1; |
|
42 |
} |
|
43 |
||
44 |
/** |
|
45 |
* Send a PRIVMSG to the channel |
|
46 |
*/ |
|
145 | 47 |
static struct lua_func lua_chan_say_func = LUA_FUNC(&lua_chan_type, "evirc.chan.say", |
48 |
"send a message to a channel", |
|
49 |
||
50 |
LUA_FUNC_ARG_STRING("message", LUA_ARG_STRING_REQUIRED ) |
|
51 |
); |
|
52 |
||
116 | 53 |
static int lua_chan_say (lua_State *L) |
54 |
{ |
|
145 | 55 |
struct lua_chan *lua_chan; |
116 | 56 |
err_t err; |
145 | 57 |
const char *message; |
116 | 58 |
|
145 | 59 |
// parse args |
60 |
lua_args_parse(L, &lua_chan_say_func, (void *) &lua_chan, |
|
61 |
&message |
|
62 |
); |
|
116 | 63 |
|
64 |
// send |
|
65 |
if ((err = irc_chan_PRIVMSG(lua_chan->chan, message))) |
|
66 |
return luaL_error(L, "irc_chan_PRIVMSG: '%s': %s", message, error_name(err)); |
|
67 |
||
68 |
// ok |
|
69 |
return 0; |
|
70 |
} |
|
71 |
||
145 | 72 |
static struct lua_method lua_chan_methods[] = LUA_METHODS( |
73 |
LUA_METHOD("__tostring", lua_chan__tostring, &lua_chan__tostring_func ), |
|
74 |
LUA_METHOD("say", lua_chan_say, &lua_chan_say_func ) |
|
75 |
); |
|
116 | 76 |
|
145 | 77 |
|
78 |
||
79 |
static struct lua_type lua_net_type = LUA_TYPE("evirc.net"); |
|
116 | 80 |
|
81 |
/** |
|
82 |
* Create a lua_net userdata from the given irc_net and push it onto the stack, returning 1. |
|
83 |
*/ |
|
84 |
static int lua_net_create (lua_State *L, struct irc_net *net) |
|
85 |
{ |
|
86 |
// create the new obj |
|
145 | 87 |
struct lua_net *lua_net = lua_type_create(L, &lua_net_type, sizeof(*lua_net)); |
116 | 88 |
|
89 |
// initialize |
|
90 |
lua_net->net = net; |
|
91 |
||
92 |
// ok |
|
93 |
return 1; |
|
94 |
} |
|
95 |
||
96 |
/** |
|
97 |
* Return the network name as a lua string |
|
98 |
*/ |
|
145 | 99 |
static struct lua_func lua_net__tostring_func = LUA_FUNC(&lua_net_type, "__tostring", |
100 |
"format using network name", |
|
101 |
||
102 |
LUA_FUNC_ARG_END |
|
103 |
); |
|
104 |
||
105 |
static int lua_net__tostring (lua_State *L) |
|
116 | 106 |
{ |
145 | 107 |
struct lua_net *lua_net; |
108 |
||
109 |
lua_args_parse(L, &lua_net__tostring_func, (void *) &lua_net); |
|
116 | 110 |
|
111 |
lua_pushfstring(L, "<irc_net %s>", irc_net_name(lua_net->net)); |
|
112 |
||
113 |
return 1; |
|
114 |
} |
|
115 |
||
116 |
/** |
|
117 |
* Join a new channel, returning the lua_chan |
|
118 |
*/ |
|
145 | 119 |
static struct lua_func lua_net_join_func = LUA_FUNC(&lua_net_type, "join", |
120 |
"create a new channel and join it", |
|
121 |
||
122 |
LUA_FUNC_ARG_STRING("channel", LUA_ARG_STRING_REQUIRED) |
|
123 |
); |
|
124 |
||
125 |
||
116 | 126 |
static int lua_net_join (lua_State *L) |
127 |
{ |
|
145 | 128 |
struct lua_net *lua_net; |
116 | 129 |
struct irc_chan_info chan_info; |
130 |
struct irc_chan *chan; |
|
131 |
struct error_info err; |
|
132 |
||
133 |
// the channel name |
|
145 | 134 |
lua_args_parse(L, &lua_net_join_func, (void *) &lua_net, |
135 |
&chan_info.channel |
|
136 |
); |
|
116 | 137 |
|
138 |
// add it |
|
139 |
if (irc_net_add_chan(lua_net->net, &chan, &chan_info, &err)) |
|
140 |
return luaL_error(L, "irc_net_add_chan: %s: %s", chan_info.channel, error_msg(&err)); |
|
141 |
||
142 |
// return it |
|
143 |
return lua_chan_create(L, chan); |
|
144 |
} |
|
145 |
||
146 |
/** |
|
147 |
* Look up a channel by name, returning the lua_chan |
|
148 |
*/ |
|
145 | 149 |
static struct lua_func lua_net_get_chan_func = LUA_FUNC(&lua_net_type, "channel", |
150 |
"look up a channel by name", |
|
151 |
||
152 |
LUA_FUNC_ARG_STRING("channel", LUA_ARG_STRING_REQUIRED) |
|
153 |
); |
|
154 |
||
116 | 155 |
static int lua_net_get_chan (lua_State *L) |
156 |
{ |
|
145 | 157 |
struct lua_net *lua_net; |
116 | 158 |
struct irc_chan *chan; |
145 | 159 |
const char *channel; |
160 |
||
161 |
// parse args |
|
162 |
lua_args_parse(L, &lua_net_get_chan_func, (void *) &lua_net, |
|
163 |
&channel |
|
164 |
); |
|
116 | 165 |
|
166 |
// lookup the irc_chan |
|
167 |
if ((chan = irc_net_get_chan(lua_net->net, channel)) == NULL) |
|
168 |
return luaL_error(L, "irc_net_get_chan: no such channel: %s", channel); |
|
169 |
||
170 |
// wrap it |
|
171 |
return lua_chan_create(L, chan); |
|
172 |
} |
|
173 |
||
145 | 174 |
static struct lua_method lua_net_methods[] = LUA_METHODS( |
175 |
LUA_METHOD("__tostring", lua_net__tostring, &lua_net__tostring_func ), |
|
176 |
LUA_METHOD("join", lua_net_join, &lua_net_join_func ), |
|
177 |
LUA_METHOD("channel", lua_net_get_chan, &lua_net_get_chan_func ) |
|
178 |
); |
|
116 | 179 |
|
180 |
||
145 | 181 |
|
182 |
static struct lua_type lua_client_type = LUA_TYPE("evirc.client"); |
|
183 |
||
184 |
||
185 |
static struct lua_func lua_client_set_defaults_func = LUA_FUNC(&lua_client_type, "set_defaults", |
|
143 | 186 |
"set the default settings to use for evirc.client.connect", |
187 |
||
188 |
LUA_FUNC_ARG_STRING("nickname", LUA_ARG_STRING_REQUIRED ), |
|
189 |
LUA_FUNC_ARG_STRING("username", LUA_ARG_STRING_REQUIRED ), |
|
190 |
LUA_FUNC_ARG_STRING("realname", LUA_ARG_STRING_REQUIRED ), |
|
191 |
LUA_FUNC_ARG_STRING("service", IRC_PORT ), |
|
192 |
LUA_FUNC_ARG_STRING("service_ssl", IRC_SSL_PORT ) |
|
145 | 193 |
); |
143 | 194 |
|
116 | 195 |
static int lua_client_set_defaults (lua_State *L) |
196 |
{ |
|
143 | 197 |
struct lua_client *lua_client; |
198 |
const char *nickname, *username, *realname, *service, *service_ssl; |
|
116 | 199 |
|
143 | 200 |
// parse args |
201 |
lua_args_parse(L, &lua_client_set_defaults_func, (void *) &lua_client, |
|
145 | 202 |
&nickname, &username, &realname, &service, &service_ssl |
203 |
); |
|
116 | 204 |
|
143 | 205 |
// set |
206 |
struct irc_client_defaults defaults = { |
|
207 |
.register_info = { |
|
208 |
.nickname = nickname, |
|
209 |
.username = username, |
|
210 |
.realname = realname |
|
211 |
}, |
|
212 |
.service = service, |
|
213 |
.service_ssl = service_ssl |
|
214 |
}; |
|
116 | 215 |
|
216 |
// invoke |
|
143 | 217 |
// XXX: needs to be copied |
218 |
irc_client_set_defaults(lua_client->client, &defaults); |
|
116 | 219 |
|
220 |
// ok |
|
221 |
return 0; |
|
222 |
} |
|
223 |
||
145 | 224 |
static struct lua_func lua_client_connect_func = LUA_FUNC(&lua_client_type, "connect", |
143 | 225 |
"Create and return a new IRC network", |
226 |
||
227 |
LUA_FUNC_ARG_STRING("network", LUA_ARG_STRING_REQUIRED ), |
|
228 |
LUA_FUNC_ARG_STRING("hostname", LUA_ARG_STRING_REQUIRED ), |
|
229 |
LUA_FUNC_ARG_STRING("service", NULL ), |
|
230 |
LUA_FUNC_ARG_BOOL( "ssl", false ), |
|
231 |
LUA_FUNC_ARG_STRING("ssl_cafile", NULL ), |
|
232 |
LUA_FUNC_ARG_BOOL( "ssl_verify", false ), |
|
233 |
LUA_FUNC_ARG_STRING("ssl_cert", NULL ), |
|
234 |
LUA_FUNC_ARG_STRING("ssl_pkey", NULL ) |
|
235 |
); |
|
236 |
||
116 | 237 |
static int lua_client_connect (lua_State *L) |
238 |
{ |
|
143 | 239 |
struct lua_client *lua_client; |
116 | 240 |
struct irc_net_info net_info; |
141
0b850238c588
implement SSL stuff for lua_client_connect
Tero Marttila <terom@fixme.fi>
parents:
131
diff
changeset
|
241 |
const char *ssl_cafile = NULL, *ssl_cert = NULL, *ssl_pkey = NULL; |
0b850238c588
implement SSL stuff for lua_client_connect
Tero Marttila <terom@fixme.fi>
parents:
131
diff
changeset
|
242 |
bool use_ssl = false, ssl_verify = false; |
116 | 243 |
struct irc_net *net; |
244 |
struct error_info err; |
|
245 |
||
246 |
// init net_info |
|
247 |
memset(&net_info, 0, sizeof(net_info)); |
|
248 |
||
143 | 249 |
// parse args |
250 |
lua_args_parse(L, &lua_client_connect_func, (void *) &lua_client, |
|
251 |
&net_info.network, &net_info.hostname, &net_info.service, |
|
252 |
&use_ssl, &ssl_cafile, &ssl_verify, &ssl_cert, &ssl_pkey |
|
253 |
); |
|
141
0b850238c588
implement SSL stuff for lua_client_connect
Tero Marttila <terom@fixme.fi>
parents:
131
diff
changeset
|
254 |
|
0b850238c588
implement SSL stuff for lua_client_connect
Tero Marttila <terom@fixme.fi>
parents:
131
diff
changeset
|
255 |
// SSL? |
0b850238c588
implement SSL stuff for lua_client_connect
Tero Marttila <terom@fixme.fi>
parents:
131
diff
changeset
|
256 |
if (use_ssl || ssl_cafile || ssl_verify || ssl_cert || ssl_pkey) { |
0b850238c588
implement SSL stuff for lua_client_connect
Tero Marttila <terom@fixme.fi>
parents:
131
diff
changeset
|
257 |
// verify |
0b850238c588
implement SSL stuff for lua_client_connect
Tero Marttila <terom@fixme.fi>
parents:
131
diff
changeset
|
258 |
if ((ssl_cert || ssl_pkey) && !(ssl_cert && ssl_pkey)) |
0b850238c588
implement SSL stuff for lua_client_connect
Tero Marttila <terom@fixme.fi>
parents:
131
diff
changeset
|
259 |
return luaL_error(L, "must give both ssl_cert and ssl_pkey"); |
0b850238c588
implement SSL stuff for lua_client_connect
Tero Marttila <terom@fixme.fi>
parents:
131
diff
changeset
|
260 |
|
0b850238c588
implement SSL stuff for lua_client_connect
Tero Marttila <terom@fixme.fi>
parents:
131
diff
changeset
|
261 |
// create |
0b850238c588
implement SSL stuff for lua_client_connect
Tero Marttila <terom@fixme.fi>
parents:
131
diff
changeset
|
262 |
if (sock_ssl_client_cred_create(&net_info.ssl_cred, ssl_cafile, ssl_verify, ssl_cert, ssl_pkey, &err)) |
0b850238c588
implement SSL stuff for lua_client_connect
Tero Marttila <terom@fixme.fi>
parents:
131
diff
changeset
|
263 |
return luaL_error(L, "sock_ssl_client_cred_create(ssl_cafile=%s, ssl_verify=%b, ssl_cert=%s, ssl_pkey=%s): %s", |
0b850238c588
implement SSL stuff for lua_client_connect
Tero Marttila <terom@fixme.fi>
parents:
131
diff
changeset
|
264 |
ssl_cafile, ssl_verify, ssl_cert, ssl_pkey, error_msg(&err) |
0b850238c588
implement SSL stuff for lua_client_connect
Tero Marttila <terom@fixme.fi>
parents:
131
diff
changeset
|
265 |
); |
0b850238c588
implement SSL stuff for lua_client_connect
Tero Marttila <terom@fixme.fi>
parents:
131
diff
changeset
|
266 |
} |
116 | 267 |
|
268 |
// create it |
|
269 |
if (irc_client_add_net(lua_client->client, &net, &net_info, &err)) |
|
270 |
return luaL_error(L, "irc_client_add_net: %s/%s: %s", net_info.network, net_info.hostname, error_msg(&err)); |
|
271 |
||
272 |
// wrap it |
|
273 |
return lua_net_create(L, net); |
|
274 |
} |
|
275 |
||
145 | 276 |
static struct lua_func lua_client_get_network_func = LUA_FUNC(&lua_client_type, "network", |
277 |
"Lookup an existing network by name", |
|
278 |
||
279 |
LUA_FUNC_ARG_STRING("network", LUA_ARG_STRING_REQUIRED) |
|
280 |
); |
|
281 |
||
116 | 282 |
static int lua_client_get_network (lua_State *L) |
283 |
{ |
|
145 | 284 |
struct lua_client *lua_client; |
116 | 285 |
struct irc_net *net; |
145 | 286 |
const char *network; |
287 |
||
288 |
// parse args |
|
289 |
lua_args_parse(L, &lua_client_get_network_func, (void *) &lua_client, |
|
290 |
&network |
|
291 |
); |
|
116 | 292 |
|
293 |
// lookup the irc_net |
|
294 |
if ((net = irc_client_get_net(lua_client->client, network)) == NULL) |
|
295 |
return luaL_error(L, "irc_client_get_net: no such network: %s", network); |
|
296 |
||
297 |
// wrap it |
|
298 |
return lua_net_create(L, net); |
|
299 |
} |
|
300 |
||
145 | 301 |
static struct lua_func lua_client_quit_func = LUA_FUNC(&lua_client_type, "quit", |
302 |
"Disconnect from all networks", |
|
303 |
||
304 |
LUA_FUNC_ARG_STRING("message", "Bye") |
|
305 |
); |
|
306 |
||
116 | 307 |
static int lua_client_quit (lua_State *L) |
308 |
{ |
|
145 | 309 |
struct lua_client *lua_client; |
116 | 310 |
err_t err; |
145 | 311 |
const char *message; |
312 |
||
313 |
// parse args |
|
314 |
lua_args_parse(L, &lua_client_quit_func, (void *) &lua_client, |
|
315 |
&message |
|
316 |
); |
|
116 | 317 |
|
318 |
// execute |
|
319 |
if ((err = irc_client_quit(lua_client->client, message))) |
|
320 |
return luaL_error(L, "irc_client_quit: %s", error_name(err)); |
|
321 |
||
322 |
// ok |
|
323 |
return 0; |
|
324 |
} |
|
325 |
||
145 | 326 |
static struct lua_method lua_client_methods[] = LUA_METHODS( |
327 |
LUA_METHOD("set_defaults", lua_client_set_defaults, &lua_client_set_defaults_func ), |
|
328 |
LUA_METHOD("connect", lua_client_connect, &lua_client_connect_func ), |
|
329 |
LUA_METHOD("network", lua_client_get_network, &lua_client_get_network_func ), |
|
330 |
LUA_METHOD("quit", lua_client_quit, &lua_client_quit_func ) |
|
331 |
); |
|
116 | 332 |
|
333 |
void lua_irc_init (struct nexus_lua *lua) |
|
334 |
{ |
|
145 | 335 |
// register types |
336 |
lua_type_register(lua->st, &lua_chan_type, lua_chan_methods); |
|
337 |
lua_type_register(lua->st, &lua_net_type, lua_net_methods); |
|
338 |
||
339 |
// register the global "client" object |
|
340 |
struct lua_client *lua_client = lua_type_register_global(lua->st, &lua_client_type, lua_client_methods, "client", sizeof(*lua_client)); |
|
341 |
||
342 |
// initialize it |
|
343 |
lua_client->client = lua->nexus->client; |
|
116 | 344 |
} |
345 |