]>
jfr.im git - irc/quakenet/newserv.git/blob - lua/luacommands.c
c1a55f9b63affd48cf8fd91c3f5e2ccd4ec298d9
1 /* Copyright (C) Chris Porter 2005-2007 */
2 /* ALL RIGHTS RESERVED. */
3 /* Don't put this into the SVN repo. */
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.
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 #include "../lib/flags.h"
28 static int lua_smsg(lua_State
*ps
);
29 static int lua_skill(lua_State
*ps
);
31 typedef struct lua_pusher
{
34 const char *structname
;
37 struct lua_pusher nickpusher
[MAX_PUSHER
];
38 struct lua_pusher chanpusher
[MAX_PUSHER
];
39 int nickpushercount
, chanpushercount
;
41 INLINE
void lua_setuppusher(struct lua_pusher
*pusherlist
, lua_State
*l
, int index
, struct lua_pusher
**lp
, int max
, int pcount
);
42 INLINE
int lua_usepusher(lua_State
*l
, struct lua_pusher
**lp
, void *np
);
44 void lua_initnickpusher(void);
45 void lua_initchanpusher(void);
47 #define lua_setupnickpusher(L2, I2, P2, M2) lua_setuppusher(&nickpusher[0], L2, I2, P2, M2, nickpushercount)
48 #define lua_setupchanpusher(L2, I2, P2, M2) lua_setuppusher(&chanpusher[0], L2, I2, P2, M2, chanpushercount)
50 int lua_cmsg(char *channell
, char *message
, ...) __attribute__ ((format (printf
, 2, 3)));
52 int lua_cmsg(char *channell
, char *message
, ...) {
57 va_start(va
, message
);
58 vsnprintf(buf
, sizeof(buf
), message
, va
);
61 cp
= findchannel(channell
);
68 lua_channelmessage(cp
, "%s", buf
);
73 static int lua_chanmsg(lua_State
*ps
) {
74 if(!lua_isstring(ps
, 1))
75 LUA_RETURN(ps
, LUA_FAIL
);
77 LUA_RETURN(ps
, lua_cmsg(LUA_PUKECHAN
, "lua: %s", lua_tostring(ps
, 1)));
80 static int lua_ctcp(lua_State
*ps
) {
84 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
85 LUA_RETURN(ps
, LUA_FAIL
);
87 n
= lua_tostring(ps
, 1);
88 msg
= lua_tostring(ps
, 2);
90 np
= getnickbynick(n
);
91 if(!np
|| !lua_lineok(msg
))
92 LUA_RETURN(ps
, LUA_FAIL
);
94 lua_message(np
, "\001%s\001", msg
);
96 LUA_RETURN(ps
, lua_cmsg(LUA_PUKECHAN
, "lua-ctcp: %s (%s)", np
->nick
, msg
));
99 static int lua_noticecmd(lua_State
*ps
) {
103 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
104 LUA_RETURN(ps
, LUA_FAIL
);
106 n
= lua_tostring(ps
, 1);
107 msg
= lua_tostring(ps
, 2);
109 np
= getnickbynick(n
);
110 if(!np
|| !lua_lineok(msg
))
111 LUA_RETURN(ps
, LUA_FAIL
);
113 lua_notice(np
, "%s", msg
);
115 LUA_RETURN(ps
, LUA_OK
);
118 static int lua_privmsgcmd(lua_State
*ps
) {
122 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
123 LUA_RETURN(ps
, LUA_FAIL
);
125 n
= lua_tostring(ps
, 1);
126 msg
= lua_tostring(ps
, 2);
128 np
= getnickbynick(n
);
129 if(!np
|| !lua_lineok(msg
))
130 LUA_RETURN(ps
, LUA_FAIL
);
132 lua_message(np
, "%s", msg
);
134 LUA_RETURN(ps
, LUA_OK
);
137 static int lua_kill(lua_State
*ps
) {
141 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
142 LUA_RETURN(ps
, LUA_FAIL
);
144 n
= lua_tostring(ps
, 1);
145 msg
= lua_tostring(ps
, 2);
147 np
= getnickbynick(n
);
149 LUA_RETURN(ps
, LUA_FAIL
);
151 if(IsOper(np
) || IsService(np
) || IsXOper(np
))
152 LUA_RETURN(ps
, LUA_FAIL
);
155 LUA_RETURN(ps
, LUA_FAIL
);
157 killuser(lua_nick
, np
, "%s", msg
);
159 LUA_RETURN(ps
, lua_cmsg(LUA_PUKECHAN
, "lua-KILL: %s (%s)", np
->nick
, msg
));
162 static int lua_kick(lua_State
*ps
) {
163 const char *n
, *msg
, *chan
;
168 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2) || !lua_isstring(ps
, 3))
169 LUA_RETURN(ps
, LUA_FAIL
);
171 chan
= lua_tostring(ps
, 1);
172 n
= lua_tostring(ps
, 2);
173 msg
= lua_tostring(ps
, 3);
175 if(lua_isboolean(ps
, 4) && !lua_toboolean(ps
, 4))
178 np
= getnickbynick(n
);
180 LUA_RETURN(ps
, LUA_FAIL
);
182 if(dochecks
&& (IsOper(np
) || IsXOper(np
) || IsService(np
)))
183 LUA_RETURN(ps
, LUA_FAIL
);
185 cp
= findchannel((char *)chan
);
187 LUA_RETURN(ps
, LUA_FAIL
);
190 LUA_RETURN(ps
, LUA_FAIL
);
192 localkickuser(lua_nick
, cp
, np
, msg
);
194 LUA_RETURN(ps
, LUA_OK
);
197 static int lua_invite(lua_State
*ps
) {
201 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
202 LUA_RETURN(ps
, LUA_FAIL
);
204 np
= getnickbynick((char *)lua_tostring(ps
, 1));
206 LUA_RETURN(ps
, LUA_FAIL
);
208 cp
= findchannel((char *)lua_tostring(ps
, 2));
210 LUA_RETURN(ps
, LUA_FAIL
);
212 localinvite(lua_nick
, cp
, np
);
214 LUA_RETURN(ps
, LUA_OK
);
217 static int lua_gline(lua_State
*ps
) {
221 int duration
, usercount
= 0;
224 if(!lua_isstring(ps
, 1) || !lua_isint(ps
, 2) || !lua_isstring(ps
, 3))
225 LUA_RETURN(ps
, LUA_FAIL
);
227 duration
= lua_toint(ps
, 2);
228 if((duration
< 1) || (duration
> 31 * 86400))
229 LUA_RETURN(ps
, LUA_FAIL
);
231 reason
= lua_tostring(ps
, 3);
232 if(!lua_lineok(reason
) || !reason
)
233 LUA_RETURN(ps
, LUA_FAIL
);
235 target
= getnickbynick(lua_tostring(ps
, 1));
236 if(!target
|| (IsOper(target
) || IsXOper(target
) || IsService(target
)))
237 LUA_RETURN(ps
, LUA_FAIL
);
241 LUA_RETURN(ps
, LUA_FAIL
);
243 usercount
= hp
->clonecount
;
244 if(usercount
> 10) { /* (decent) trusted host */
250 for (j
=0;j
<NICKHASHSIZE
;j
++)
251 for (np
=nicktable
[j
];np
;np
=np
->next
)
252 if (np
&& (np
->host
== hp
) && (!ircd_strcmp(np
->ident
, target
->ident
)))
256 LUA_RETURN(ps
, LUA_FAIL
);
258 snprintf(mask
, sizeof(mask
), "*%s@%s", target
->ident
, IPtostr(target
->p_ipaddr
));
260 snprintf(mask
, sizeof(mask
), "*@%s", IPtostr(target
->p_ipaddr
));
263 irc_send("%s GL * +%s %d :%s", mynumeric
->content
, mask
, duration
, reason
);
264 LUA_RETURN(ps
, lua_cmsg(LUA_PUKECHAN
, "lua-GLINE: %s (%d users, %d seconds -- %s)", mask
, usercount
, duration
, reason
));
267 static int lua_fastgetchaninfo(lua_State
*ps
) {
268 static struct lua_pusher
*ourpusher
[MAX_PUSHER
];
271 if(!lua_isstring(ps
, 1))
274 cp
= findchannel((char *)lua_tostring(ps
, 1));
275 if(!cp
|| cp
->index
->channel
!= cp
)
278 lua_setupchanpusher(ps
, 2, ourpusher
, MAX_PUSHER
);
279 return lua_usepusher(ps
, ourpusher
, cp
->index
);
282 static int lua_opchan(lua_State
*ps
) {
286 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
287 LUA_RETURN(ps
, LUA_FAIL
);
289 cp
= findchannel((char *)lua_tostring(ps
, 1));
291 LUA_RETURN(ps
, LUA_FAIL
);
293 np
= getnickbynick((char *)lua_tostring(ps
, 2));
295 LUA_RETURN(ps
, LUA_FAIL
);
297 localsetmodes(lua_nick
, cp
, np
, MC_OP
);
298 LUA_RETURN(ps
, LUA_OK
);
301 static int lua_deopchan(lua_State
*ps
) {
305 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
306 LUA_RETURN(ps
, LUA_FAIL
);
308 cp
= findchannel((char *)lua_tostring(ps
, 1));
310 LUA_RETURN(ps
, LUA_FAIL
);
312 np
= getnickbynick((char *)lua_tostring(ps
, 2));
314 LUA_RETURN(ps
, LUA_FAIL
);
316 localsetmodes(lua_nick
, cp
, np
, MC_DEOP
);
317 LUA_RETURN(ps
, LUA_OK
);
320 static int lua_voicechan(lua_State
*ps
) {
324 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
325 LUA_RETURN(ps
, LUA_FAIL
);
327 cp
= findchannel((char *)lua_tostring(ps
, 1));
329 LUA_RETURN(ps
, LUA_FAIL
);
331 np
= getnickbynick((char *)lua_tostring(ps
, 2));
333 LUA_RETURN(ps
, LUA_FAIL
);
335 localsetmodes(lua_nick
, cp
, np
, MC_VOICE
);
336 LUA_RETURN(ps
, LUA_OK
);
339 static int lua_counthost(lua_State
*ps
) {
343 if(!lua_islong(ps
, 1))
346 numeric
= lua_tolong(ps
, 1);
348 np
= getnickbynumeric(numeric
);
352 lua_pushint(ps
, np
->host
->clonecount
);
356 static int lua_versioninfo(lua_State
*ps
) {
357 lua_pushstring(ps
, LUA_VERSION
);
358 lua_pushstring(ps
, LUA_BOTVERSION
);
359 lua_pushstring(ps
, __DATE__
);
360 lua_pushstring(ps
, __TIME__
);
362 lua_pushstring(ps
, LUA_AUXVERSION
);
367 static int lua_basepath(lua_State
*ps
) {
368 lua_pushfstring(ps
, "%s/", cpath
->content
);
373 static int lua_botnick(lua_State
*ps
) {
374 lua_pushstring(ps
, luabotnick
->content
);
380 static int lua_getuserbyauth(lua_State
*l
) {
385 if(!lua_isstring(l
, 1))
388 acc
= lua_tostring(l
, 1);
390 for(i
=0;i
<NICKHASHSIZE
;i
++) {
391 for(np
=nicktable
[i
];np
;np
=np
->next
) {
392 if(np
&& np
->authname
[0] && !ircd_strcmp(np
->authname
, acc
)) {
393 lua_pushnumeric(l
, np
->numeric
);
402 static int lua_getnickchans(lua_State
*l
) {
407 if(!lua_islong(l
, 1))
410 np
= getnickbynumeric(lua_tolong(l
, 1));
414 channels
= (channel
**)np
->channels
->content
;
415 for(i
=0;i
<np
->channels
->cursi
;i
++)
416 lua_pushstring(l
, channels
[i
]->index
->name
->content
);
418 return np
->channels
->cursi
;
421 static int lua_getnickchanindex(lua_State
*l
) {
425 if(!lua_islong(l
, 1) || !lua_isint(l
, 2))
428 np
= getnickbynumeric(lua_tolong(l
, 1));
432 offset
= lua_toint(l
, 2);
433 if((offset
< 0) || (offset
>= np
->channels
->cursi
))
436 lua_pushstring(l
, ((channel
**)np
->channels
->content
)[offset
]->index
->name
->content
);
445 struct lua_pusher
*nickhashpusher
[MAX_PUSHER
];
447 static int lua_getnextnick(lua_State
*l
) {
448 if(!lasthashnick
&& (hashindex
!= -1))
454 if(hashindex
>= NICKHASHSIZE
)
456 lasthashnick
= nicktable
[hashindex
];
458 lasthashnick
= lasthashnick
->next
;
460 } while(!lasthashnick
);
462 return lua_usepusher(l
, nickhashpusher
, lasthashnick
);
465 static int lua_getfirstnick(lua_State
*l
) {
469 lua_setupnickpusher(l
, 1, nickhashpusher
, MAX_PUSHER
);
470 geoipext
= findnickext("geoip");
472 return lua_getnextnick(l
);
476 chanindex
*lasthashchan
;
478 struct lua_pusher
*chanhashpusher
[MAX_PUSHER
];
480 static int lua_getnextchan(lua_State
*l
) {
481 if(!lasthashchan
&& (chanhashindex
!= -1))
487 if(chanhashindex
>= CHANNELHASHSIZE
)
489 lasthashchan
= chantable
[chanhashindex
];
491 lasthashchan
= lasthashchan
->next
;
493 } while(!lasthashchan
|| !lasthashchan
->channel
);
495 return lua_usepusher(l
, chanhashpusher
, lasthashchan
);
498 static int lua_getfirstchan(lua_State
*l
) {
502 lua_setupchanpusher(l
, 1, chanhashpusher
, MAX_PUSHER
);
504 return lua_getnextchan(l
);
507 static int lua_getnickchancount(lua_State
*l
) {
510 if(!lua_islong(l
, 1))
513 np
= getnickbynumeric(lua_tolong(l
, 1));
517 lua_pushint(l
, np
->channels
->cursi
);
522 static int lua_gethostusers(lua_State
*l
) {
526 if(!lua_islong(l
, 1))
529 np
= getnickbynumeric(lua_tolong(l
, 1));
530 if(!np
|| !np
->host
|| !np
->host
->nicks
)
533 np
= np
->host
->nicks
;
534 count
= np
->host
->clonecount
;
537 lua_pushnumeric(l
, np
->numeric
);
544 static int lua_getnickcountry(lua_State
*l
) {
548 ext
= findnickext("geoip");
552 if(!lua_islong(l
, 1))
555 np
= getnickbynumeric(lua_tolong(l
, 1));
559 lua_pushint(l
, (long)np
->exts
[ext
]);
563 static int lua_chanfix(lua_State
*ps
) {
567 if(!lua_isstring(ps
, 1))
568 LUA_RETURN(ps
, LUA_FAIL
);
570 cp
= findchannel((char *)lua_tostring(ps
, 1));
571 if(!cp
|| !cp
->index
)
572 LUA_RETURN(ps
, LUA_FAIL
);
574 np
= getnickbynick(LUA_CHANFIXBOT
);
576 LUA_RETURN(ps
, LUA_FAIL
);
578 lua_message(np
, "chanfix %s", cp
->index
->name
->content
);
580 LUA_RETURN(ps
, LUA_OK
);
583 static int lua_clearmode(lua_State
*ps
) {
590 if(!lua_isstring(ps
, 1))
591 LUA_RETURN(ps
, LUA_FAIL
);
593 cp
= findchannel((char *)lua_tostring(ps
, 1));
594 if(!cp
|| !cp
->users
)
595 LUA_RETURN(ps
, LUA_FAIL
);
597 localsetmodeinit(&changes
, cp
, lua_nick
);
599 localdosetmode_key(&changes
, NULL
, MCB_DEL
);
600 localdosetmode_simple(&changes
, 0, CHANMODE_INVITEONLY
| CHANMODE_LIMIT
);
603 localdosetmode_ban(&changes
, bantostring(cp
->bans
), MCB_DEL
);
605 for(i
=0,lp
=cp
->users
->content
;i
<cp
->users
->hashsize
;i
++,lp
++)
606 if((*lp
!= nouser
) && (*lp
& CUMODE_OP
)) {
607 np
= getnickbynumeric(*lp
);
608 if(np
&& !IsService(np
))
609 localdosetmode_nick(&changes
, np
, MC_DEOP
);
612 localsetmodeflush(&changes
, 1);
614 LUA_RETURN(ps
, LUA_OK
);
617 static int lua_ban(lua_State
*ps
) {
623 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
624 LUA_RETURN(ps
, LUA_FAIL
);
626 if(lua_isboolean(ps
, 3) && lua_toboolean(ps
, 3))
629 cp
= findchannel((char *)lua_tostring(ps
, 1));
631 LUA_RETURN(ps
, LUA_FAIL
);
633 mask
= lua_tostring(ps
, 2);
634 if(!mask
|| !mask
[0] || !lua_lineok(mask
))
635 LUA_RETURN(ps
, LUA_FAIL
);
637 localsetmodeinit(&changes
, cp
, lua_nick
);
638 localdosetmode_ban(&changes
, mask
, dir
);
639 localsetmodeflush(&changes
, 1);
641 LUA_RETURN(ps
, LUA_OK
);
644 static int lua_topic(lua_State
*ps
) {
648 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
649 LUA_RETURN(ps
, LUA_FAIL
);
651 cp
= findchannel((char *)lua_tostring(ps
, 1));
653 LUA_RETURN(ps
, LUA_FAIL
);
655 topic
= (char *)lua_tostring(ps
, 2);
656 if(!topic
|| !lua_lineok(topic
))
657 LUA_RETURN(ps
, LUA_FAIL
);
659 localsettopic(lua_nick
, cp
, topic
);
661 LUA_RETURN(ps
, LUA_OK
);
664 static int lua_getuserchanmodes(lua_State
*l
) {
669 if(!lua_islong(l
, 1) || !lua_isstring(l
, 2))
672 np
= getnickbynumeric(lua_tolong(l
, 1));
676 cp
= findchannel((char *)lua_tostring(l
, 2));
677 if(!cp
|| !cp
->users
)
680 lp
= getnumerichandlefromchanhash(cp
->users
, np
->numeric
);
684 LUA_PUSHNICKCHANMODES(l
, lp
);
688 static int lua_getusermodes(lua_State
*l
) {
691 if(!lua_islong(l
, 1))
694 np
= getnickbynumeric(lua_tolong(l
, 1));
698 lua_pushstring(l
, printflags(np
->umodes
, umodeflags
));
702 static int lua_fastgetnickbynumeric(lua_State
*l
) {
703 static struct lua_pusher
*ourpusher
[MAX_PUSHER
];
706 if(!lua_islong(l
, 1))
709 np
= getnickbynumeric(lua_tolong(l
, 1));
713 lua_setupnickpusher(l
, 2, ourpusher
, MAX_PUSHER
);
714 return lua_usepusher(l
, ourpusher
, np
);
717 static int lua_fastgetnickbynick(lua_State
*l
) {
718 static struct lua_pusher
*ourpusher
[MAX_PUSHER
];
721 if(!lua_isstring(l
, 1))
724 np
= getnickbynick((char *)lua_tostring(l
, 1));
728 lua_setupnickpusher(l
, 2, ourpusher
, MAX_PUSHER
);
729 return lua_usepusher(l
, ourpusher
, np
);
732 int channelnicklistindex
, channelnicklistcount
= -1;
733 channel
*channelnicklist
;
735 struct lua_pusher
*channelnickpusher
[MAX_PUSHER
];
737 static int lua_getnextchannick(lua_State
*l
) {
741 channelnicklistindex
++;
743 if(channelnicklistindex
>= channelnicklistcount
)
745 } while((channelnicklist
->users
->content
[channelnicklistindex
] == nouser
) || !(np
= getnickbynumeric(channelnicklist
->users
->content
[channelnicklistindex
])));
747 return lua_usepusher(l
, channelnickpusher
, np
);
750 static int lua_getfirstchannick(lua_State
*l
) {
751 if(!lua_isstring(l
, 1))
754 channelnicklist
= findchannel((char *)lua_tostring(l
, 1));
755 if(!channelnicklist
|| !channelnicklist
->users
)
758 channelnicklistindex
= -1;
759 channelnicklistcount
= channelnicklist
->users
->hashsize
;
761 lua_setupnickpusher(l
, 2, channelnickpusher
, MAX_PUSHER
);
763 return lua_getnextchannick(l
);
766 static int lua_nickonchan(lua_State
*l
) {
768 if(lua_islong(l
, 1) && lua_isstring(l
, 2)) {
769 channel
*cp
= findchannel((char *)lua_tostring(l
, 2));
770 if(cp
&& cp
->users
) {
771 unsigned long *lp
= getnumerichandlefromchanhash(cp
->users
, lua_tolong(l
, 1));
777 lua_pushboolean(l
, success
);
781 static int lua_simplechanmode(lua_State
*ps
) {
784 flag_t add
= 0, del
= ~add
;
785 flag_t permitted
= CHANMODE_NOEXTMSG
| CHANMODE_TOPICLIMIT
| CHANMODE_SECRET
| CHANMODE_PRIVATE
| CHANMODE_INVITEONLY
| CHANMODE_MODERATE
| CHANMODE_NOCOLOUR
| CHANMODE_NOCTCP
| CHANMODE_REGONLY
| CHANMODE_DELJOINS
| CHANMODE_NOQUITMSG
| CHANMODE_NONOTICE
| CHANMODE_MODNOAUTH
| CHANMODE_SINGLETARG
;
788 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
789 LUA_RETURN(ps
, LUA_FAIL
);
791 cp
= findchannel((char *)lua_tostring(ps
, 1));
793 LUA_RETURN(ps
, LUA_FAIL
);
795 modes
= (char *)lua_tostring(ps
, 2);
797 LUA_RETURN(ps
, LUA_FAIL
);
799 if(setflags(&add
, permitted
, modes
, cmodeflags
, REJECT_DISALLOWED
|REJECT_UNKNOWN
) != REJECT_NONE
)
800 LUA_RETURN(ps
, LUA_FAIL
);
802 if(setflags(&del
, permitted
, modes
, cmodeflags
, REJECT_DISALLOWED
|REJECT_UNKNOWN
) != REJECT_NONE
)
803 LUA_RETURN(ps
, LUA_FAIL
);
805 localsetmodeinit(&changes
, cp
, lua_nick
);
806 localdosetmode_simple(&changes
, add
, ~del
);
807 localsetmodeflush(&changes
, 1);
809 LUA_RETURN(ps
, LUA_OK
);
812 static int lua_sethost(lua_State
*ps
) {
816 if(!lua_islong(ps
, 1) || !lua_isstring(ps
, 2) || !lua_isstring(ps
, 3))
817 LUA_RETURN(ps
, LUA_FAIL
);
819 np
= getnickbynumeric(lua_tolong(ps
, 1));
821 LUA_RETURN(ps
, LUA_FAIL
);
823 ident
= (char *)lua_tostring(ps
, 2);
824 host
= (char *)lua_tostring(ps
, 3);
825 if(!lua_lineok(ident
) || !lua_lineok(host
))
826 LUA_RETURN(ps
, LUA_FAIL
);
828 sethostuser(np
, ident
, host
);
830 LUA_RETURN(ps
, LUA_OK
);
833 static int lua_getvisiblehostmask(lua_State
*l
) {
835 char buf
[HOSTLEN
+USERLEN
+NICKLEN
+REALLEN
+10];
837 if(!lua_islong(l
, 1))
840 np
= getnickbynumeric(lua_tolong(l
, 1));
844 lua_pushstring(l
, visiblehostmask(np
, buf
));
848 void lua_registercommands(lua_State
*l
) {
849 lua_register(l
, "irc_smsg", lua_smsg
);
850 lua_register(l
, "irc_skill", lua_skill
);
852 lua_register(l
, "chanmsg", lua_chanmsg
);
853 lua_register(l
, "versioninfo", lua_versioninfo
);
854 lua_register(l
, "basepath", lua_basepath
);
855 lua_register(l
, "botnick", lua_botnick
);
857 lua_register(l
, "irc_report", lua_chanmsg
);
858 lua_register(l
, "irc_ctcp", lua_ctcp
);
859 lua_register(l
, "irc_kill", lua_kill
);
860 lua_register(l
, "irc_kick", lua_kick
);
861 lua_register(l
, "irc_invite", lua_invite
);
862 lua_register(l
, "irc_gline", lua_gline
);
863 lua_register(l
, "irc_counthost", lua_counthost
);
864 lua_register(l
, "irc_getuserbyauth", lua_getuserbyauth
);
865 lua_register(l
, "irc_notice", lua_noticecmd
);
866 lua_register(l
, "irc_privmsg", lua_privmsgcmd
);
867 lua_register(l
, "irc_opchan", lua_opchan
);
868 lua_register(l
, "irc_voicechan", lua_voicechan
);
869 lua_register(l
, "irc_chanfix", lua_chanfix
);
870 lua_register(l
, "irc_clearmode", lua_clearmode
);
871 lua_register(l
, "irc_ban", lua_ban
);
872 lua_register(l
, "irc_deopchan", lua_deopchan
);
873 lua_register(l
, "irc_topic", lua_topic
);
875 lua_register(l
, "irc_getfirstnick", lua_getfirstnick
);
876 lua_register(l
, "irc_getnextnick", lua_getnextnick
);
878 lua_register(l
, "irc_getnickchans", lua_getnickchans
);
879 lua_register(l
, "irc_getnickchanindex", lua_getnickchanindex
);
880 lua_register(l
, "irc_getnickchancount", lua_getnickchancount
);
882 lua_register(l
, "irc_getuserchanmodes", lua_getuserchanmodes
);
884 lua_register(l
, "irc_getfirstchannick", lua_getfirstchannick
);
885 lua_register(l
, "irc_getnextchannick", lua_getnextchannick
);
887 lua_register(l
, "irc_gethostusers", lua_gethostusers
);
888 lua_register(l
, "irc_getnickcountry", lua_getnickcountry
);
890 lua_register(l
, "irc_getfirstchan", lua_getfirstchan
);
891 lua_register(l
, "irc_getnextchan", lua_getnextchan
);
892 lua_register(l
, "irc_getusermodes", lua_getusermodes
);
893 lua_register(l
, "irc_nickonchan", lua_nickonchan
);
895 lua_register(l
, "irc_fastgetnickbynumeric", lua_fastgetnickbynumeric
);
896 lua_register(l
, "irc_fastgetnickbynick", lua_fastgetnickbynick
);
897 lua_register(l
, "irc_fastgetchaninfo", lua_fastgetchaninfo
);
899 lua_register(l
, "irc_getvisiblehostmask", lua_getvisiblehostmask
);
901 lua_register(l
, "irc_simplechanmode", lua_simplechanmode
);
902 lua_register(l
, "irc_sethost", lua_sethost
);
907 static int lua_smsg(lua_State
*ps
) {
908 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
909 LUA_RETURN(ps
, LUA_FAIL
);
911 LUA_RETURN(ps
, lua_cmsg((char *)lua_tostring(ps
, 2), "%s", lua_tostring(ps
, 1)));
914 static int lua_skill(lua_State
*ps
) {
918 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
919 LUA_RETURN(ps
, LUA_FAIL
);
921 n
= lua_tostring(ps
, 1);
922 msg
= lua_tostring(ps
, 2);
924 np
= getnickbynick(n
);
926 LUA_RETURN(ps
, LUA_FAIL
);
928 if(IsOper(np
) || IsService(np
) || IsXOper(np
))
929 LUA_RETURN(ps
, LUA_FAIL
);
932 LUA_RETURN(ps
, LUA_FAIL
);
934 killuser(lua_nick
, np
, "%s", msg
);
936 LUA_RETURN(ps
, LUA_OK
);
939 #define PUSHER_STRING 1
940 #define PUSHER_REALNAME 2
942 #define PUSHER_LONG 4
943 #define PUSHER_HOSTNAME 5
944 #define PUSHER_SSTRING 6
945 #define PUSHER_TOTALUSERS 7
946 #define PUSHER_TOPIC 8
947 #define PUSHER_UMODES 9
948 #define PUSHER_COUNTRY 10
949 #define PUSHER_REALUSERS 11
950 #define PUSHER_CHANMODES 12
951 #define PUSHER_TIMESTAMP 13
952 #define PUSHER_STRING_INDIRECT 14
954 void lua_initnickpusher(void) {
957 #define PUSH_NICKPUSHER(F2, O2) nickpusher[i].argtype = F2; nickpusher[i].structname = #O2; nickpusher[i].offset = offsetof(nick, O2); i++;
958 #define PUSH_NICKPUSHER_CUSTOM(F2, custom) nickpusher[i].argtype = F2; nickpusher[i].structname = custom; nickpusher[i].offset = 0; i++;
960 PUSH_NICKPUSHER(PUSHER_STRING
, nick
);
961 PUSH_NICKPUSHER(PUSHER_STRING
, ident
);
962 PUSH_NICKPUSHER(PUSHER_HOSTNAME
, host
);
963 PUSH_NICKPUSHER(PUSHER_REALNAME
, realname
);
964 PUSH_NICKPUSHER(PUSHER_STRING_INDIRECT
, authname
);
965 PUSH_NICKPUSHER(PUSHER_IP
, ipnode
);
966 PUSH_NICKPUSHER(PUSHER_LONG
, numeric
);
967 PUSH_NICKPUSHER(PUSHER_LONG
, timestamp
);
968 PUSH_NICKPUSHER(PUSHER_LONG
, accountts
);
969 PUSH_NICKPUSHER(PUSHER_UMODES
, umodes
);
970 PUSH_NICKPUSHER_CUSTOM(PUSHER_COUNTRY
, "country");
973 nickpusher
[i
].argtype
= 0;
976 INLINE
void lua_setuppusher(struct lua_pusher
*pusherlist
, lua_State
*l
, int index
, struct lua_pusher
**lp
, int max
, int pcount
) {
982 if(!lua_istable(l
, index
) || (max
< 2))
989 while(lua_next(l
, index
)) {
990 if(lua_isint(l
, -1)) {
991 int index
= lua_toint(l
, -1);
992 if((index
>= 0) && (index
< pcount
))
993 lp
[current
++] = &pusherlist
[index
];
1005 INLINE
int lua_usepusher(lua_State
*l
, struct lua_pusher
**lp
, void *np
) {
1009 void *offset
= (void *)np
+ (*lp
)->offset
;
1011 switch((*lp
)->argtype
) {
1013 lua_pushstring(l
, (char *)offset
);
1015 case PUSHER_STRING_INDIRECT
:
1016 lua_pushstring(l
, *(char **)offset
);
1018 case PUSHER_HOSTNAME
:
1019 lua_pushstring(l
, (*(host
**)offset
)->name
->content
);
1021 case PUSHER_REALNAME
:
1022 lua_pushstring(l
, (*(realname
**)offset
)->name
->content
);
1024 case PUSHER_SSTRING
:
1025 lua_pushstring(l
, (*((sstring
**)offset
))->content
);
1028 lua_pushlong(l
, *((long *)offset
));
1030 case PUSHER_TIMESTAMP
:
1031 lua_pushlong(l
, (*((channel
**)offset
))->timestamp
);
1034 lua_pushstring(l
, IPtostr((*((patricia_node_t
**)offset
))->prefix
->sin
));
1036 case PUSHER_TOTALUSERS
:
1037 lua_pushint(l
, (*((channel
**)offset
))->users
->totalusers
);
1039 case PUSHER_CHANMODES
:
1040 lua_pushstring(l
, printallmodes(*((channel
**)offset
)));
1042 case PUSHER_REALUSERS
:
1044 channel
*cp
= *((channel
**)offset
);
1046 int i
, currentusers
= countuniquehosts(cp
);
1047 for(i
=0;i
<cp
->users
->hashsize
;i
++) {
1048 if(cp
->users
->content
[i
]==nouser
)
1051 if((np2
=getnickbynumeric(cp
->users
->content
[i
]))==NULL
) {
1052 Error("lua", ERR_ERROR
, "Found unknown numeric %lu on channel %s", cp
->users
->content
[i
], cp
->index
->name
->content
);
1056 if (IsXOper(np2
) || IsService(np2
))
1059 lua_pushint(l
, currentusers
);
1063 lua_pushstring(l
, printflags(*((flag_t
*)offset
), umodeflags
));
1066 if((*((channel
**)offset
))->topic
) {
1067 lua_pushstring(l
, (*((channel
**)offset
))->topic
->content
);
1072 case PUSHER_COUNTRY
:
1076 lua_pushint(l
, (long)((nick
*)offset
)->exts
[geoipext
]);
1088 void lua_initchanpusher(void) {
1091 #define PUSH_CHANPUSHER(F2, O2, N2) chanpusher[i].argtype = F2; chanpusher[i].structname = N2; chanpusher[i].offset = offsetof(chanindex, O2); i++;
1093 PUSH_CHANPUSHER(PUSHER_SSTRING
, name
, "name");
1094 PUSH_CHANPUSHER(PUSHER_TOTALUSERS
, channel
, "totalusers");
1095 PUSH_CHANPUSHER(PUSHER_TOPIC
, channel
, "topic");
1096 PUSH_CHANPUSHER(PUSHER_REALUSERS
, channel
, "realusers");
1097 PUSH_CHANPUSHER(PUSHER_TIMESTAMP
, channel
, "timestamp");
1098 PUSH_CHANPUSHER(PUSHER_CHANMODES
, channel
, "modes");
1100 chanpushercount
= i
;
1101 chanpusher
[i
].argtype
= 0;