]>
jfr.im git - irc/quakenet/newserv.git/blob - lua/luacommands.c
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"
19 #include "../authext/authext.h"
20 #include "../glines/glines.h"
21 #include "../trusts/trusts.h"
22 #include "../bans/bans.h"
23 #include "../core/modules.h"
33 static int lua_smsg(lua_State
*ps
);
34 static int lua_skill(lua_State
*ps
);
36 typedef struct lua_pusher
{
39 const char *structname
;
42 struct lua_pusher nickpusher
[MAX_PUSHER
];
43 struct lua_pusher chanpusher
[MAX_PUSHER
];
44 int nickpushercount
, chanpushercount
;
46 void lua_setuppusher(struct lua_pusher
*pusherlist
, lua_State
*l
, int index
, struct lua_pusher
**lp
, int max
, int pcount
);
47 int lua_usepusher(lua_State
*l
, struct lua_pusher
**lp
, void *np
);
49 void lua_initnickpusher(void);
50 void lua_initchanpusher(void);
52 #define lua_setupnickpusher(L2, I2, P2, M2) lua_setuppusher(&nickpusher[0], L2, I2, P2, M2, nickpushercount)
53 #define lua_setupchanpusher(L2, I2, P2, M2) lua_setuppusher(&chanpusher[0], L2, I2, P2, M2, chanpushercount)
55 int lua_cmsg(char *channell
, char *message
, ...) __attribute__ ((format (printf
, 2, 3)));
57 int lua_cmsg(char *channell
, char *message
, ...) {
62 va_start(va
, message
);
63 vsnprintf(buf
, sizeof(buf
), message
, va
);
66 cp
= findchannel(channell
);
73 lua_channelmessage(cp
, "%s", buf
);
78 static int lua_chanmsg(lua_State
*ps
) {
79 if(!lua_isstring(ps
, 1))
80 LUA_RETURN(ps
, LUA_FAIL
);
82 LUA_RETURN(ps
, lua_cmsg(LUA_PUKECHAN
, "lua: %s", lua_tostring(ps
, 1)));
85 static int lua_ctcp(lua_State
*ps
) {
89 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
90 LUA_RETURN(ps
, LUA_FAIL
);
92 n
= lua_tostring(ps
, 1);
93 msg
= lua_tostring(ps
, 2);
95 np
= getnickbynick(n
);
96 if(!np
|| !lua_lineok(msg
))
97 LUA_RETURN(ps
, LUA_FAIL
);
99 lua_message(np
, "\001%s\001", msg
);
101 LUA_RETURN(ps
, lua_cmsg(LUA_PUKECHAN
, "lua-ctcp: %s (%s)", np
->nick
, msg
));
104 static int lua_noticecmd(lua_State
*ps
) {
108 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
109 LUA_RETURN(ps
, LUA_FAIL
);
111 n
= lua_tostring(ps
, 1);
112 msg
= lua_tostring(ps
, 2);
114 np
= getnickbynick(n
);
115 if(!np
|| !lua_lineok(msg
))
116 LUA_RETURN(ps
, LUA_FAIL
);
118 lua_notice(np
, "%s", msg
);
120 LUA_RETURN(ps
, LUA_OK
);
123 static int lua_privmsgcmd(lua_State
*ps
) {
127 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
128 LUA_RETURN(ps
, LUA_FAIL
);
130 n
= lua_tostring(ps
, 1);
131 msg
= lua_tostring(ps
, 2);
133 np
= getnickbynick(n
);
134 if(!np
|| !lua_lineok(msg
))
135 LUA_RETURN(ps
, LUA_FAIL
);
137 lua_message(np
, "%s", msg
);
139 LUA_RETURN(ps
, LUA_OK
);
142 static int lua_kill(lua_State
*ps
) {
146 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
147 LUA_RETURN(ps
, LUA_FAIL
);
149 n
= lua_tostring(ps
, 1);
150 msg
= lua_tostring(ps
, 2);
152 np
= getnickbynick(n
);
154 LUA_RETURN(ps
, LUA_FAIL
);
156 if(IsOper(np
) || IsService(np
) || IsXOper(np
))
157 LUA_RETURN(ps
, LUA_FAIL
);
160 LUA_RETURN(ps
, LUA_FAIL
);
162 killuser(lua_nick
, np
, "%s", msg
);
164 LUA_RETURN(ps
, lua_cmsg(LUA_PUKECHAN
, "lua-KILL: %s (%s)", np
->nick
, msg
));
167 static int lua_kick(lua_State
*ps
) {
168 const char *n
, *msg
, *chan
;
173 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2) || !lua_isstring(ps
, 3))
174 LUA_RETURN(ps
, LUA_FAIL
);
176 chan
= lua_tostring(ps
, 1);
177 n
= lua_tostring(ps
, 2);
178 msg
= lua_tostring(ps
, 3);
180 if(lua_isboolean(ps
, 4) && !lua_toboolean(ps
, 4))
183 np
= getnickbynick(n
);
185 LUA_RETURN(ps
, LUA_FAIL
);
187 if(dochecks
&& (IsOper(np
) || IsXOper(np
) || IsService(np
)))
188 LUA_RETURN(ps
, LUA_FAIL
);
190 cp
= findchannel((char *)chan
);
192 LUA_RETURN(ps
, LUA_FAIL
);
195 LUA_RETURN(ps
, LUA_FAIL
);
197 localkickuser(lua_nick
, cp
, np
, msg
);
199 LUA_RETURN(ps
, LUA_OK
);
202 static int lua_invite(lua_State
*ps
) {
206 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
207 LUA_RETURN(ps
, LUA_FAIL
);
209 np
= getnickbynick((char *)lua_tostring(ps
, 1));
211 LUA_RETURN(ps
, LUA_FAIL
);
213 cp
= findchannel((char *)lua_tostring(ps
, 2));
215 LUA_RETURN(ps
, LUA_FAIL
);
217 localinvite(lua_nick
, cp
->index
, np
);
219 LUA_RETURN(ps
, LUA_OK
);
222 static int lua_gline(lua_State
*ps
) {
228 if(!lua_isstring(ps
, 1) || !lua_isint(ps
, 2) || !lua_isstring(ps
, 3))
229 LUA_RETURN(ps
, LUA_FAIL
);
231 duration
= lua_toint(ps
, 2);
232 if((duration
< 1) || (duration
> 31 * 86400))
233 LUA_RETURN(ps
, LUA_FAIL
);
235 reason
= lua_tostring(ps
, 3);
236 if(!lua_lineok(reason
) || !reason
)
237 LUA_RETURN(ps
, LUA_FAIL
);
239 target
= getnickbynick(lua_tostring(ps
, 1));
240 if(!target
|| (IsOper(target
) || IsXOper(target
) || IsService(target
)))
241 LUA_RETURN(ps
, LUA_FAIL
);
243 if(glinebynick(target
, duration
, reason
, GLINE_SIMULATE
, "lua") > 50)
244 LUA_RETURN(ps
, LUA_FAIL
);
246 info
= glinebynickex(target
, duration
, reason
, 0, "lua");
247 LUA_RETURN(ps
, lua_cmsg(LUA_PUKECHAN
, "lua-GLINE: %s (%d users, %d seconds -- %s)", info
->mask
, info
->hits
, duration
, reason
));
250 static int lua_fastgetchaninfo(lua_State
*ps
) {
251 static struct lua_pusher
*ourpusher
[MAX_PUSHER
];
254 if(!lua_isstring(ps
, 1))
257 cp
= findchannel((char *)lua_tostring(ps
, 1));
258 if(!cp
|| cp
->index
->channel
!= cp
)
261 lua_setupchanpusher(ps
, 2, ourpusher
, MAX_PUSHER
);
262 return lua_usepusher(ps
, ourpusher
, cp
->index
);
265 static int lua_opchan(lua_State
*ps
) {
269 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
270 LUA_RETURN(ps
, LUA_FAIL
);
272 cp
= findchannel((char *)lua_tostring(ps
, 1));
274 LUA_RETURN(ps
, LUA_FAIL
);
276 np
= getnickbynick((char *)lua_tostring(ps
, 2));
278 LUA_RETURN(ps
, LUA_FAIL
);
280 localsetmodes(lua_nick
, cp
, np
, MC_OP
);
281 LUA_RETURN(ps
, LUA_OK
);
284 static int lua_deopchan(lua_State
*ps
) {
288 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
289 LUA_RETURN(ps
, LUA_FAIL
);
291 cp
= findchannel((char *)lua_tostring(ps
, 1));
293 LUA_RETURN(ps
, LUA_FAIL
);
295 np
= getnickbynick((char *)lua_tostring(ps
, 2));
297 LUA_RETURN(ps
, LUA_FAIL
);
299 localsetmodes(lua_nick
, cp
, np
, MC_DEOP
);
300 LUA_RETURN(ps
, LUA_OK
);
303 static int lua_voicechan(lua_State
*ps
) {
307 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
308 LUA_RETURN(ps
, LUA_FAIL
);
310 cp
= findchannel((char *)lua_tostring(ps
, 1));
312 LUA_RETURN(ps
, LUA_FAIL
);
314 np
= getnickbynick((char *)lua_tostring(ps
, 2));
316 LUA_RETURN(ps
, LUA_FAIL
);
318 localsetmodes(lua_nick
, cp
, np
, MC_VOICE
);
319 LUA_RETURN(ps
, LUA_OK
);
322 static int lua_counthost(lua_State
*ps
) {
326 if(!lua_islong(ps
, 1))
329 numeric
= lua_tolong(ps
, 1);
331 np
= getnickbynumeric(numeric
);
335 lua_pushint(ps
, np
->host
->clonecount
);
339 static int lua_versioninfo(lua_State
*ps
) {
340 lua_pushstring(ps
, LUA_VERSION
);
341 lua_pushstring(ps
, LUA_BOTVERSION
);
342 lua_pushstring(ps
, __DATE__
);
343 lua_pushstring(ps
, __TIME__
);
345 lua_pushstring(ps
, LUA_AUXVERSION
);
350 static int lua_nickmatchban(lua_State
*ps
) {
351 const char *chanban_str
, *nick_str
;
355 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
358 nick_str
= lua_tostring(ps
, 1);
359 chanban_str
= lua_tostring(ps
, 2);
361 np
= getnickbynick(nick_str
);
365 cb
= makeban(chanban_str
);
369 lua_pushboolean(ps
, nickmatchban(np
, cb
, 1));
376 static int lua_nickbanned(lua_State
*ps
) {
377 const char *channel_str
, *nick_str
;
381 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
384 nick_str
= lua_tostring(ps
, 1);
385 channel_str
= lua_tostring(ps
, 2);
387 np
= getnickbynick(nick_str
);
391 cp
= findchannel((char *)channel_str
);
395 lua_pushboolean(ps
, nickbanned(np
, cp
, 1));
400 static int lua_suggestbanmask(lua_State
*ps
) {
401 const char *nick_str
;
407 if (!lua_isstring(ps
, 1))
410 nick_str
= lua_tostring(ps
, 1);
411 np
= getnickbynick(nick_str
);
415 glinebufinit(&gb
, 0);
416 glinebufaddbynick(&gb
, np
, 0, "Auto", "None", time(NULL
), time(NULL
), time(NULL
));
420 for (gl
= gb
.glines
; gl
; gl
= gl
->next
) {
421 if (gl
->host
&& gl
->host
->content
) {
422 char *mask
= glinetostring(gl
);
423 LUA_APUSHSTRING(ps
, i
, mask
);
433 static int lua_nickistrusted(lua_State
*ps
) {
434 const char *nick_str
;
437 if(!lua_isstring(ps
, 1))
440 nick_str
= lua_tostring(ps
, 1);
442 np
= getnickbynick(nick_str
);
446 lua_pushboolean(ps
, istrusted(np
));
451 static int lua_basepath(lua_State
*ps
) {
452 lua_pushfstring(ps
, "%s/", cpath
->content
);
457 static int lua_botnick(lua_State
*ps
) {
458 lua_pushstring(ps
, luabotnick
->content
);
463 static int lua_numerictobase64(lua_State
*ps
) {
464 if(!lua_islong(ps
, 1))
467 lua_pushstring(ps
, longtonumeric(lua_tolong(ps
, 1), 5));
471 static int lua_match(lua_State
*ps
) {
472 const char *mask
, *string
;
474 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
477 mask
= lua_tostring(ps
, 1);
478 string
= lua_tostring(ps
, 2);
480 if (!mask
|| !mask
[0] || !string
|| !string
[0])
483 lua_pushboolean(ps
, match2strings(mask
, string
));
487 static int lua_getuserbyauth(lua_State
*l
) {
492 if(!lua_isstring(l
, 1))
495 au
= getauthbyname(lua_tostring(l
, 1));
499 for(np
=au
->nicks
;np
;np
=np
->nextbyauthname
) {
500 lua_pushnumeric(l
, np
->numeric
);
507 static int lua_getnickchans(lua_State
*l
) {
512 if(!lua_islong(l
, 1))
515 np
= getnickbynumeric(lua_tolong(l
, 1));
519 channels
= (channel
**)np
->channels
->content
;
520 for(i
=0;i
<np
->channels
->cursi
;i
++)
521 lua_pushstring(l
, channels
[i
]->index
->name
->content
);
523 return np
->channels
->cursi
;
526 static int lua_getnickchanindex(lua_State
*l
) {
530 if(!lua_islong(l
, 1) || !lua_isint(l
, 2))
533 np
= getnickbynumeric(lua_tolong(l
, 1));
537 offset
= lua_toint(l
, 2);
538 if((offset
< 0) || (offset
>= np
->channels
->cursi
))
541 lua_pushstring(l
, ((channel
**)np
->channels
->content
)[offset
]->index
->name
->content
);
550 struct lua_pusher
*nickhashpusher
[MAX_PUSHER
];
552 static int lua_getnextnick(lua_State
*l
) {
553 if(!lasthashnick
&& (hashindex
!= -1))
559 if(hashindex
>= NICKHASHSIZE
)
561 lasthashnick
= nicktable
[hashindex
];
563 lasthashnick
= lasthashnick
->next
;
565 } while(!lasthashnick
);
567 return lua_usepusher(l
, nickhashpusher
, lasthashnick
);
570 static int lua_getfirstnick(lua_State
*l
) {
574 lua_setupnickpusher(l
, 1, nickhashpusher
, MAX_PUSHER
);
575 geoipext
= findnickext("geoip");
577 return lua_getnextnick(l
);
581 chanindex
*lasthashchan
;
583 struct lua_pusher
*chanhashpusher
[MAX_PUSHER
];
585 static int lua_getnextchan(lua_State
*l
) {
586 if(!lasthashchan
&& (chanhashindex
!= -1))
592 if(chanhashindex
>= CHANNELHASHSIZE
)
594 lasthashchan
= chantable
[chanhashindex
];
596 lasthashchan
= lasthashchan
->next
;
598 } while(!lasthashchan
|| !lasthashchan
->channel
);
600 return lua_usepusher(l
, chanhashpusher
, lasthashchan
);
603 static int lua_getfirstchan(lua_State
*l
) {
607 lua_setupchanpusher(l
, 1, chanhashpusher
, MAX_PUSHER
);
609 return lua_getnextchan(l
);
612 static int lua_getnickchancount(lua_State
*l
) {
615 if(!lua_islong(l
, 1))
618 np
= getnickbynumeric(lua_tolong(l
, 1));
622 lua_pushint(l
, np
->channels
->cursi
);
627 static int lua_gethostusers(lua_State
*l
) {
631 if(!lua_islong(l
, 1))
634 np
= getnickbynumeric(lua_tolong(l
, 1));
635 if(!np
|| !np
->host
|| !np
->host
->nicks
)
638 np
= np
->host
->nicks
;
639 count
= np
->host
->clonecount
;
642 lua_pushnumeric(l
, np
->numeric
);
649 static int lua_getnickcountry(lua_State
*l
) {
653 ext
= findnickext("geoip");
657 if(!lua_islong(l
, 1))
660 np
= getnickbynumeric(lua_tolong(l
, 1));
664 lua_pushint(l
, (long)np
->exts
[ext
]);
668 static int lua_chanfix(lua_State
*ps
) {
672 if(!lua_isstring(ps
, 1))
673 LUA_RETURN(ps
, LUA_FAIL
);
675 cp
= findchannel((char *)lua_tostring(ps
, 1));
676 if(!cp
|| !cp
->index
)
677 LUA_RETURN(ps
, LUA_FAIL
);
679 np
= getnickbynick(LUA_CHANFIXBOT
);
681 LUA_RETURN(ps
, LUA_FAIL
);
683 lua_message(np
, "chanfix %s", cp
->index
->name
->content
);
685 LUA_RETURN(ps
, LUA_OK
);
688 static int lua_clearmode(lua_State
*ps
) {
695 if(!lua_isstring(ps
, 1))
696 LUA_RETURN(ps
, LUA_FAIL
);
698 cp
= findchannel((char *)lua_tostring(ps
, 1));
699 if(!cp
|| !cp
->users
)
700 LUA_RETURN(ps
, LUA_FAIL
);
702 localsetmodeinit(&changes
, cp
, lua_nick
);
704 localdosetmode_key(&changes
, NULL
, MCB_DEL
);
705 localdosetmode_simple(&changes
, 0, CHANMODE_INVITEONLY
| CHANMODE_LIMIT
);
708 localdosetmode_ban(&changes
, bantostring(cp
->bans
), MCB_DEL
);
710 for(i
=0,lp
=cp
->users
->content
;i
<cp
->users
->hashsize
;i
++,lp
++)
711 if((*lp
!= nouser
) && (*lp
& CUMODE_OP
)) {
712 np
= getnickbynumeric(*lp
);
713 if(np
&& !IsService(np
))
714 localdosetmode_nick(&changes
, np
, MC_DEOP
);
717 localsetmodeflush(&changes
, 1);
719 LUA_RETURN(ps
, LUA_OK
);
722 static int lua_ban(lua_State
*ps
) {
728 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
729 LUA_RETURN(ps
, LUA_FAIL
);
731 if(lua_isboolean(ps
, 3) && lua_toboolean(ps
, 3))
734 cp
= findchannel((char *)lua_tostring(ps
, 1));
736 LUA_RETURN(ps
, LUA_FAIL
);
738 mask
= lua_tostring(ps
, 2);
739 if(!mask
|| !mask
[0] || !lua_lineok(mask
))
740 LUA_RETURN(ps
, LUA_FAIL
);
742 localsetmodeinit(&changes
, cp
, lua_nick
);
743 localdosetmode_ban(&changes
, mask
, dir
);
744 localsetmodeflush(&changes
, 1);
746 LUA_RETURN(ps
, LUA_OK
);
749 static int lua_topic(lua_State
*ps
) {
753 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
754 LUA_RETURN(ps
, LUA_FAIL
);
756 cp
= findchannel((char *)lua_tostring(ps
, 1));
758 LUA_RETURN(ps
, LUA_FAIL
);
760 topic
= (char *)lua_tostring(ps
, 2);
761 if(!topic
|| !lua_lineok(topic
))
762 LUA_RETURN(ps
, LUA_FAIL
);
764 localsettopic(lua_nick
, cp
, topic
);
766 LUA_RETURN(ps
, LUA_OK
);
769 static int lua_getuserchanmodes(lua_State
*l
) {
774 if(!lua_islong(l
, 1) || !lua_isstring(l
, 2))
777 np
= getnickbynumeric(lua_tolong(l
, 1));
781 cp
= findchannel((char *)lua_tostring(l
, 2));
782 if(!cp
|| !cp
->users
)
785 lp
= getnumerichandlefromchanhash(cp
->users
, np
->numeric
);
789 LUA_PUSHNICKCHANMODES(l
, lp
);
793 static int lua_getusermodes(lua_State
*l
) {
796 if(!lua_islong(l
, 1))
799 np
= getnickbynumeric(lua_tolong(l
, 1));
803 lua_pushstring(l
, printflags(np
->umodes
, umodeflags
));
807 static int lua_fastgetnickbynumeric(lua_State
*l
) {
808 static struct lua_pusher
*ourpusher
[MAX_PUSHER
];
811 if(!lua_islong(l
, 1))
814 np
= getnickbynumeric(lua_tolong(l
, 1));
818 lua_setupnickpusher(l
, 2, ourpusher
, MAX_PUSHER
);
819 return lua_usepusher(l
, ourpusher
, np
);
822 static int lua_fastgetnickbynick(lua_State
*l
) {
823 static struct lua_pusher
*ourpusher
[MAX_PUSHER
];
826 if(!lua_isstring(l
, 1))
829 np
= getnickbynick((char *)lua_tostring(l
, 1));
833 lua_setupnickpusher(l
, 2, ourpusher
, MAX_PUSHER
);
834 return lua_usepusher(l
, ourpusher
, np
);
837 int channelnicklistindex
, channelnicklistcount
= -1;
838 channel
*channelnicklist
;
840 struct lua_pusher
*channelnickpusher
[MAX_PUSHER
];
842 static int lua_getnextchannick(lua_State
*l
) {
846 channelnicklistindex
++;
848 if(channelnicklistindex
>= channelnicklistcount
)
850 } while((channelnicklist
->users
->content
[channelnicklistindex
] == nouser
) || !(np
= getnickbynumeric(channelnicklist
->users
->content
[channelnicklistindex
])));
852 return lua_usepusher(l
, channelnickpusher
, np
);
855 static int lua_getfirstchannick(lua_State
*l
) {
856 if(!lua_isstring(l
, 1))
859 channelnicklist
= findchannel((char *)lua_tostring(l
, 1));
860 if(!channelnicklist
|| !channelnicklist
->users
)
863 channelnicklistindex
= -1;
864 channelnicklistcount
= channelnicklist
->users
->hashsize
;
866 lua_setupnickpusher(l
, 2, channelnickpusher
, MAX_PUSHER
);
868 return lua_getnextchannick(l
);
871 static int lua_nickonchan(lua_State
*l
) {
873 if(lua_islong(l
, 1) && lua_isstring(l
, 2)) {
874 channel
*cp
= findchannel((char *)lua_tostring(l
, 2));
875 if(cp
&& cp
->users
) {
876 unsigned long *lp
= getnumerichandlefromchanhash(cp
->users
, lua_tolong(l
, 1));
882 lua_pushboolean(l
, success
);
886 static int lua_simplechanmode(lua_State
*ps
) {
889 flag_t add
= 0, del
= ~add
;
890 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
;
893 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
894 LUA_RETURN(ps
, LUA_FAIL
);
896 cp
= findchannel((char *)lua_tostring(ps
, 1));
898 LUA_RETURN(ps
, LUA_FAIL
);
900 modes
= (char *)lua_tostring(ps
, 2);
902 LUA_RETURN(ps
, LUA_FAIL
);
904 if(setflags(&add
, permitted
, modes
, cmodeflags
, REJECT_DISALLOWED
|REJECT_UNKNOWN
) != REJECT_NONE
)
905 LUA_RETURN(ps
, LUA_FAIL
);
907 if(setflags(&del
, permitted
, modes
, cmodeflags
, REJECT_DISALLOWED
|REJECT_UNKNOWN
) != REJECT_NONE
)
908 LUA_RETURN(ps
, LUA_FAIL
);
910 localsetmodeinit(&changes
, cp
, lua_nick
);
911 localdosetmode_simple(&changes
, add
, ~del
);
912 localsetmodeflush(&changes
, 1);
914 LUA_RETURN(ps
, LUA_OK
);
917 static int lua_sethost(lua_State
*ps
) {
921 if(!lua_islong(ps
, 1) || !lua_isstring(ps
, 2) || !lua_isstring(ps
, 3))
922 LUA_RETURN(ps
, LUA_FAIL
);
924 np
= getnickbynumeric(lua_tolong(ps
, 1));
926 LUA_RETURN(ps
, LUA_FAIL
);
928 ident
= (char *)lua_tostring(ps
, 2);
929 host
= (char *)lua_tostring(ps
, 3);
930 if(!lua_lineok(ident
) || !lua_lineok(host
))
931 LUA_RETURN(ps
, LUA_FAIL
);
933 sethostuser(np
, ident
, host
);
935 LUA_RETURN(ps
, LUA_OK
);
938 static int lua_getvisiblehostmask(lua_State
*l
) {
940 char buf
[HOSTLEN
+USERLEN
+NICKLEN
+REALLEN
+10];
942 if(!lua_islong(l
, 1))
945 np
= getnickbynumeric(lua_tolong(l
, 1));
949 lua_pushstring(l
, visiblehostmask(np
, buf
));
953 void lua_registercommands(lua_State
*l
) {
954 lua_register(l
, "irc_smsg", lua_smsg
);
955 lua_register(l
, "irc_skill", lua_skill
);
957 lua_register(l
, "chanmsg", lua_chanmsg
);
958 lua_register(l
, "versioninfo", lua_versioninfo
);
959 lua_register(l
, "basepath", lua_basepath
);
960 lua_register(l
, "botnick", lua_botnick
);
962 lua_register(l
, "irc_report", lua_chanmsg
);
963 lua_register(l
, "irc_ctcp", lua_ctcp
);
964 lua_register(l
, "irc_kill", lua_kill
);
965 lua_register(l
, "irc_kick", lua_kick
);
966 lua_register(l
, "irc_invite", lua_invite
);
967 lua_register(l
, "irc_gline", lua_gline
);
968 lua_register(l
, "irc_counthost", lua_counthost
);
969 lua_register(l
, "irc_getuserbyauth", lua_getuserbyauth
);
970 lua_register(l
, "irc_notice", lua_noticecmd
);
971 lua_register(l
, "irc_privmsg", lua_privmsgcmd
);
972 lua_register(l
, "irc_opchan", lua_opchan
);
973 lua_register(l
, "irc_voicechan", lua_voicechan
);
974 lua_register(l
, "irc_chanfix", lua_chanfix
);
975 lua_register(l
, "irc_clearmode", lua_clearmode
);
976 lua_register(l
, "irc_ban", lua_ban
);
977 lua_register(l
, "irc_deopchan", lua_deopchan
);
978 lua_register(l
, "irc_topic", lua_topic
);
980 lua_register(l
, "irc_getfirstnick", lua_getfirstnick
);
981 lua_register(l
, "irc_getnextnick", lua_getnextnick
);
983 lua_register(l
, "irc_getnickchans", lua_getnickchans
);
984 lua_register(l
, "irc_getnickchanindex", lua_getnickchanindex
);
985 lua_register(l
, "irc_getnickchancount", lua_getnickchancount
);
987 lua_register(l
, "irc_getuserchanmodes", lua_getuserchanmodes
);
989 lua_register(l
, "irc_getfirstchannick", lua_getfirstchannick
);
990 lua_register(l
, "irc_getnextchannick", lua_getnextchannick
);
992 lua_register(l
, "irc_gethostusers", lua_gethostusers
);
993 lua_register(l
, "irc_getnickcountry", lua_getnickcountry
);
995 lua_register(l
, "irc_getfirstchan", lua_getfirstchan
);
996 lua_register(l
, "irc_getnextchan", lua_getnextchan
);
997 lua_register(l
, "irc_getusermodes", lua_getusermodes
);
998 lua_register(l
, "irc_nickonchan", lua_nickonchan
);
1000 lua_register(l
, "irc_fastgetnickbynumeric", lua_fastgetnickbynumeric
);
1001 lua_register(l
, "irc_fastgetnickbynick", lua_fastgetnickbynick
);
1002 lua_register(l
, "irc_fastgetchaninfo", lua_fastgetchaninfo
);
1004 lua_register(l
, "irc_getvisiblehostmask", lua_getvisiblehostmask
);
1006 lua_register(l
, "irc_simplechanmode", lua_simplechanmode
);
1007 lua_register(l
, "irc_sethost", lua_sethost
);
1009 lua_register(l
, "irc_numerictobase64", lua_numerictobase64
);
1010 lua_register(l
, "ircmatch", lua_match
);
1012 lua_register(l
, "irc_nickmatchban", lua_nickmatchban
);
1013 lua_register(l
, "irc_nickistrusted", lua_nickistrusted
);
1014 lua_register(l
, "irc_nickbanned", lua_nickbanned
);
1015 lua_register(l
, "irc_suggestbanmask", lua_suggestbanmask
);
1020 static int lua_smsg(lua_State
*ps
) {
1021 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
1022 LUA_RETURN(ps
, LUA_FAIL
);
1024 LUA_RETURN(ps
, lua_cmsg((char *)lua_tostring(ps
, 2), "%s", lua_tostring(ps
, 1)));
1027 static int lua_skill(lua_State
*ps
) {
1028 const char *n
, *msg
;
1031 if(!lua_isstring(ps
, 1) || !lua_isstring(ps
, 2))
1032 LUA_RETURN(ps
, LUA_FAIL
);
1034 n
= lua_tostring(ps
, 1);
1035 msg
= lua_tostring(ps
, 2);
1037 np
= getnickbynick(n
);
1039 LUA_RETURN(ps
, LUA_FAIL
);
1041 if(IsOper(np
) || IsService(np
) || IsXOper(np
))
1042 LUA_RETURN(ps
, LUA_FAIL
);
1044 if(!lua_lineok(msg
))
1045 LUA_RETURN(ps
, LUA_FAIL
);
1047 killuser(lua_nick
, np
, "%s", msg
);
1049 LUA_RETURN(ps
, LUA_OK
);
1052 #define PUSHER_STRING 1
1053 #define PUSHER_REALNAME 2
1055 #define PUSHER_LONG 4
1056 #define PUSHER_HOSTNAME 5
1057 #define PUSHER_SSTRING 6
1058 #define PUSHER_TOTALUSERS 7
1059 #define PUSHER_TOPIC 8
1060 #define PUSHER_UMODES 9
1061 #define PUSHER_COUNTRY 10
1062 #define PUSHER_REALUSERS 11
1063 #define PUSHER_CHANMODES 12
1064 #define PUSHER_TIMESTAMP 13
1065 #define PUSHER_STRING_INDIRECT 14
1066 #define PUSHER_ACC_ID 15
1067 #define PUSHER_SERVER_NAME 16
1068 #define PUSHER_SERVER_NUMERIC 17
1069 #define PUSHER_IS_SERVICE 18
1071 void lua_initnickpusher(void) {
1074 #define PUSH_NICKPUSHER(F2, O2) nickpusher[i].argtype = F2; nickpusher[i].structname = #O2; nickpusher[i].offset = offsetof(nick, O2); i++;
1075 #define PUSH_NICKPUSHER_CUSTOM(F2, custom) nickpusher[i].argtype = F2; nickpusher[i].structname = custom; nickpusher[i].offset = 0; i++;
1077 PUSH_NICKPUSHER(PUSHER_STRING
, nick
);
1078 PUSH_NICKPUSHER(PUSHER_STRING
, ident
);
1079 PUSH_NICKPUSHER(PUSHER_HOSTNAME
, host
);
1080 PUSH_NICKPUSHER(PUSHER_REALNAME
, realname
);
1081 PUSH_NICKPUSHER(PUSHER_STRING_INDIRECT
, authname
);
1082 PUSH_NICKPUSHER(PUSHER_IP
, ipnode
);
1083 PUSH_NICKPUSHER(PUSHER_LONG
, numeric
);
1084 PUSH_NICKPUSHER(PUSHER_LONG
, timestamp
);
1085 PUSH_NICKPUSHER(PUSHER_LONG
, accountts
);
1086 PUSH_NICKPUSHER(PUSHER_UMODES
, umodes
);
1087 PUSH_NICKPUSHER_CUSTOM(PUSHER_COUNTRY
, "country");
1088 PUSH_NICKPUSHER_CUSTOM(PUSHER_ACC_ID
, "accountid");
1089 PUSH_NICKPUSHER_CUSTOM(PUSHER_SERVER_NAME
, "servername");
1090 PUSH_NICKPUSHER_CUSTOM(PUSHER_SERVER_NUMERIC
, "servernumeric");
1091 PUSH_NICKPUSHER_CUSTOM(PUSHER_IS_SERVICE
, "isservice");
1093 nickpushercount
= i
;
1094 nickpusher
[i
].argtype
= 0;
1097 void lua_setuppusher(struct lua_pusher
*pusherlist
, lua_State
*l
, int index
, struct lua_pusher
**lp
, int max
, int pcount
) {
1103 if(!lua_istable(l
, index
) || (max
< 2))
1110 while(lua_next(l
, index
)) {
1111 if(lua_isint(l
, -1)) {
1112 int index
= lua_toint(l
, -1);
1113 if((index
>= 0) && (index
< pcount
))
1114 lp
[current
++] = &pusherlist
[index
];
1126 int lua_usepusher(lua_State
*l
, struct lua_pusher
**lp
, void *np
) {
1130 void *offset
= (void *)np
+ (*lp
)->offset
;
1132 switch((*lp
)->argtype
) {
1134 lua_pushstring(l
, (char *)offset
);
1136 case PUSHER_STRING_INDIRECT
:
1137 lua_pushstring(l
, *(char **)offset
);
1139 case PUSHER_HOSTNAME
:
1140 lua_pushstring(l
, (*(host
**)offset
)->name
->content
);
1142 case PUSHER_REALNAME
:
1143 lua_pushstring(l
, (*(realname
**)offset
)->name
->content
);
1145 case PUSHER_SSTRING
:
1146 lua_pushstring(l
, (*((sstring
**)offset
))->content
);
1149 lua_pushlong(l
, *((long *)offset
));
1151 case PUSHER_TIMESTAMP
:
1152 lua_pushlong(l
, (*((channel
**)offset
))->timestamp
);
1155 lua_pushstring(l
, IPtostr((*((patricia_node_t
**)offset
))->prefix
->sin
));
1157 case PUSHER_TOTALUSERS
:
1158 lua_pushint(l
, (*((channel
**)offset
))->users
->totalusers
);
1160 case PUSHER_CHANMODES
:
1161 lua_pushstring(l
, printallmodes(*((channel
**)offset
)));
1165 nick
*tnp
= (nick
*)np
;
1166 if(IsAccount(tnp
) && tnp
->auth
) {
1167 lua_pushlong(l
, tnp
->auth
->userid
);
1173 case PUSHER_REALUSERS
:
1175 channel
*cp
= *((channel
**)offset
);
1177 int i
, currentusers
= countuniquehosts(cp
);
1178 for(i
=0;i
<cp
->users
->hashsize
;i
++) {
1179 if(cp
->users
->content
[i
]==nouser
)
1182 if((np2
=getnickbynumeric(cp
->users
->content
[i
]))==NULL
) {
1183 Error("lua", ERR_ERROR
, "Found unknown numeric %lu on channel %s", cp
->users
->content
[i
], cp
->index
->name
->content
);
1187 if (IsXOper(np2
) || IsService(np2
))
1190 lua_pushint(l
, currentusers
);
1194 lua_pushstring(l
, printflags(*((flag_t
*)offset
), umodeflags
));
1197 if((*((channel
**)offset
))->topic
) {
1198 lua_pushstring(l
, (*((channel
**)offset
))->topic
->content
);
1203 case PUSHER_COUNTRY
:
1207 lua_pushint(l
, (long)((nick
*)offset
)->exts
[geoipext
]);
1210 case PUSHER_SERVER_NAME
:
1211 lua_pushstring(l
, serverlist
[homeserver(((nick
*)offset
)->numeric
)].name
->content
);
1213 case PUSHER_SERVER_NUMERIC
:
1214 lua_pushint(l
, homeserver(((nick
*)offset
)->numeric
));
1216 case PUSHER_IS_SERVICE
:
1217 lua_pushboolean(l
, NickOnServiceServer((nick
*)offset
));
1228 void lua_initchanpusher(void) {
1231 #define PUSH_CHANPUSHER(F2, O2, N2) chanpusher[i].argtype = F2; chanpusher[i].structname = N2; chanpusher[i].offset = offsetof(chanindex, O2); i++;
1233 PUSH_CHANPUSHER(PUSHER_SSTRING
, name
, "name");
1234 PUSH_CHANPUSHER(PUSHER_TOTALUSERS
, channel
, "totalusers");
1235 PUSH_CHANPUSHER(PUSHER_TOPIC
, channel
, "topic");
1236 PUSH_CHANPUSHER(PUSHER_REALUSERS
, channel
, "realusers");
1237 PUSH_CHANPUSHER(PUSHER_TIMESTAMP
, channel
, "timestamp");
1238 PUSH_CHANPUSHER(PUSHER_CHANMODES
, channel
, "modes");
1240 chanpushercount
= i
;
1241 chanpusher
[i
].argtype
= 0;