#include "module.h" #define AUTHOR "DrStein" #define MYNAME "cs_getstatusonadd" #define VERSION "0.1.4" /* -------------------------------------------- * MODULE AUTHOR AND RELEASE DATE * -------------------------------------------- * Name: cs_getstatusonadd * Author: DrStein * Date: 05-05-2004 * * -------------------------------------------- * MODULE DESCRIPTION * -------------------------------------------- * This module will change the user status on * the channel as soon as he has been added * to the access list (xOP system is supported * as well) * * -------------------------------------------- * MODULE SUPPORT * -------------------------------------------- * Tested on Unreal 3.2, but supports all IRCds * which Anope support. * * -------------------------------------------- * CHANGELOG * -------------------------------------------- * v0.1.4 - Added compatibility for old gcc * versions. (Thanks to Certus). * v0.1.3 - Fixed a memory leak bug. * v0.1.2 - Fixed bug which occur when the * user added is not online. (thanks * to grit!) * v0.1.1 - Fixed bug related to 1.6 series. * v0.1.0 - The module will check the status on * channel registration as well. * v0.0.3 - Just added a line with the hope of * fix a posible bug. * v0.0.2 - Fixed bug on /cs ACCESS list, sorry * v0.0.1 - Initial release. * */ /* --------------------------------------------- * Please don't edit anything below here. * --------------------------------------------- */ extern int should_mode_change(int16, int16); extern int xop_msgs[4][14]; int access_finderror(User * u); int xop_finderror(User *u, char *, int, int *); int register_error(User *u); static int vop_error(User *u); static int hop_error(User *u); static int aop_error(User *u); static int sop_error(User *u); int c_oponadd(User *u); int c_owneronreg(User *u); int g_err = 0; void AnopeInit(void) { int status=0; Command *c=NULL; c = createCommand("ACCESS", access_finderror, NULL,-1,-1,-1,-1,-1); status += moduleAddCommand(CHANSERV, c, MOD_HEAD); c = createCommand("ACCESS", c_oponadd, NULL,-1,-1,-1,-1,-1); status += moduleAddCommand(CHANSERV, c, MOD_TAIL); c = createCommand("VOP", vop_error, NULL,-1,-1,-1,-1,-1); status += moduleAddCommand(CHANSERV, c, MOD_HEAD); c = createCommand("HOP", hop_error, NULL,-1,-1,-1,-1,-1); status += moduleAddCommand(CHANSERV, c, MOD_HEAD); c = createCommand("AOP", aop_error, NULL,-1,-1,-1,-1,-1); status += moduleAddCommand(CHANSERV, c, MOD_HEAD); c = createCommand("SOP", sop_error, NULL,-1,-1,-1,-1,-1); status += moduleAddCommand(CHANSERV, c, MOD_HEAD); c = createCommand("REGISTER", register_error, NULL,-1,-1,-1,-1,-1); status += moduleAddCommand(CHANSERV, c, MOD_HEAD); c = createCommand("VOP", c_oponadd, NULL,-1,-1,-1,-1,-1); status += moduleAddCommand(CHANSERV, c, MOD_TAIL); c = createCommand("HOP", c_oponadd, NULL,-1,-1,-1,-1,-1); status += moduleAddCommand(CHANSERV, c, MOD_TAIL); c = createCommand("AOP", c_oponadd, NULL,-1,-1,-1,-1,-1); status += moduleAddCommand(CHANSERV, c, MOD_TAIL); c = createCommand("SOP", c_oponadd, NULL,-1,-1,-1,-1,-1); status += moduleAddCommand(CHANSERV, c, MOD_TAIL); c = createCommand("REGISTER", c_owneronreg, NULL,-1,-1,-1,-1,-1); status += moduleAddCommand(CHANSERV, c, MOD_TAIL); if (status == 0) { alog("[%s.so] Loaded successfully", MYNAME); } else { alog("[%s.so] FAILED to load - result %d", MYNAME, status); } moduleAddAuthor(AUTHOR); moduleAddVersion(VERSION); } void AnopeFini(void) { alog("[%s.so] module unloaded", MYNAME); } static int vop_error(User *u) { return xop_finderror(u, "VOP", ACCESS_VOP, xop_msgs[2]); } static int hop_error(User *u) { return xop_finderror(u, "HOP", ACCESS_HOP, xop_msgs[3]); } static int aop_error(User *u) { return xop_finderror(u, "AOP", ACCESS_AOP, xop_msgs[0]); } static int sop_error(User *u) { return xop_finderror(u, "SOP", ACCESS_SOP, xop_msgs[1]); } int access_finderror(User *u) { char *args = NULL; char *chan = NULL; char *cmd = NULL; char *nick = NULL; char *s = NULL; ChannelInfo *ci; NickAlias *na; NickCore *nc; ChanAccess *access; int i; short level = 0, ulev; int is_list = (cmd && stricmp(cmd, "LIST") == 0); int is_servadmin = is_services_admin(u); if (moduleGetLastBuffer()) { args = sstrdup(moduleGetLastBuffer()); chan = myStrGetToken(args, ' ', 0); cmd = myStrGetToken(args, ' ', 1); nick = myStrGetToken(args, ' ', 2); s = myStrGetToken(args, ' ', 3); free(args); } else { g_err = 1; return MOD_CONT; } if (!cmd || ((is_list || !stricmp(cmd, "CLEAR")) ? 0 : (stricmp(cmd, "DEL") == 0) ? (!nick || s) : !s)) { g_err = 1; return MOD_CONT; } else if (!(ci = cs_findchan(chan))) { g_err = 1; return MOD_CONT; } else if (ci->flags & CI_VERBOTEN) { g_err = 1; return MOD_CONT; } else if ((ci->flags & CI_XOP) && !is_list) { g_err = 1; return MOD_CONT; } else if (((is_list && !check_access(u, ci, CA_ACCESS_LIST)) || (!is_list && !check_access(u, ci, CA_ACCESS_CHANGE))) && !is_servadmin) { g_err = 1; return MOD_CONT; } else if (stricmp(cmd, "ADD") == 0) { if (readonly) { g_err = 1; return MOD_CONT; } level = atoi(s); ulev = get_access(u, ci); if (!is_servadmin && level >= ulev) { g_err = 1; return MOD_CONT; } if (level == 0) { g_err = 1; return MOD_CONT; } else if (level <= ACCESS_INVALID || level >= ACCESS_FOUNDER) { g_err = 1; return MOD_CONT; } na = findnick(nick); if (!na) { g_err = 1; return MOD_CONT; } if (na->status & NS_VERBOTEN) { g_err = 1; return MOD_CONT; } nc = na->nc; for (access = ci->access, i = 0; i < ci->accesscount; access++, i++) { if (access->nc == nc) { if (!is_servadmin && access->level >= ulev) { g_err = 1; return MOD_CONT; } if (access->level == level) { g_err = 1; return MOD_CONT; } g_err = 0; return MOD_CONT; } } for (i = 0; i < ci->accesscount; i++) { if (!ci->access[i].in_use) break; } if (i == ci->accesscount) { if (i > CSAccessMax) { g_err = 1; return MOD_CONT; } } } else { g_err = 1; return MOD_CONT; } g_err = 0; return MOD_CONT; } int xop_finderror(User *u, char *xname, int xlev, int *xmsgs) { char *args = NULL; char *chan = NULL; char *cmd = NULL; char *nick = NULL; ChannelInfo *ci; NickAlias *na; NickCore *nc; int i; int change = 0; short ulev; int is_servadmin = is_services_admin(u); ChanAccess *access; if (moduleGetLastBuffer()) { args = sstrdup(moduleGetLastBuffer()); chan = myStrGetToken(args, ' ', 0); cmd = myStrGetToken(args, ' ', 1); nick = myStrGetToken(args, ' ', 2); free(args); } else { g_err = 1; return MOD_CONT; } if (!cmd) { g_err = 1; return MOD_CONT; } else if (!nick) { g_err = 1; return MOD_CONT; } else if (!(ci = cs_findchan(chan))) { g_err = 1; return MOD_CONT; } else if (ci->flags & CI_VERBOTEN) { g_err = 1; return MOD_CONT; } else if (!(ci->flags & CI_XOP)) { g_err = 1; return MOD_CONT; } else if (stricmp(cmd, "ADD") == 0) { if (readonly) { g_err = 1; return MOD_CONT; } ulev = get_access(u, ci); if (!is_servadmin && (xlev >= ulev || ulev < ACCESS_AOP)) { g_err = 1; return MOD_CONT; } na = findnick(nick); if (!na) { g_err = 1; return MOD_CONT; } else if (na->status & NS_VERBOTEN) { g_err = 1; return MOD_CONT; } nc = na->nc; for (access = ci->access, i = 0; i < ci->accesscount; access++, i++) { if (access->nc == nc) { if ((access->level >= ulev) && (!u->isSuperAdmin)) { g_err = 1; return MOD_CONT; } change++; break; } } if (!change) { for (i = 0; i < ci->accesscount; i++) if (!ci->access[i].in_use) break; if (i == ci->accesscount) { if (i > CSAccessMax) { g_err = 1; return MOD_CONT; } } } } else { g_err = 1; } g_err = 0; return MOD_CONT; } int register_error(User *u) { char *args = NULL; char *chan = NULL; char *pass = NULL; char *desc = NULL; NickCore *nc; Channel *c; ChannelInfo *ci; int is_servadmin = is_services_admin(u); #ifdef USE_ENCRYPTION char founderpass[PASSMAX + 1]; #endif if (moduleGetLastBuffer()) { args = sstrdup(moduleGetLastBuffer()); chan = myStrGetToken(args, ' ', 0); pass = myStrGetToken(args, ' ', 1); desc = myStrGetToken(args, ' ', 2); free(args); } else { g_err = 1; return MOD_CONT; } if (readonly) { g_err = 1; return MOD_CONT; } if (checkDefCon(DEFCON_NO_NEW_CHANNELS)) { g_err = 1; return MOD_CONT; } if (!desc) { g_err = 1; return MOD_CONT; } else if (*chan == '&') { g_err = 1; return MOD_CONT; } else if (!u->na || !(nc = u->na->nc)) { g_err = 1; return MOD_CONT; } else if (!nick_recognized(u)) { g_err = 1; return MOD_CONT; } else if ((ci = cs_findchan(chan)) != NULL) { g_err = 1; return MOD_CONT; } else if (!stricmp(chan, "#")) { g_err = 1; return MOD_CONT; } else if (!(c = findchan(chan)) || !chan_has_user_status(c, u, CUS_OP)) { g_err = 1; return MOD_CONT; } else if (!is_servadmin && nc->channelmax > 0 && nc->channelcount >= nc->channelmax) { g_err = 1; return MOD_CONT; #ifdef USE_ENCRYPTION } else if (strscpy(founderpass, pass, PASSMAX + 1), encrypt_in_place(founderpass, PASSMAX) < 0) { g_err = 1; return MOD_CONT; #endif } else { g_err = 0; return MOD_CONT; } return MOD_CONT; } int c_oponadd(User *u) { char *args = NULL; char *chan = NULL; char *nick = NULL; char *chan2; char *chan3; Channel *c; Channel *c2; User *u2; struct u_chanlist *uc; if (g_err > 0) { return MOD_CONT; } if (moduleGetLastBuffer()) { args = sstrdup(moduleGetLastBuffer()); chan = myStrGetToken(args, ' ', 0); nick = myStrGetToken(args, ' ', 2); free(args); } else { return MOD_CONT; } u2 = finduser(nick); if (!u2) return MOD_CONT; c = findchan(chan); chan3 = c->name; for (uc = u2->chans; uc; uc = uc->next) { if ((c2 = uc->chan)) { chan2 = c2->name; if (chan2 == chan3) { #if defined(IRC_UNREAL) || defined(IRC_VIAGRA) if (should_mode_change(uc->status, CUS_OWNER) && check_should_owner(u2, chan)) { chan_set_user_status(c, u2, CUS_OWNER); } else #endif #if defined(IRC_UNREAL) || defined(IRC_VIAGRA) || defined(IRC_ULTIMATE3) if (should_mode_change(uc->status, CUS_PROTECT) && check_should_protect(u2, chan)) { chan_set_user_status(c, u2, CUS_PROTECT); } else #endif if (should_mode_change(uc->status, CUS_OP) && check_should_op(u2, chan)) { chan_set_user_status(c, u2, CUS_OP); } else #ifdef HAS_HALFOP if (should_mode_change(uc->status, CUS_HALFOP) && check_should_halfop(u2, chan)) { chan_set_user_status(c, u2, CUS_HALFOP); } else #endif if (should_mode_change(uc->status, CUS_VOICE) && check_should_voice(u2, chan)) { chan_set_user_status(c, u2, CUS_VOICE); } return MOD_CONT; } } } return MOD_CONT; } int c_owneronreg(User *u) { char *args = NULL; char *chan = NULL; char *chan2; char *chan3; Channel *c; Channel *c2; struct u_chanlist *uc; if (g_err > 0) { return MOD_CONT; } if (moduleGetLastBuffer()) { args = sstrdup(moduleGetLastBuffer()); chan = myStrGetToken(args, ' ', 0); free(args); } else { return MOD_CONT; } c = findchan(chan); chan3 = c->name; for (uc = u->chans; uc; uc = uc->next) { if ((c2 = uc->chan)) { chan2 = c2->name; if (chan2 == chan3) { #if defined(IRC_UNREAL) || defined(IRC_VIAGRA) if (should_mode_change(uc->status, CUS_OWNER) && check_should_owner(u, chan)) { chan_set_user_status(c, u, CUS_OWNER); } else #endif #if defined(IRC_ULTIMATE3) if (should_mode_change(uc->status, CUS_PROTECT) && check_should_protect(u, chan)) { chan_set_user_status(c, u, CUS_PROTECT); } else #endif if (should_mode_change(uc->status, CUS_OP) && check_should_op(u, chan)) { chan_set_user_status(c, u, CUS_OP); } return MOD_CONT; } } } return MOD_CONT; } /* EOF */