#include "../localuser/localuserchannel.h"
#include "../lib/irc_string.h"
#include "../lib/flags.h"
+#include "../authext/authext.h"
#include "lua.h"
#include "luabot.h"
struct lua_pusher chanpusher[MAX_PUSHER];
int nickpushercount, chanpushercount;
-INLINE void lua_setuppusher(struct lua_pusher *pusherlist, lua_State *l, int index, struct lua_pusher **lp, int max, int pcount);
-INLINE int lua_usepusher(lua_State *l, struct lua_pusher **lp, void *np);
+void lua_setuppusher(struct lua_pusher *pusherlist, lua_State *l, int index, struct lua_pusher **lp, int max, int pcount);
+int lua_usepusher(lua_State *l, struct lua_pusher **lp, void *np);
void lua_initnickpusher(void);
void lua_initchanpusher(void);
#define lua_setupnickpusher(L2, I2, P2, M2) lua_setuppusher(&nickpusher[0], L2, I2, P2, M2, nickpushercount)
#define lua_setupchanpusher(L2, I2, P2, M2) lua_setuppusher(&chanpusher[0], L2, I2, P2, M2, chanpushercount)
+int lua_cmsg(char *channell, char *message, ...) __attribute__ ((format (printf, 2, 3)));
+
int lua_cmsg(char *channell, char *message, ...) {
char buf[512];
va_list va;
snprintf(mask, sizeof(mask), "*@%s", IPtostr(target->p_ipaddr));
}
- irc_send("%s GL * +%s %d :%s", mynumeric->content, mask, duration, reason);
+ irc_send("%s GL * +%s %d %jd :%s", mynumeric->content, mask, duration, (intmax_t)getnettime(), reason);
LUA_RETURN(ps, lua_cmsg(LUA_PUKECHAN, "lua-GLINE: %s (%d users, %d seconds -- %s)", mask, usercount, duration, reason));
}
-static int lua_getchaninfo(lua_State *ps) {
+static int lua_fastgetchaninfo(lua_State *ps) {
+ static struct lua_pusher *ourpusher[MAX_PUSHER];
channel *cp;
if(!lua_isstring(ps, 1))
return 0;
cp = findchannel((char *)lua_tostring(ps, 1));
- if(!cp)
+ if(!cp || cp->index->channel != cp)
return 0;
- LUA_PUSHCHAN(ps, cp);
-
- return 1;
+ lua_setupchanpusher(ps, 2, ourpusher, MAX_PUSHER);
+ return lua_usepusher(ps, ourpusher, cp->index);
}
static int lua_opchan(lua_State *ps) {
return 1;
}
-/* O(n) */
+static int lua_botnick(lua_State *ps) {
+ lua_pushstring(ps, luabotnick->content);
+
+ return 1;
+}
+
+static int lua_numerictobase64(lua_State *ps) {
+ if(!lua_islong(ps, 1))
+ return 0;
+
+ lua_pushstring(ps, longtonumeric(lua_tolong(ps, 1), 5));
+ return 1;
+}
+
static int lua_getuserbyauth(lua_State *l) {
- const char *acc;
nick *np;
- int i, found = 0;
+ int found = 0;
+ authname *au;
if(!lua_isstring(l, 1))
return 0;
- acc = lua_tostring(l, 1);
+ au = getauthbyname(lua_tostring(l, 1));
+ if(!au)
+ return 0;
- for(i=0;i<NICKHASHSIZE;i++) {
- for(np=nicktable[i];np;np=np->next) {
- if(np && np->authname && !ircd_strcmp(np->authname, acc)) {
- LUA_PUSHNICK(l, np);
- found++;
- }
- }
+ for(np=au->nicks;np;np=np->nextbyauthname) {
+ lua_pushnumeric(l, np->numeric);
+ found++;
}
return found;
int hashindex;
nick *lasthashnick;
+static int geoipext;
struct lua_pusher *nickhashpusher[MAX_PUSHER];
lasthashnick = NULL;
lua_setupnickpusher(l, 1, nickhashpusher, MAX_PUSHER);
+ geoipext = findnickext("geoip");
return lua_getnextnick(l);
}
count = np->host->clonecount;
do {
- LUA_PUSHNICK(l, np);
+ lua_pushnumeric(l, np->numeric);
np = np->nextbyhost;
} while(np);
if(!np)
return 0;
- lua_pushint(l, (int)np->exts[ext]);
+ lua_pushint(l, (long)np->exts[ext]);
return 1;
}
return 1;
}
-static int lua_getnickbynick(lua_State *l) {
- nick *np;
-
- if(!lua_isstring(l, 1))
- return 0;
-
- np = getnickbynick(lua_tostring(l, 1));
- if(!np)
- return 0;
-
- LUA_PUSHNICK(l, np);
- return 1;
-}
-
-static int lua_getnickbynumeric(lua_State *l) {
+static int lua_fastgetnickbynumeric(lua_State *l) {
+ static struct lua_pusher *ourpusher[MAX_PUSHER];
nick *np;
if(!lua_islong(l, 1))
if(!np)
return 0;
- LUA_PUSHNICK(l, np);
- return 1;
+ lua_setupnickpusher(l, 2, ourpusher, MAX_PUSHER);
+ return lua_usepusher(l, ourpusher, np);
}
-static int lua_fastgetnickbynumeric(lua_State *l) {
+static int lua_fastgetnickbynick(lua_State *l) {
static struct lua_pusher *ourpusher[MAX_PUSHER];
nick *np;
- if(!lua_islong(l, 1))
+ if(!lua_isstring(l, 1))
return 0;
- np = getnickbynumeric(lua_tolong(l, 1));
+ np = getnickbynick((char *)lua_tostring(l, 1));
if(!np)
return 0;
channel *cp;
char *modes;
flag_t add = 0, del = ~add;
- 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;
+ 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;
modechanges changes;
if(!lua_isstring(ps, 1) || !lua_isstring(ps, 2))
LUA_RETURN(ps, LUA_OK);
}
+static int lua_sethost(lua_State *ps) {
+ char *ident, *host;
+ nick *np;
+
+ if(!lua_islong(ps, 1) || !lua_isstring(ps, 2) || !lua_isstring(ps, 3))
+ LUA_RETURN(ps, LUA_FAIL);
+
+ np = getnickbynumeric(lua_tolong(ps, 1));
+ if(!np)
+ LUA_RETURN(ps, LUA_FAIL);
+
+ ident = (char *)lua_tostring(ps, 2);
+ host = (char *)lua_tostring(ps, 3);
+ if(!lua_lineok(ident) || !lua_lineok(host))
+ LUA_RETURN(ps, LUA_FAIL);
+
+ sethostuser(np, ident, host);
+
+ LUA_RETURN(ps, LUA_OK);
+}
+
+static int lua_getvisiblehostmask(lua_State *l) {
+ nick *np;
+ char buf[HOSTLEN+USERLEN+NICKLEN+REALLEN+10];
+
+ if(!lua_islong(l, 1))
+ return 0;
+
+ np = getnickbynumeric(lua_tolong(l, 1));
+ if(!np)
+ return 0;
+
+ lua_pushstring(l, visiblehostmask(np, buf));
+ return 1;
+}
+
void lua_registercommands(lua_State *l) {
lua_register(l, "irc_smsg", lua_smsg);
lua_register(l, "irc_skill", lua_skill);
lua_register(l, "chanmsg", lua_chanmsg);
lua_register(l, "versioninfo", lua_versioninfo);
lua_register(l, "basepath", lua_basepath);
+ lua_register(l, "botnick", lua_botnick);
lua_register(l, "irc_report", lua_chanmsg);
lua_register(l, "irc_ctcp", lua_ctcp);
lua_register(l, "irc_kick", lua_kick);
lua_register(l, "irc_invite", lua_invite);
lua_register(l, "irc_gline", lua_gline);
- lua_register(l, "irc_getchaninfo", lua_getchaninfo);
lua_register(l, "irc_counthost", lua_counthost);
lua_register(l, "irc_getuserbyauth", lua_getuserbyauth);
lua_register(l, "irc_notice", lua_noticecmd);
lua_register(l, "irc_deopchan", lua_deopchan);
lua_register(l, "irc_topic", lua_topic);
- lua_register(l, "irc_getnickbynick", lua_getnickbynick);
- lua_register(l, "irc_getnickbynumeric", lua_getnickbynumeric);
lua_register(l, "irc_getfirstnick", lua_getfirstnick);
lua_register(l, "irc_getnextnick", lua_getnextnick);
lua_register(l, "irc_nickonchan", lua_nickonchan);
lua_register(l, "irc_fastgetnickbynumeric", lua_fastgetnickbynumeric);
+ lua_register(l, "irc_fastgetnickbynick", lua_fastgetnickbynick);
+ lua_register(l, "irc_fastgetchaninfo", lua_fastgetchaninfo);
+
+ lua_register(l, "irc_getvisiblehostmask", lua_getvisiblehostmask);
lua_register(l, "irc_simplechanmode", lua_simplechanmode);
+ lua_register(l, "irc_sethost", lua_sethost);
+
+ lua_register(l, "irc_numerictobase64", lua_numerictobase64);
}
/* --- */
#define PUSHER_SSTRING 6
#define PUSHER_TOTALUSERS 7
#define PUSHER_TOPIC 8
+#define PUSHER_UMODES 9
+#define PUSHER_COUNTRY 10
+#define PUSHER_REALUSERS 11
+#define PUSHER_CHANMODES 12
+#define PUSHER_TIMESTAMP 13
+#define PUSHER_STRING_INDIRECT 14
void lua_initnickpusher(void) {
int i = 0;
#define PUSH_NICKPUSHER(F2, O2) nickpusher[i].argtype = F2; nickpusher[i].structname = #O2; nickpusher[i].offset = offsetof(nick, O2); i++;
+#define PUSH_NICKPUSHER_CUSTOM(F2, custom) nickpusher[i].argtype = F2; nickpusher[i].structname = custom; nickpusher[i].offset = 0; i++;
PUSH_NICKPUSHER(PUSHER_STRING, nick);
PUSH_NICKPUSHER(PUSHER_STRING, ident);
PUSH_NICKPUSHER(PUSHER_HOSTNAME, host);
PUSH_NICKPUSHER(PUSHER_REALNAME, realname);
- PUSH_NICKPUSHER(PUSHER_STRING, authname);
+ PUSH_NICKPUSHER(PUSHER_STRING_INDIRECT, authname);
PUSH_NICKPUSHER(PUSHER_IP, ipnode);
PUSH_NICKPUSHER(PUSHER_LONG, numeric);
+ PUSH_NICKPUSHER(PUSHER_LONG, timestamp);
+ PUSH_NICKPUSHER(PUSHER_LONG, accountts);
+ PUSH_NICKPUSHER(PUSHER_UMODES, umodes);
+ PUSH_NICKPUSHER_CUSTOM(PUSHER_COUNTRY, "country");
nickpushercount = i;
nickpusher[i].argtype = 0;
}
-INLINE void lua_setuppusher(struct lua_pusher *pusherlist, lua_State *l, int index, struct lua_pusher **lp, int max, int pcount) {
+void lua_setuppusher(struct lua_pusher *pusherlist, lua_State *l, int index, struct lua_pusher **lp, int max, int pcount) {
int current = 0;
if(max > 0)
lp[current] = NULL;
}
-INLINE int lua_usepusher(lua_State *l, struct lua_pusher **lp, void *np) {
+int lua_usepusher(lua_State *l, struct lua_pusher **lp, void *np) {
int i = 0;
while(*lp) {
case PUSHER_STRING:
lua_pushstring(l, (char *)offset);
break;
+ case PUSHER_STRING_INDIRECT:
+ lua_pushstring(l, *(char **)offset);
+ break;
case PUSHER_HOSTNAME:
lua_pushstring(l, (*(host **)offset)->name->content);
break;
case PUSHER_LONG:
lua_pushlong(l, *((long *)offset));
break;
+ case PUSHER_TIMESTAMP:
+ lua_pushlong(l, (*((channel **)offset))->timestamp);
+ break;
case PUSHER_IP:
- lua_pushstring(l, IPtostr((((patricia_node_t *)offset)->prefix->sin)));
+ lua_pushstring(l, IPtostr((*((patricia_node_t **)offset))->prefix->sin));
break;
case PUSHER_TOTALUSERS:
lua_pushint(l, (*((channel **)offset))->users->totalusers);
break;
+ case PUSHER_CHANMODES:
+ lua_pushstring(l, printallmodes(*((channel **)offset)));
+ break;
+ case PUSHER_REALUSERS:
+ {
+ channel *cp = *((channel **)offset);
+ nick *np2;
+ int i, currentusers = countuniquehosts(cp);
+ for(i=0;i<cp->users->hashsize;i++) {
+ if(cp->users->content[i]==nouser)
+ continue;
+
+ if((np2=getnickbynumeric(cp->users->content[i]))==NULL) {
+ Error("lua", ERR_ERROR, "Found unknown numeric %lu on channel %s", cp->users->content[i], cp->index->name->content);
+ continue;
+ }
+
+ if (IsXOper(np2) || IsService(np2))
+ currentusers--;
+ }
+ lua_pushint(l, currentusers);
+ }
+ break;
+ case PUSHER_UMODES:
+ lua_pushstring(l, printflags(*((flag_t *)offset), umodeflags));
+ break;
case PUSHER_TOPIC:
if((*((channel **)offset))->topic) {
lua_pushstring(l, (*((channel **)offset))->topic->content);
lua_pushnil(l);
}
break;
+ case PUSHER_COUNTRY:
+ if(geoipext < 0) {
+ lua_pushint(l, -1);
+ } else {
+ lua_pushint(l, (long)((nick *)offset)->exts[geoipext]);
+ }
+ break;
}
i++;
PUSH_CHANPUSHER(PUSHER_SSTRING, name, "name");
PUSH_CHANPUSHER(PUSHER_TOTALUSERS, channel, "totalusers");
PUSH_CHANPUSHER(PUSHER_TOPIC, channel, "topic");
+ PUSH_CHANPUSHER(PUSHER_REALUSERS, channel, "realusers");
+ PUSH_CHANPUSHER(PUSHER_TIMESTAMP, channel, "timestamp");
+ PUSH_CHANPUSHER(PUSHER_CHANMODES, channel, "modes");
chanpushercount = i;
chanpusher[i].argtype = 0;