void lua_localnickhandler(nick *target, int type, void **args);
void lua_reconnectlocal(void *arg);
-static int lua_registerlocaluser(lua_State *ps) {
- nick *np;
+static int lua_registerlocaluserid(lua_State *ps) {
lua_list *l;
lua_localnick *ln;
char *nickname, *ident, *hostname, *realname, *account;
flag_t modes = 0;
+ long userid;
- if(!lua_isstring(ps, 1) || !lua_isstring(ps, 2) || !lua_isstring(ps, 3) || !lua_isstring(ps, 4) || !lua_isstring(ps, 5) || !lua_isstring(ps, 6) || !lua_isfunction(ps, 7))
+ if(!lua_isstring(ps, 1) || !lua_isstring(ps, 2) || !lua_isstring(ps, 3) || !lua_isstring(ps, 4) || !lua_isstring(ps, 5) || !lua_isstring(ps, 7) || !lua_isfunction(ps, 8))
return 0;
nickname = (char *)lua_tostring(ps, 1);
hostname = (char *)lua_tostring(ps, 3);
realname = (char *)lua_tostring(ps, 4);
account = (char *)lua_tostring(ps, 5);
+ if(lua_islong(ps, 6)) {
+ userid = lua_tolong(ps, 6);
+ } else {
+ userid = 0;
+ }
- setflags(&modes, UMODE_ALL, (char *)lua_tostring(ps, 6), umodeflags, REJECT_NONE);
+ setflags(&modes, UMODE_ALL, (char *)lua_tostring(ps, 7), umodeflags, REJECT_NONE);
if(!lua_lineok(nickname) || !lua_lineok(ident) || !lua_lineok(hostname) || !lua_lineok(realname) || !lua_lineok(account))
return 0;
if(!l)
return 0;
- ln = (lua_localnick *)malloc(sizeof(lua_localnick));
+ ln = (lua_localnick *)luamalloc(sizeof(lua_localnick));
if(!ln)
return 0;
ln->reconnect = NULL;
- ln->nick = registerlocaluser(nickname, ident, hostname, realname, account, modes, &lua_localnickhandler);
+ ln->nick = registerlocaluserflags(nickname, ident, hostname, realname, account, userid, 0, modes, &lua_localnickhandler);
if(!ln->nick) {
- free(ln);
+ luafree(ln);
return 0;
}
ln->next = l->nicks;
l->nicks = ln;
- lua_pushlong(ps, np->numeric);
+ lua_pushlong(ps, ln->nick->numeric);
return 1;
}
luaL_unref(ps, LUA_REGISTRYINDEX, l->handler);
- free(l);
+ luafree(l);
}
int lua_getlocalnickbynick(nick *np, lua_list **rl, lua_localnick **rln) {
if(!lua_islong(ps, 1))
LUA_RETURN(ps, LUA_FAIL);
+ numeric = lua_tolong(ps, 1);
+
quitm = lua_isstring(ps, 2)?(char *)lua_tostring(ps, 2):"localuser unregistered.";
l = lua_listfromstate(ps);
for(l2=l->nicks;l2;lp=l2,l2=l2->next) {
- if(l2->nick->numeric == numeric) {
- lp->next = l2->next;
+ if(l2->nick && l2->nick->numeric == numeric) {
+ if(lp) {
+ lp->next = l2->next;
+ } else {
+ l->nicks = l2->next;
+ }
+
lua_freelocalnick(ps, l2, quitm);
LUA_RETURN(ps, LUA_OK);
}
void lua_deregisternicks(lua_list *l) {
struct lua_localnick *ln, *pn;
- for(ln=l->nicks;ln;ln=pn) {
+ ln = l->nicks;
+ l->nicks = NULL;
+ for(;ln;ln=pn) {
pn = ln->next;
lua_freelocalnick(l->l, ln, "Script unloaded.");
break;
+ case LU_PRIVNOTICE:
+ np = (nick *)args[0];
+ p = (char *)args[1];
+
+ if(!np || !p)
+ return;
+
+ lua_vlpcall(l, ln, "irc_onnotice", "Ns", np, p);
+
+ break;
+
case LU_CHANMSG:
np = (nick *)args[0];
c = (channel *)args[1];
ln->reconnect = scheduleoneshot(time(NULL) + 1, &lua_reconnectlocal, ln);
+ break;
+ case LU_INVITE:
+ /* we were invited, check if someone invited us to PUBLICCHAN */
+ np = (nick *)args[0];
+ c = (channel *)args[1];
+
+ if(!c || !np || !c->index || !c->index->name)
+ return;
+
+ lua_vlpcall(l, ln, "irc_oninvite", "Ns", np, c->index->name->content);
break;
}
}
LUA_RETURN(ps, LUA_FAIL);
chan = (char *)lua_tostring(ps, 2);
+ if(chan[0] != '#')
+ LUA_RETURN(ps, LUA_FAIL);
if(!lua_lineok(chan))
LUA_RETURN(ps, LUA_FAIL);
LUA_RETURN(ps, LUA_OK);
}
+static int lua_localpart(lua_State *ps) {
+ nick *source;
+ channel *target;
+ char *chan, *reason;
+
+ if(!lua_islong(ps, 1) || !lua_isstring(ps, 2))
+ LUA_RETURN(ps, LUA_FAIL);
+
+ source = getnickbynumeric(lua_tolong(ps, 1));
+ if(!source)
+ LUA_RETURN(ps, LUA_FAIL);
+
+ chan = (char *)lua_tostring(ps, 2);
+
+ if(!lua_lineok(chan))
+ LUA_RETURN(ps, LUA_FAIL);
+
+ if(lua_isstring(ps, 3)) {
+ reason = (char *)lua_tostring(ps, 3);
+ if(!lua_lineok(reason))
+ LUA_RETURN(ps, LUA_FAIL);
+ } else {
+ reason = NULL;
+ }
+
+ target = findchannel(chan);
+ if(target) {
+ localpartchannel(source, target, reason);
+ } else {
+ LUA_RETURN(ps, LUA_FAIL);
+ }
+
+ LUA_RETURN(ps, LUA_OK);
+}
+
static int lua_localchanmsg(lua_State *ps) {
char *msg;
nick *source;
LUA_RETURN(ps, LUA_OK);
}
+static int lua_localchanopnotice(lua_State *ps) {
+ char *msg;
+ nick *source;
+ channel *target;
+
+ if(!lua_islong(ps, 1) || !lua_isstring(ps, 2) || !lua_isstring(ps, 3))
+ LUA_RETURN(ps, LUA_FAIL);
+
+ source = getnickbynumeric(lua_tolong(ps, 1));
+ if(!source)
+ LUA_RETURN(ps, LUA_FAIL);
+
+ target = findchannel((char *)lua_tostring(ps, 2));
+ if(!target)
+ LUA_RETURN(ps, LUA_FAIL);
+
+ msg = (char *)lua_tostring(ps, 3);
+
+ if(!lua_lineok(msg))
+ LUA_RETURN(ps, LUA_FAIL);
+
+ sendopnoticetochannel(source, target, "%s", msg);
+
+ LUA_RETURN(ps, LUA_OK);
+}
+
static int lua_localnotice(lua_State *ps) {
char *msg;
nick *source;
LUA_RETURN(ps, LUA_OK);
}
+static int lua_localprivmsg(lua_State *ps) {
+ char *msg;
+ nick *source;
+ nick *target;
+
+ if(!lua_islong(ps, 1) || !lua_islong(ps, 2) || !lua_isstring(ps, 3))
+ LUA_RETURN(ps, LUA_FAIL);
+
+ source = getnickbynumeric(lua_tolong(ps, 1));
+ if(!source)
+ LUA_RETURN(ps, LUA_FAIL);
+
+ target = getnickbynumeric(lua_tolong(ps, 2));
+ if(!target)
+ LUA_RETURN(ps, LUA_FAIL);
+
+ msg = (char *)lua_tostring(ps, 3);
+
+ if(!lua_lineok(msg))
+ LUA_RETURN(ps, LUA_FAIL);
+
+ sendmessagetouser(source, target, "%s", msg);
+
+ LUA_RETURN(ps, LUA_OK);
+}
+
+static int lua_localovmode(lua_State *l) {
+ nick *source;
+ channel *chan;
+ int state = 0, add = 0, realmode = 0, ignoring = 0;
+ modechanges changes;
+
+ if(!lua_islong(l, 1) || !lua_isstring(l, 2) || !lua_istable(l, 3))
+ LUA_RETURN(l, LUA_FAIL);
+
+ source = getnickbynumeric(lua_tolong(l, 1));
+ if(!source)
+ LUA_RETURN(l, LUA_FAIL);
+
+ chan = findchannel((char *)lua_tostring(l, 2));
+ if(!chan)
+ LUA_RETURN(l, LUA_FAIL);
+
+ localsetmodeinit(&changes, chan, source);
+
+ lua_pushnil(l);
+
+ while(lua_next(l, 3)) {
+ if(state == 0) {
+ ignoring = 0;
+
+ if(!lua_isboolean(l, -1)) {
+ ignoring = 1;
+ } else {
+ add = (int)lua_toboolean(l, -1);
+ }
+ } else if((state == 1) && !ignoring) {
+ if(!lua_isstring(l, -1)) {
+ ignoring = 1;
+ } else {
+ char *mode = (char *)lua_tostring(l, -1);
+ if((*mode == 'o') && add) {
+ realmode = MC_OP;
+ } else if (*mode == 'o') {
+ realmode = MC_DEOP;
+ } else if((*mode == 'v') && add) {
+ realmode = MC_VOICE;
+ } else if (*mode == 'v') {
+ realmode = MC_DEVOICE;
+ } else {
+ ignoring = 1;
+ }
+ }
+ } else if((state == 2) && !ignoring) {
+ if(lua_islong(l, -1)) {
+ nick *target = getnickbynumeric(lua_tolong(l, -1));
+ if(target)
+ localdosetmode_nick(&changes, target, realmode);
+ }
+ }
+
+ lua_pop(l, 1);
+
+ state = (state + 1) % 3;
+ }
+
+ localsetmodeflush(&changes, 1);
+
+ LUA_RETURN(l, LUA_OK);
+}
+
+static int lua_localumodes(lua_State *ps) {
+ nick *np;
+ char *modes;
+ flag_t newmodes = 0;
+
+ if(!lua_islong(ps, 1) || !lua_isstring(ps, 2))
+ LUA_RETURN(ps, LUA_FAIL);
+
+ np = getnickbynumeric(lua_tolong(ps, 1));
+ if(!np)
+ LUA_RETURN(ps, LUA_FAIL);
+
+ modes = (char *)lua_tostring(ps, 2);
+
+ setflags(&newmodes, UMODE_ALL, modes, umodeflags, REJECT_NONE);
+
+ localusersetumodes(np, newmodes);
+ LUA_RETURN(ps, LUA_OK);
+}
+
+static int lua_localtopic(lua_State *ps) {
+ nick *np;
+ channel *cp;
+ char *topic;
+
+ 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);
+
+ cp = findchannel((char *)lua_tostring(ps, 2));
+ if(!cp)
+ LUA_RETURN(ps, LUA_FAIL);
+
+ topic = (char *)lua_tostring(ps, 3);
+ if(!topic || !lua_lineok(topic))
+ LUA_RETURN(ps, LUA_FAIL);
+
+ localsettopic(np, cp, topic);
+
+ LUA_RETURN(ps, LUA_OK);
+}
+
+static int lua_localban(lua_State *ps) {
+ channel *cp;
+ const char *mask;
+ modechanges changes;
+ nick *source;
+
+ int dir = MCB_ADD;
+
+ if(!lua_islong(ps, 1) || !lua_isstring(ps, 2) || !lua_isstring(ps, 3))
+ LUA_RETURN(ps, LUA_FAIL);
+
+ if(lua_isboolean(ps, 4) && lua_toboolean(ps, 4))
+ dir = MCB_DEL;
+
+ source = getnickbynumeric(lua_tolong(ps, 1));
+
+ cp = findchannel((char *)lua_tostring(ps, 2));
+ if(!cp)
+ LUA_RETURN(ps, LUA_FAIL);
+
+ mask = lua_tostring(ps, 3);
+ if(!mask || !mask[0] || !lua_lineok(mask))
+ LUA_RETURN(ps, LUA_FAIL);
+
+ localsetmodeinit(&changes, cp, source);
+ localdosetmode_ban(&changes, mask, dir);
+ localsetmodeflush(&changes, 1);
+
+ LUA_RETURN(ps, LUA_OK);
+}
+
+static int lua_localkick(lua_State *ps) {
+ const char *n, *msg, *chan;
+ nick *source, *np;
+ channel *cp;
+ int dochecks = 1;
+
+ if(!lua_islong(ps, 1) || !lua_isstring(ps, 2) || !lua_isstring(ps, 3) || !lua_isstring(ps, 4))
+ LUA_RETURN(ps, LUA_FAIL);
+
+ source = getnickbynumeric(lua_tolong(ps, 1));
+ chan = lua_tostring(ps, 2);
+ n = lua_tostring(ps, 3);
+ msg = lua_tostring(ps, 4);
+ if(!source)
+ LUA_RETURN(ps, LUA_FAIL);
+
+ if(lua_isboolean(ps, 4) && !lua_toboolean(ps, 4))
+ dochecks = 0;
+
+ np = getnickbynick(n);
+ if(!np)
+ LUA_RETURN(ps, LUA_FAIL);
+
+ if(dochecks && (IsOper(np) || IsXOper(np) || IsService(np)))
+ LUA_RETURN(ps, LUA_FAIL);
+
+ cp = findchannel((char *)chan);
+ if(!cp)
+ LUA_RETURN(ps, LUA_FAIL);
+
+ if(!lua_lineok(msg))
+ LUA_RETURN(ps, LUA_FAIL);
+
+ localkickuser(source, cp, np, msg);
+
+ LUA_RETURN(ps, LUA_OK);
+}
+
+static int lua_localrename(lua_State *ps) {
+ nick *np;
+ char *changeto;
+
+ if(!lua_islong(ps, 1) || !lua_isstring(ps, 2) )
+ LUA_RETURN(ps, LUA_FAIL);
+
+ np = getnickbynumeric(lua_tolong(ps, 1));
+ changeto = (char *)lua_tostring(ps, 2);
+
+ if(!lua_lineok(changeto))
+ LUA_RETURN(ps, LUA_FAIL);
+
+ renamelocaluser(np, changeto);
+
+ LUA_RETURN(ps, LUA_OK);
+}
+
+static int lua_localwallusers(lua_State *ps) {
+ char *msg;
+ nick *source;
+ char senderstr[6];
+
+ if(!lua_islong(ps, 1) || !lua_isstring(ps, 2))
+ LUA_RETURN(ps, LUA_FAIL);
+
+ source = getnickbynumeric(lua_tolong(ps, 1));
+ if(!source)
+ LUA_RETURN(ps, LUA_FAIL);
+
+ msg = (char *)lua_tostring(ps, 2);
+
+ if(!lua_lineok(msg))
+ LUA_RETURN(ps, LUA_FAIL);
+
+ longtonumeric2(source->numeric,5,senderstr);
+ irc_send("%s WU :%s", senderstr, msg);
+
+ LUA_RETURN(ps, LUA_OK);
+}
+
+static int lua_localwallops(lua_State *ps) {
+ char *msg;
+ nick *source;
+ char senderstr[6];
+
+ if(!lua_islong(ps, 1) || !lua_isstring(ps, 2))
+ LUA_RETURN(ps, LUA_FAIL);
+
+ source = getnickbynumeric(lua_tolong(ps, 1));
+ if(!source)
+ LUA_RETURN(ps, LUA_FAIL);
+
+ msg = (char *)lua_tostring(ps, 2);
+
+ if(!lua_lineok(msg))
+ LUA_RETURN(ps, LUA_FAIL);
+
+ longtonumeric2(source->numeric,5,senderstr);
+ irc_send("%s WA :%s", senderstr, msg);
+
+ LUA_RETURN(ps, LUA_OK);
+}
+
+static int lua_localsimplechanmode(lua_State *ps) {
+ nick *source;
+ 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 | CHANMODE_MODNOAUTH | CHANMODE_SINGLETARG;
+ modechanges changes;
+
+ if(!lua_islong(ps, 1) || !lua_isstring(ps, 2) || !lua_isstring(ps, 3))
+ LUA_RETURN(ps, LUA_FAIL);
+
+ source = getnickbynumeric(lua_tolong(ps, 1));
+ if(!source)
+ LUA_RETURN(ps, LUA_FAIL);
+
+ cp = findchannel((char *)lua_tostring(ps, 2));
+ if(!cp)
+ LUA_RETURN(ps, LUA_FAIL);
+
+ modes = (char *)lua_tostring(ps, 3);
+ if(!modes)
+ LUA_RETURN(ps, LUA_FAIL);
+
+ if(setflags(&add, permitted, modes, cmodeflags, REJECT_DISALLOWED|REJECT_UNKNOWN) != REJECT_NONE)
+ LUA_RETURN(ps, LUA_FAIL);
+
+ if(setflags(&del, permitted, modes, cmodeflags, REJECT_DISALLOWED|REJECT_UNKNOWN) != REJECT_NONE)
+ LUA_RETURN(ps, LUA_FAIL);
+
+ localsetmodeinit(&changes, cp, source);
+ localdosetmode_simple(&changes, add, ~del);
+ localsetmodeflush(&changes, 1);
+
+ LUA_RETURN(ps, LUA_OK);
+}
+
void lua_registerlocalcommands(lua_State *l) {
- lua_register(l, "irc_localregisteruser", lua_registerlocaluser);
+ lua_register(l, "irc_localregisteruserid", lua_registerlocaluserid);
lua_register(l, "irc_localderegisteruser", lua_deregisterlocaluser);
lua_register(l, "irc_localjoin", lua_localjoin);
+ lua_register(l, "irc_localpart", lua_localpart);
lua_register(l, "irc_localchanmsg", lua_localchanmsg);
lua_register(l, "irc_localnotice", lua_localnotice);
+ lua_register(l, "irc_localprivmsg", lua_localprivmsg);
+
+ lua_register(l, "irc_localovmode", lua_localovmode);
+ lua_register(l, "irc_localtopic", lua_localtopic);
+
+ lua_register(l, "irc_localban", lua_localban);
+ lua_register(l, "irc_localkick", lua_localkick);
+ lua_register(l, "irc_localumodes", lua_localumodes);
+
+ lua_register(l, "irc_localrename", lua_localrename);
+
+ lua_register(l, "irc_localwallusers", lua_localwallusers);
+ lua_register(l, "irc_localwallops", lua_localwallops);
+
+ lua_register(l, "irc_localsimplechanmode", lua_localsimplechanmode);
+ lua_register(l, "irc_localchanopnotice", lua_localchanopnotice);
}