/* * IRC - Internet Relay Chat levelimit.c * (C) 2005 Dominick Meglio * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 1, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" #include "struct.h" #include "common.h" #include "sys.h" #include "numeric.h" #include "msg.h" #include "proto.h" #include "channel.h" #include #include #include #include #include #include "h.h" #define MOD_NAME levellimit ModuleHeader MOD_HEADER(levellimit) = { "levellimit", "1.0", "Kanal ve Nick access koruma modulu", "3.2-b8-1", NULL, }; Cmode_t EXTCMODE_LEVELLIMIT = 0L; int modeP_is_ok(aClient *sptr, aChannel *chptr, char *para, int checkt, int what); CmodeParam * modeP_put_param(CmodeParam *lst, char *para); char *modeP_get_param(CmodeParam *lst); char *modeP_conv_param(char *param); void modeP_free_param(CmodeParam *lst); CmodeParam *modeP_dup_struct(CmodeParam *src); int modeP_sjoin_check(aChannel *chptr, CmodeParam *ourx, CmodeParam *theirx); int h_modeP_pre_local_join(aClient *, aChannel *); int levelToMode(char level); typedef struct { EXTCM_PAR_HEADER char level; } aModePEntry; DLLFUNC int MOD_INIT(MOD_NAME)(ModuleInfo *modinfo) { CmodeInfo req; ModuleSetOptions(modinfo->handle, MOD_OPT_PERM); memset(&req, 0, sizeof(req)); req.flag = 'P'; req.paracount = 1; req.is_ok = modeP_is_ok; req.put_param = modeP_put_param; req.get_param = modeP_get_param; req.conv_param = modeP_conv_param; req.free_param = modeP_free_param; req.sjoin_check = modeP_sjoin_check; req.dup_struct = modeP_dup_struct; CmodeAdd(modinfo->handle, req, &EXTCMODE_LEVELLIMIT); HookAddEx(modinfo->handle, HOOKTYPE_PRE_LOCAL_JOIN, h_modeP_pre_local_join); return MOD_SUCCESS; } DLLFUNC int MOD_LOAD(MOD_NAME)(int module_load) { return MOD_SUCCESS; } DLLFUNC int MOD_UNLOAD(MOD_NAME)(int module_unload) { return MOD_FAILED; } int modeP_is_ok(aClient *sptr, aChannel *chptr, char *para, int checkt, int what) { if ((checkt == EXCHK_ACCESS) || (checkt == EXCHK_ACCESS_ERR)) { int mustHaveMode = UMODE_OPER; if (what == MODE_ADD) mustHaveMode = levelToMode(*para); else { aModePEntry *para = (aModePEntry *)extcmode_get_struct(chptr->mode.extmodeparam, 'P'); if (para) mustHaveMode = levelToMode(para->level); } if (!(sptr->umodes & mustHaveMode)) { if (checkt == EXCHK_ACCESS_ERR) sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, sptr->name); return 0; } return 1; } else if (checkt == EXCHK_PARAM) { switch (*para) { case 'o': case 'O': case 'C': case 'A': case 'a': case 'N': return 1; default: return 0; } } return 0; } CmodeParam * modeP_put_param(CmodeParam *para_struct, char *para) { aModePEntry *r = (aModePEntry *)para_struct; if (!r) { /* Need to create one */ r = (aModePEntry *)malloc(sizeof(aModePEntry)); memset(r, 0, sizeof(aModePEntry)); r->flag = 'P'; } r->level = *para; return (CmodeParam *)r; } char *modeP_get_param(CmodeParam *para_struct) { aModePEntry *r = (aModePEntry *)para_struct; static char tmpret[2]; if (!r) return NULL; tmpret[0] = r->level; tmpret[1] = 0; return tmpret; } char *modeP_conv_param(char *param) { static char tmpret[2]; sprintf(tmpret, "%c", *param); if (tmpret[0] == 'O') tmpret[0] = 'o'; return tmpret; } void modeP_free_param(CmodeParam *para_struct) { aModePEntry *r = (aModePEntry *)para_struct; free(r); } CmodeParam *modeP_dup_struct(CmodeParam *src) { aModePEntry *n = (aModePEntry *)malloc(sizeof(aModePEntry)); memcpy(n, src, sizeof(aModePEntry)); return (CmodeParam *)n; } int levelToInt(char level) { switch (level) { case 'o': return 1; case 'C': return 2; case 'A': return 3; case 'a': return 4; case 'N': return 5; } return 0; } int levelToMode(char level) { int mustHaveMode = UMODE_OPER; switch (level) { case 'C': mustHaveMode |= UMODE_COADMIN; case 'A': mustHaveMode |= UMODE_ADMIN; case 'a': mustHaveMode |= UMODE_SADMIN; case 'N': mustHaveMode |= UMODE_NETADMIN; } return mustHaveMode; } int modeP_sjoin_check(aChannel *chptr, CmodeParam *ourx, CmodeParam *theirx) { aModePEntry *our = (aModePEntry *)ourx; aModePEntry *their = (aModePEntry *)theirx; if (our->level == their->level) return EXSJ_SAME; if (levelToInt(our->level) > levelToInt(their->level)) return EXSJ_WEWON; else return EXSJ_THEYWON; } int h_modeP_pre_local_join(aClient *sptr, aChannel *chptr) { aModePEntry *para = (aModePEntry *)extcmode_get_struct(chptr->mode.extmodeparam, 'P'); if (!para) return HOOK_CONTINUE; if (!(sptr->umodes & levelToMode(para->level))) { sendnotice(sptr, "Joining %s requires usermode %c", chptr->chname, para->level); return HOOK_DENY; } return HOOK_CONTINUE; }