]> jfr.im git - irc/quakenet/newserv.git/blob - lua/luacommands.c
r729@blue (orig r504): slug | 2006-06-09 14:02:53 +0100
[irc/quakenet/newserv.git] / lua / luacommands.c
1 /* Copyright (C) Chris Porter 2005-2006 */
2 /* ALL RIGHTS RESERVED. */
3 /* Don't put this into the SVN repo. */
4
5 /*
6 @todo
7 - Write a nick printf type thing for pcalled functions.
8 - Make commands register as apposed to blinding calling.
9 - Use numerics instead of huge structures, and add lookup functions.
10 */
11
12 #include "../channel/channel.h"
13 #include "../control/control.h"
14 #include "../nick/nick.h"
15 #include "../localuser/localuser.h"
16 #include "../localuser/localuserchannel.h"
17 #include "../lib/irc_string.h"
18
19 #include "lua.h"
20 #include "luabot.h"
21
22 #include <stdarg.h>
23 #include <stddef.h>
24
25 #define MAX_PUSHER 50
26
27 static int lua_smsg(lua_State *ps);
28 static int lua_skill(lua_State *ps);
29
30 typedef struct lua_pusher {
31 short argtype;
32 short offset;
33 const char *structname;
34 } lua_pusher;
35
36 struct lua_pusher nickpusher[MAX_PUSHER];
37 struct lua_pusher chanpusher[MAX_PUSHER];
38 int nickpushercount, chanpushercount;
39
40 INLINE void lua_setuppusher(struct lua_pusher *pusherlist, lua_State *l, int index, struct lua_pusher **lp, int max, int pcount);
41 INLINE int lua_usepusher(lua_State *l, struct lua_pusher **lp, void *np);
42
43 void lua_initnickpusher(void);
44 void lua_initchanpusher(void);
45
46 #define lua_setupnickpusher(L2, I2, P2, M2) lua_setuppusher(&nickpusher[0], L2, I2, P2, M2, nickpushercount)
47 #define lua_setupchanpusher(L2, I2, P2, M2) lua_setuppusher(&chanpusher[0], L2, I2, P2, M2, chanpushercount)
48
49 int lua_cmsg(char *channell, char *message, ...) {
50 char buf[512];
51 va_list va;
52 channel *cp;
53
54 va_start(va, message);
55 vsnprintf(buf, sizeof(buf), message, va);
56 va_end(va);
57
58 cp = findchannel(channell);
59 if(!cp)
60 return LUA_FAIL;
61
62 if(!lua_lineok(buf))
63 return LUA_FAIL;
64
65 lua_channelmessage(cp, "%s", buf);
66
67 return LUA_OK;
68 }
69
70 static int lua_chanmsg(lua_State *ps) {
71 if(!lua_isstring(ps, 1))
72 LUA_RETURN(ps, LUA_FAIL);
73
74 LUA_RETURN(ps, lua_cmsg(LUA_PUKECHAN, "lua: %s", lua_tostring(ps, 1)));
75 }
76
77 static int lua_ctcp(lua_State *ps) {
78 const char *n, *msg;
79 nick *np;
80
81 if(!lua_isstring(ps, 1) || !lua_isstring(ps, 2))
82 LUA_RETURN(ps, LUA_FAIL);
83
84 n = lua_tostring(ps, 1);
85 msg = lua_tostring(ps, 2);
86
87 np = getnickbynick(n);
88 if(!np || !lua_lineok(msg))
89 LUA_RETURN(ps, LUA_FAIL);
90
91 lua_message(np, "\001%s\001", msg);
92
93 LUA_RETURN(ps, lua_cmsg(LUA_PUKECHAN, "lua-ctcp: %s (%s)", np->nick, msg));
94 }
95
96 static int lua_noticecmd(lua_State *ps) {
97 const char *n, *msg;
98 nick *np;
99
100 if(!lua_isstring(ps, 1) || !lua_isstring(ps, 2))
101 LUA_RETURN(ps, LUA_FAIL);
102
103 n = lua_tostring(ps, 1);
104 msg = lua_tostring(ps, 2);
105
106 np = getnickbynick(n);
107 if(!np || !lua_lineok(msg))
108 LUA_RETURN(ps, LUA_FAIL);
109
110 lua_notice(np, "%s", msg);
111
112 LUA_RETURN(ps, LUA_OK);
113 }
114
115 static int lua_privmsgcmd(lua_State *ps) {
116 const char *n, *msg;
117 nick *np;
118
119 if(!lua_isstring(ps, 1) || !lua_isstring(ps, 2))
120 LUA_RETURN(ps, LUA_FAIL);
121
122 n = lua_tostring(ps, 1);
123 msg = lua_tostring(ps, 2);
124
125 np = getnickbynick(n);
126 if(!np || !lua_lineok(msg))
127 LUA_RETURN(ps, LUA_FAIL);
128
129 lua_message(np, "%s", msg);
130
131 LUA_RETURN(ps, LUA_OK);
132 }
133
134 static int lua_kill(lua_State *ps) {
135 const char *n, *msg;
136 nick *np;
137
138 if(!lua_isstring(ps, 1) || !lua_isstring(ps, 2))
139 LUA_RETURN(ps, LUA_FAIL);
140
141 n = lua_tostring(ps, 1);
142 msg = lua_tostring(ps, 2);
143
144 np = getnickbynick(n);
145 if(!np)
146 LUA_RETURN(ps, LUA_FAIL);
147
148 if(IsOper(np) || IsService(np) || IsXOper(np))
149 LUA_RETURN(ps, LUA_FAIL);
150
151 if(!lua_lineok(msg))
152 LUA_RETURN(ps, LUA_FAIL);
153
154 killuser(lua_nick, np, "%s", msg);
155
156 LUA_RETURN(ps, lua_cmsg(LUA_PUKECHAN, "lua-KILL: %s (%s)", np->nick, msg));
157 }
158
159 static int lua_kick(lua_State *ps) {
160 const char *n, *msg, *chan;
161 nick *np;
162 channel *cp;
163 int dochecks = 1;
164
165 if(!lua_isstring(ps, 1) || !lua_isstring(ps, 2) || !lua_isstring(ps, 3))
166 LUA_RETURN(ps, LUA_FAIL);
167
168 chan = lua_tostring(ps, 1);
169 n = lua_tostring(ps, 2);
170 msg = lua_tostring(ps, 3);
171
172 if(lua_isboolean(ps, 4) && !lua_toboolean(ps, 4))
173 dochecks = 0;
174
175 np = getnickbynick(n);
176 if(!np)
177 LUA_RETURN(ps, LUA_FAIL);
178
179 if(dochecks && (IsOper(np) || IsXOper(np) || IsService(np)))
180 LUA_RETURN(ps, LUA_FAIL);
181
182 cp = findchannel((char *)chan);
183 if(!cp)
184 LUA_RETURN(ps, LUA_FAIL);
185
186 if(!lua_lineok(msg))
187 LUA_RETURN(ps, LUA_FAIL);
188
189 localkickuser(lua_nick, cp, np, msg);
190
191 LUA_RETURN(ps, LUA_OK);
192 }
193
194 static int lua_invite(lua_State *ps) {
195 nick *np;
196 channel *cp;
197
198 if(!lua_isstring(ps, 1) || !lua_isstring(ps, 2))
199 LUA_RETURN(ps, LUA_FAIL);
200
201 np = getnickbynick((char *)lua_tostring(ps, 1));
202 if(!np)
203 LUA_RETURN(ps, LUA_FAIL);
204
205 cp = findchannel((char *)lua_tostring(ps, 2));
206 if(!cp)
207 LUA_RETURN(ps, LUA_FAIL);
208
209 localinvite(lua_nick, cp, np);
210
211 LUA_RETURN(ps, LUA_OK);
212 }
213
214 static int lua_gline(lua_State *ps) {
215 const char *reason;
216 nick *target;
217 char mask[512];
218 int duration, usercount = 0;
219 host *hp;
220
221 if(!lua_isstring(ps, 1) || !lua_isint(ps, 2) || !lua_isstring(ps, 3))
222 LUA_RETURN(ps, LUA_FAIL);
223
224 duration = lua_toint(ps, 2);
225 if((duration < 1) || (duration > 31 * 86400))
226 LUA_RETURN(ps, LUA_FAIL);
227
228 reason = lua_tostring(ps, 3);
229 if(!lua_lineok(reason) || !reason)
230 LUA_RETURN(ps, LUA_FAIL);
231
232 target = getnickbynick(lua_tostring(ps, 1));
233 if(!target || (IsOper(target) || IsXOper(target) || IsService(target)))
234 LUA_RETURN(ps, LUA_FAIL);
235
236 hp = target->host;
237 if(!hp)
238 LUA_RETURN(ps, LUA_FAIL);
239
240 usercount = hp->clonecount;
241 if(usercount > 10) { /* (decent) trusted host */
242 int j;
243 nick *np;
244
245 usercount = 0;
246
247 for (j=0;j<NICKHASHSIZE;j++)
248 for (np=nicktable[j];np;np=np->next)
249 if (np && (np->host == hp) && (!ircd_strcmp(np->ident, target->ident)))
250 usercount++;
251
252 if(usercount > 50)
253 LUA_RETURN(ps, LUA_FAIL);
254
255 snprintf(mask, sizeof(mask), "*%s@%s", target->ident, IPtostr(target->ipaddress));
256 } else {
257 snprintf(mask, sizeof(mask), "*@%s", IPtostr(target->ipaddress));
258 }
259
260 irc_send("%s GL * +%s %d :%s", mynumeric->content, mask, duration, reason);
261 LUA_RETURN(ps, lua_cmsg(LUA_PUKECHAN, "lua-GLINE: %s (%d users, %d seconds -- %s)", mask, usercount, duration, reason));
262 }
263
264 static int lua_getchaninfo(lua_State *ps) {
265 channel *cp;
266
267 if(!lua_isstring(ps, 1))
268 return 0;
269
270 cp = findchannel((char *)lua_tostring(ps, 1));
271 if(!cp)
272 return 0;
273
274 LUA_PUSHCHAN(ps, cp);
275
276 return 1;
277 }
278
279 static int lua_opchan(lua_State *ps) {
280 channel *cp;
281 nick *np;
282
283 if(!lua_isstring(ps, 1) || !lua_isstring(ps, 2))
284 LUA_RETURN(ps, LUA_FAIL);
285
286 cp = findchannel((char *)lua_tostring(ps, 1));
287 if(!cp)
288 LUA_RETURN(ps, LUA_FAIL);
289
290 np = getnickbynick((char *)lua_tostring(ps, 2));
291 if(!np)
292 LUA_RETURN(ps, LUA_FAIL);
293
294 localsetmodes(lua_nick, cp, np, MC_OP);
295 LUA_RETURN(ps, LUA_OK);
296 }
297
298 static int lua_deopchan(lua_State *ps) {
299 channel *cp;
300 nick *np;
301
302 if(!lua_isstring(ps, 1) || !lua_isstring(ps, 2))
303 LUA_RETURN(ps, LUA_FAIL);
304
305 cp = findchannel((char *)lua_tostring(ps, 1));
306 if(!cp)
307 LUA_RETURN(ps, LUA_FAIL);
308
309 np = getnickbynick((char *)lua_tostring(ps, 2));
310 if(!np)
311 LUA_RETURN(ps, LUA_FAIL);
312
313 localsetmodes(lua_nick, cp, np, MC_DEOP);
314 LUA_RETURN(ps, LUA_OK);
315 }
316
317 static int lua_voicechan(lua_State *ps) {
318 channel *cp;
319 nick *np;
320
321 if(!lua_isstring(ps, 1) || !lua_isstring(ps, 2))
322 LUA_RETURN(ps, LUA_FAIL);
323
324 cp = findchannel((char *)lua_tostring(ps, 1));
325 if(!cp)
326 LUA_RETURN(ps, LUA_FAIL);
327
328 np = getnickbynick((char *)lua_tostring(ps, 2));
329 if(!np)
330 LUA_RETURN(ps, LUA_FAIL);
331
332 localsetmodes(lua_nick, cp, np, MC_VOICE);
333 LUA_RETURN(ps, LUA_OK);
334 }
335
336 static int lua_counthost(lua_State *ps) {
337 long numeric;
338 nick *np;
339
340 if(!lua_islong(ps, 1))
341 return 0;
342
343 numeric = lua_tolong(ps, 1);
344
345 np = getnickbynumeric(numeric);
346 if(!np)
347 return 0;
348
349 lua_pushint(ps, np->host->clonecount);
350 return 1;
351 }
352
353 static int lua_versioninfo(lua_State *ps) {
354 lua_pushstring(ps, LUA_VERSION);
355 lua_pushstring(ps, LUA_BOTVERSION);
356 lua_pushstring(ps, __DATE__);
357 lua_pushstring(ps, __TIME__);
358
359 lua_pushstring(ps, LUA_AUXVERSION);
360
361 return 5;
362 }
363
364 static int lua_basepath(lua_State *ps) {
365 lua_pushfstring(ps, "%s/", cpath->content);
366
367 return 1;
368 }
369
370 /* O(n) */
371 static int lua_getuserbyauth(lua_State *l) {
372 const char *acc;
373 nick *np;
374 int i, found = 0;
375
376 if(!lua_isstring(l, 1))
377 return 0;
378
379 acc = lua_tostring(l, 1);
380
381 for(i=0;i<NICKHASHSIZE;i++) {
382 for(np=nicktable[i];np;np=np->next) {
383 if(np && np->authname && !ircd_strcmp(np->authname, acc)) {
384 LUA_PUSHNICK(l, np);
385 found++;
386 }
387 }
388 }
389
390 return found;
391 }
392
393 static int lua_getnickchans(lua_State *l) {
394 nick *np;
395 int i;
396 channel **channels;
397
398 if(!lua_islong(l, 1))
399 return 0;
400
401 np = getnickbynumeric(lua_tolong(l, 1));
402 if(!np)
403 return 0;
404
405 channels = (channel **)np->channels->content;
406 for(i=0;i<np->channels->cursi;i++)
407 lua_pushstring(l, channels[i]->index->name->content);
408
409 return np->channels->cursi;
410 }
411
412 static int lua_getnickchanindex(lua_State *l) {
413 nick *np;
414 int offset;
415
416 if(!lua_islong(l, 1) || !lua_isint(l, 2))
417 return 0;
418
419 np = getnickbynumeric(lua_tolong(l, 1));
420 if(!np)
421 return 0;
422
423 offset = lua_toint(l, 2);
424 if((offset < 0) || (offset >= np->channels->cursi))
425 return 0;
426
427 lua_pushstring(l, ((channel **)np->channels->content)[offset]->index->name->content);
428
429 return 1;
430 }
431
432 int hashindex;
433 nick *lasthashnick;
434
435 struct lua_pusher *nickhashpusher[MAX_PUSHER];
436
437 static int lua_getnextnick(lua_State *l) {
438 if(!lasthashnick && (hashindex != -1))
439 return 0;
440
441 do {
442 if(!lasthashnick) {
443 hashindex++;
444 if(hashindex >= NICKHASHSIZE)
445 return 0;
446 lasthashnick = nicktable[hashindex];
447 } else {
448 lasthashnick = lasthashnick->next;
449 }
450 } while(!lasthashnick);
451
452 return lua_usepusher(l, nickhashpusher, lasthashnick);
453 }
454
455 static int lua_getfirstnick(lua_State *l) {
456 hashindex = -1;
457 lasthashnick = NULL;
458
459 lua_setupnickpusher(l, 1, nickhashpusher, MAX_PUSHER);
460
461 return lua_getnextnick(l);
462 }
463
464 int chanhashindex;
465 chanindex *lasthashchan;
466
467 struct lua_pusher *chanhashpusher[MAX_PUSHER];
468
469 static int lua_getnextchan(lua_State *l) {
470 if(!lasthashchan && (chanhashindex != -1))
471 return 0;
472
473 do {
474 if(!lasthashchan) {
475 chanhashindex++;
476 if(chanhashindex >= CHANNELHASHSIZE)
477 return 0;
478 lasthashchan = chantable[chanhashindex];
479 } else {
480 lasthashchan = lasthashchan->next;
481 }
482 } while(!lasthashchan || !lasthashchan->channel);
483
484 return lua_usepusher(l, chanhashpusher, lasthashchan);
485 }
486
487 static int lua_getfirstchan(lua_State *l) {
488 chanhashindex = -1;
489 lasthashchan = NULL;
490
491 lua_setupchanpusher(l, 1, chanhashpusher, MAX_PUSHER);
492
493 return lua_getnextchan(l);
494 }
495
496 static int lua_getnickchancount(lua_State *l) {
497 nick *np;
498
499 if(!lua_islong(l, 1))
500 return 0;
501
502 np = getnickbynumeric(lua_tolong(l, 1));
503 if(!np)
504 return 0;
505
506 lua_pushint(l, np->channels->cursi);
507
508 return 1;
509 }
510
511 static int lua_gethostusers(lua_State *l) {
512 nick *np;
513 int count;
514
515 if(!lua_islong(l, 1))
516 return 0;
517
518 np = getnickbynumeric(lua_tolong(l, 1));
519 if(!np || !np->host || !np->host->nicks)
520 return 0;
521
522 np = np->host->nicks;
523 count = np->host->clonecount;
524
525 do {
526 LUA_PUSHNICK(l, np);
527 np = np->nextbyhost;
528 } while(np);
529
530 return count;
531 }
532
533 static int lua_getnickcountry(lua_State *l) {
534 nick *np;
535 int ext;
536
537 ext = findnickext("geoip");
538 if(ext == -1)
539 return 0;
540
541 if(!lua_islong(l, 1))
542 return 0;
543
544 np = getnickbynumeric(lua_tolong(l, 1));
545 if(!np)
546 return 0;
547
548 lua_pushint(l, (int)np->exts[ext]);
549 return 1;
550 }
551
552 static int lua_chanfix(lua_State *ps) {
553 channel *cp;
554 nick *np;
555
556 if(!lua_isstring(ps, 1))
557 LUA_RETURN(ps, LUA_FAIL);
558
559 cp = findchannel((char *)lua_tostring(ps, 1));
560 if(!cp || !cp->index)
561 LUA_RETURN(ps, LUA_FAIL);
562
563 np = getnickbynick(LUA_CHANFIXBOT);
564 if(!np)
565 LUA_RETURN(ps, LUA_FAIL);
566
567 lua_message(np, "chanfix %s", cp->index->name->content);
568
569 LUA_RETURN(ps, LUA_OK);
570 }
571
572 static int lua_clearmode(lua_State *ps) {
573 channel *cp;
574 int i;
575 nick *np;
576 unsigned long *lp;
577 modechanges changes;
578
579 if(!lua_isstring(ps, 1))
580 LUA_RETURN(ps, LUA_FAIL);
581
582 cp = findchannel((char *)lua_tostring(ps, 1));
583 if(!cp || !cp->users)
584 LUA_RETURN(ps, LUA_FAIL);
585
586 localsetmodeinit(&changes, cp, lua_nick);
587
588 localdosetmode_key(&changes, NULL, MCB_DEL);
589 localdosetmode_simple(&changes, 0, CHANMODE_INVITEONLY | CHANMODE_LIMIT);
590
591 while(cp->bans)
592 localdosetmode_ban(&changes, bantostring(cp->bans), MCB_DEL);
593
594 for(i=0,lp=cp->users->content;i<cp->users->hashsize;i++,lp++)
595 if((*lp != nouser) && (*lp & CUMODE_OP)) {
596 np = getnickbynumeric(*lp);
597 if(np && !IsService(np))
598 localdosetmode_nick(&changes, np, MC_DEOP);
599 }
600
601 localsetmodeflush(&changes, 1);
602
603 LUA_RETURN(ps, LUA_OK);
604 }
605
606 static int lua_ban(lua_State *ps) {
607 channel *cp;
608 const char *mask;
609 modechanges changes;
610 int dir = MCB_ADD;
611
612 if(!lua_isstring(ps, 1) || !lua_isstring(ps, 2))
613 LUA_RETURN(ps, LUA_FAIL);
614
615 if(lua_isboolean(ps, 3) && lua_toboolean(ps, 3))
616 dir = MCB_DEL;
617
618 cp = findchannel((char *)lua_tostring(ps, 1));
619 if(!cp)
620 LUA_RETURN(ps, LUA_FAIL);
621
622 mask = lua_tostring(ps, 2);
623 if(!mask || !mask[0] || !lua_lineok(mask))
624 LUA_RETURN(ps, LUA_FAIL);
625
626 localsetmodeinit(&changes, cp, lua_nick);
627 localdosetmode_ban(&changes, mask, dir);
628 localsetmodeflush(&changes, 1);
629
630 LUA_RETURN(ps, LUA_OK);
631 }
632
633 static int lua_topic(lua_State *ps) {
634 channel *cp;
635 char *topic;
636
637 if(!lua_isstring(ps, 1) || !lua_isstring(ps, 2))
638 LUA_RETURN(ps, LUA_FAIL);
639
640 cp = findchannel((char *)lua_tostring(ps, 1));
641 if(!cp)
642 LUA_RETURN(ps, LUA_FAIL);
643
644 topic = (char *)lua_tostring(ps, 2);
645 if(!topic || !lua_lineok(topic))
646 LUA_RETURN(ps, LUA_FAIL);
647
648 localsettopic(lua_nick, cp, topic);
649
650 LUA_RETURN(ps, LUA_OK);
651 }
652
653 static int lua_getuserchanmodes(lua_State *l) {
654 nick *np;
655 channel *cp;
656 unsigned long *lp;
657
658 if(!lua_islong(l, 1) || !lua_isstring(l, 2))
659 return 0;
660
661 np = getnickbynumeric(lua_tolong(l, 1));
662 if(!np)
663 return 0;
664
665 cp = findchannel((char *)lua_tostring(l, 2));
666 if(!cp || !cp->users)
667 return 0;
668
669 lp = getnumerichandlefromchanhash(cp->users, np->numeric);
670 if(!lp)
671 return 0;
672
673 LUA_PUSHNICKCHANMODES(l, lp);
674 return 1;
675 }
676
677 static int lua_getusermodes(lua_State *l) {
678 nick *np;
679
680 if(!lua_islong(l, 1))
681 return 0;
682
683 np = getnickbynumeric(lua_tolong(l, 1));
684 if(!np)
685 return 0;
686
687 lua_pushstring(l, printflags(np->umodes, umodeflags));
688 return 1;
689 }
690
691 static int lua_getnickbynick(lua_State *l) {
692 nick *np;
693
694 if(!lua_isstring(l, 1))
695 return 0;
696
697 np = getnickbynick(lua_tostring(l, 1));
698 if(!np)
699 return 0;
700
701 LUA_PUSHNICK(l, np);
702 return 1;
703 }
704
705 static int lua_getnickbynumeric(lua_State *l) {
706 nick *np;
707
708 if(!lua_islong(l, 1))
709 return 0;
710
711 np = getnickbynumeric(lua_tolong(l, 1));
712 if(!np)
713 return 0;
714
715 LUA_PUSHNICK(l, np);
716 return 1;
717 }
718
719 static int lua_fastgetnickbynumeric(lua_State *l) {
720 static struct lua_pusher *ourpusher[MAX_PUSHER];
721 nick *np;
722
723 if(!lua_islong(l, 1))
724 return 0;
725
726 np = getnickbynumeric(lua_tolong(l, 1));
727 if(!np)
728 return 0;
729
730 lua_setupnickpusher(l, 2, ourpusher, MAX_PUSHER);
731 return lua_usepusher(l, ourpusher, np);
732 }
733
734 int channelnicklistindex, channelnicklistcount = -1;
735 channel *channelnicklist;
736
737 struct lua_pusher *channelnickpusher[MAX_PUSHER];
738
739 static int lua_getnextchannick(lua_State *l) {
740 nick *np;
741
742 do {
743 channelnicklistindex++;
744
745 if(channelnicklistindex >= channelnicklistcount)
746 return 0;
747 } while((channelnicklist->users->content[channelnicklistindex] == nouser) || !(np = getnickbynumeric(channelnicklist->users->content[channelnicklistindex])));
748
749 return lua_usepusher(l, channelnickpusher, np);
750 }
751
752 static int lua_getfirstchannick(lua_State *l) {
753 if(!lua_isstring(l, 1))
754 return 0;
755
756 channelnicklist = findchannel((char *)lua_tostring(l, 1));
757 if(!channelnicklist|| !channelnicklist->users)
758 return 0;
759
760 channelnicklistindex = -1;
761 channelnicklistcount = channelnicklist->users->hashsize;
762
763 lua_setupnickpusher(l, 2, channelnickpusher, MAX_PUSHER);
764
765 return lua_getnextchannick(l);
766 }
767
768 static int lua_nickonchan(lua_State *l) {
769 int success = 0;
770 if(lua_islong(l, 1) && lua_isstring(l, 2)) {
771 channel *cp = findchannel((char *)lua_tostring(l, 2));
772 if(cp && cp->users) {
773 unsigned long *lp = getnumerichandlefromchanhash(cp->users, lua_tolong(l, 1));
774 if(lp)
775 success = 1;
776 }
777 }
778
779 lua_pushboolean(l, success);
780 return 1;
781 }
782
783 void lua_registercommands(lua_State *l) {
784 lua_register(l, "irc_smsg", lua_smsg);
785 lua_register(l, "irc_skill", lua_skill);
786
787 lua_register(l, "chanmsg", lua_chanmsg);
788 lua_register(l, "versioninfo", lua_versioninfo);
789 lua_register(l, "basepath", lua_basepath);
790
791 lua_register(l, "irc_report", lua_chanmsg);
792 lua_register(l, "irc_ctcp", lua_ctcp);
793 lua_register(l, "irc_kill", lua_kill);
794 lua_register(l, "irc_kick", lua_kick);
795 lua_register(l, "irc_invite", lua_invite);
796 lua_register(l, "irc_gline", lua_gline);
797 lua_register(l, "irc_getchaninfo", lua_getchaninfo);
798 lua_register(l, "irc_counthost", lua_counthost);
799 lua_register(l, "irc_getuserbyauth", lua_getuserbyauth);
800 lua_register(l, "irc_notice", lua_noticecmd);
801 lua_register(l, "irc_privmsg", lua_privmsgcmd);
802 lua_register(l, "irc_opchan", lua_opchan);
803 lua_register(l, "irc_voicechan", lua_voicechan);
804 lua_register(l, "irc_chanfix", lua_chanfix);
805 lua_register(l, "irc_clearmode", lua_clearmode);
806 lua_register(l, "irc_ban", lua_ban);
807 lua_register(l, "irc_deopchan", lua_deopchan);
808 lua_register(l, "irc_topic", lua_topic);
809
810 lua_register(l, "irc_getnickbynick", lua_getnickbynick);
811 lua_register(l, "irc_getnickbynumeric", lua_getnickbynumeric);
812 lua_register(l, "irc_getfirstnick", lua_getfirstnick);
813 lua_register(l, "irc_getnextnick", lua_getnextnick);
814
815 lua_register(l, "irc_getnickchans", lua_getnickchans);
816 lua_register(l, "irc_getnickchanindex", lua_getnickchanindex);
817 lua_register(l, "irc_getnickchancount", lua_getnickchancount);
818
819 lua_register(l, "irc_getuserchanmodes", lua_getuserchanmodes);
820
821 lua_register(l, "irc_getfirstchannick", lua_getfirstchannick);
822 lua_register(l, "irc_getnextchannick", lua_getnextchannick);
823
824 lua_register(l, "irc_gethostusers", lua_gethostusers);
825 lua_register(l, "irc_getnickcountry", lua_getnickcountry);
826
827 lua_register(l, "irc_getfirstchan", lua_getfirstchan);
828 lua_register(l, "irc_getnextchan", lua_getnextchan);
829 lua_register(l, "irc_getusermodes", lua_getusermodes);
830 lua_register(l, "irc_nickonchan", lua_nickonchan);
831
832 lua_register(l, "irc_fastgetnickbynumeric", lua_fastgetnickbynumeric);
833 }
834
835 /* --- */
836
837 static int lua_smsg(lua_State *ps) {
838 if(!lua_isstring(ps, 1) || !lua_isstring(ps, 2))
839 LUA_RETURN(ps, LUA_FAIL);
840
841 LUA_RETURN(ps, lua_cmsg((char *)lua_tostring(ps, 2), "%s", lua_tostring(ps, 1)));
842 }
843
844 static int lua_skill(lua_State *ps) {
845 const char *n, *msg;
846 nick *np;
847
848 if(!lua_isstring(ps, 1) || !lua_isstring(ps, 2))
849 LUA_RETURN(ps, LUA_FAIL);
850
851 n = lua_tostring(ps, 1);
852 msg = lua_tostring(ps, 2);
853
854 np = getnickbynick(n);
855 if(!np)
856 LUA_RETURN(ps, LUA_FAIL);
857
858 if(IsOper(np) || IsService(np) || IsXOper(np))
859 LUA_RETURN(ps, LUA_FAIL);
860
861 if(!lua_lineok(msg))
862 LUA_RETURN(ps, LUA_FAIL);
863
864 killuser(lua_nick, np, "%s", msg);
865
866 LUA_RETURN(ps, LUA_OK);
867 }
868
869 #define PUSHER_STRING 1
870 #define PUSHER_REALNAME 2
871 #define PUSHER_IP 3
872 #define PUSHER_LONG 4
873 #define PUSHER_HOSTNAME 5
874 #define PUSHER_SSTRING 6
875 #define PUSHER_TOTALUSERS 7
876 #define PUSHER_TOPIC 8
877
878 void lua_initnickpusher(void) {
879 int i = 0;
880
881 #define PUSH_NICKPUSHER(F2, O2) nickpusher[i].argtype = F2; nickpusher[i].structname = #O2; nickpusher[i].offset = offsetof(nick, O2); i++;
882
883 PUSH_NICKPUSHER(PUSHER_STRING, nick);
884 PUSH_NICKPUSHER(PUSHER_STRING, ident);
885 PUSH_NICKPUSHER(PUSHER_HOSTNAME, host);
886 PUSH_NICKPUSHER(PUSHER_REALNAME, realname);
887 PUSH_NICKPUSHER(PUSHER_STRING, authname);
888 PUSH_NICKPUSHER(PUSHER_IP, ipaddress);
889 PUSH_NICKPUSHER(PUSHER_LONG, numeric);
890
891 nickpushercount = i;
892 nickpusher[i].argtype = 0;
893 }
894
895 INLINE void lua_setuppusher(struct lua_pusher *pusherlist, lua_State *l, int index, struct lua_pusher **lp, int max, int pcount) {
896 int current = 0;
897
898 if(max > 0)
899 lp[0] = NULL;
900
901 if(!lua_istable(l, index) || (max < 2))
902 return;
903
904 lua_pushnil(l);
905
906 max--;
907
908 while(lua_next(l, index)) {
909 if(lua_isint(l, -1)) {
910 int index = lua_toint(l, -1);
911 if((index >= 0) && (index < pcount))
912 lp[current++] = &pusherlist[index];
913 }
914
915 lua_pop(l, 1);
916
917 if(current == max)
918 break;
919 }
920
921 lp[current] = NULL;
922 }
923
924 INLINE int lua_usepusher(lua_State *l, struct lua_pusher **lp, void *np) {
925 int i = 0;
926
927 while(*lp) {
928 void *offset = (void *)np + (*lp)->offset;
929
930 switch((*lp)->argtype) {
931 case PUSHER_STRING:
932 lua_pushstring(l, (char *)offset);
933 break;
934 case PUSHER_HOSTNAME:
935 lua_pushstring(l, (*(host **)offset)->name->content);
936 break;
937 case PUSHER_REALNAME:
938 lua_pushstring(l, (*(realname **)offset)->name->content);
939 break;
940 case PUSHER_SSTRING:
941 lua_pushstring(l, (*((sstring **)offset))->content);
942 break;
943 case PUSHER_LONG:
944 lua_pushlong(l, *((long *)offset));
945 break;
946 case PUSHER_IP:
947 lua_pushstring(l, IPtostr(*((long *)offset)));
948 break;
949 case PUSHER_TOTALUSERS:
950 lua_pushint(l, (*((channel **)offset))->users->totalusers);
951 break;
952 case PUSHER_TOPIC:
953 if((*((channel **)offset))->topic) {
954 lua_pushstring(l, (*((channel **)offset))->topic->content);
955 } else {
956 lua_pushnil(l);
957 }
958 break;
959 }
960
961 i++;
962 lp++;
963 }
964
965 return i;
966 }
967
968 void lua_initchanpusher(void) {
969 int i = 0;
970
971 #define PUSH_CHANPUSHER(F2, O2, N2) chanpusher[i].argtype = F2; chanpusher[i].structname = N2; chanpusher[i].offset = offsetof(chanindex, O2); i++;
972
973 PUSH_CHANPUSHER(PUSHER_SSTRING, name, "name");
974 PUSH_CHANPUSHER(PUSHER_TOTALUSERS, channel, "totalusers");
975 PUSH_CHANPUSHER(PUSHER_TOPIC, channel, "topic");
976
977 chanpushercount = i;
978 chanpusher[i].argtype = 0;
979 }