📄 m_mode.c
字号:
break; } }#endif } if (found == 0) /* Mode char unknown */ { /* temporary hack: eat parameters of certain future chanmodes.. */ if (*curchr == 'I') paracount++; if ((*curchr == 'j') && (what == MODE_ADD)) paracount++; if (MyClient(cptr)) sendto_one(cptr, err_str(ERR_UNKNOWNMODE), me.name, cptr->name, *curchr); break; } if (checkrestr && strchr(RESTRICT_CHANNELMODES, *curchr)) { if (warnrestr) { sendto_one(cptr, ":%s %s %s :Setting/removing of channelmode(s) '%s' has been disabled.", me.name, IsWebTV(cptr) ? "PRIVMSG" : "NOTICE", cptr->name, RESTRICT_CHANNELMODES); warnrestr = 0; } paracount += foundat.parameters; break; }#ifndef NO_OPEROVERRIDE if (found == 1) { if ((Halfop_mode(modetype) == FALSE) && opermode == 2 && htrig != 1) { /* YUCK! */ if ((foundat.flag == 'h') && !(parc <= paracount) && parv[paracount] && (find_person(parv[paracount], NULL) == cptr)) { /* ircop with halfop doing a -h on himself. no warning. */ } else { opermode = 0; htrig = 1; } } }#ifdef EXTCMODE else if (found == 2) { /* Extended mode: all override stuff is in do_extmode_char which will set * opermode if appropriate. -- Syzop */ }#endif /* EXTCMODE */#endif /* !NO_OPEROVERRIDE */ /* We can afford to send off a param */ if (parc <= paracount) parv[paracount] = NULL; if (parv[paracount] && strlen(parv[paracount]) >= MODEBUFLEN) parv[paracount][MODEBUFLEN-1] = '\0'; if (found == 1) { paracount += do_mode_char(chptr, modetype, *curchr, parv[paracount], what, cptr, pcount, pvar, bounce, my_access); }#ifdef EXTCMODE else if (found == 2) { paracount += do_extmode_char(chptr, extm, parv[paracount], what, cptr, pcount, pvar, bounce); }#endif /* EXTCMODE */ break; } }#ifdef EXTCMODE make_mode_str(chptr, oldm, oldem, oldl, *pcount, pvar, modebuf, parabuf, bounce);#else make_mode_str(chptr, oldm, oldl, *pcount, pvar, modebuf, parabuf, bounce);#endif#ifndef NO_OPEROVERRIDE if (htrig == 1) { /* This is horrible. Just horrible. */ if (!((modebuf[0] == '+' || modebuf[0] == '-') && modebuf[1] == '\0')) sendto_snomask(SNO_EYES, "*** OperOverride -- %s (%s@%s) MODE %s %s %s", cptr->name, cptr->user->username, cptr->user->realhost, chptr->chname, modebuf, parabuf); /* Logging Implementation added by XeRXeS */ ircd_log(LOG_OVERRIDE,"OVERRIDE: %s (%s@%s) MODE %s %s %s", cptr->name, cptr->user->username, cptr->user->realhost, chptr->chname, modebuf, parabuf); htrig = 0; opermode = 0; /* stop double override notices... but is this ok??? -- Syzop */ }#endif}/* * m_umode() added 15/10/91 By Darren Reed. * parv[0] - sender * parv[1] - username to change mode for * parv[2] - modes to change */DLLFUNC CMD_FUNC(_m_umode){ int i; char **p, *m; aClient *acptr; int what, setflags, setsnomask = 0; /* (small note: keep 'what' as an int. -- Syzop). */ short rpterror = 0, umode_restrict_err = 0, chk_restrict = 0, modex_err = 0; what = MODE_ADD; if (parc < 2) { sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "MODE"); return 0; } if (!(acptr = find_person(parv[1], NULL))) { if (MyConnect(sptr)) sendto_one(sptr, err_str(ERR_NOSUCHNICK), me.name, parv[0], parv[1]); return 0; } if (acptr != sptr) return 0; if (parc < 3) { sendto_one(sptr, rpl_str(RPL_UMODEIS), me.name, parv[0], get_mode_str(sptr)); if (sptr->user->snomask) sendto_one(sptr, rpl_str(RPL_SNOMASK), me.name, parv[0], get_sno_str(sptr)); return 0; } /* find flags already set for user */ setflags = 0; for (i = 0; i <= Usermode_highest; i++) if ((sptr->umodes & Usermode_Table[i].mode)) setflags |= Usermode_Table[i].mode; if (RESTRICT_USERMODES && MyClient(sptr) && !IsAnOper(sptr) && !IsServer(sptr)) chk_restrict = 1; if (MyConnect(sptr)) setsnomask = sptr->user->snomask; /* * parse mode change string(s) */ p = &parv[2]; for (m = *p; *m; m++) { if (chk_restrict && strchr(RESTRICT_USERMODES, *m)) { if (!umode_restrict_err) { sendto_one(sptr, ":%s %s %s :Setting/removing of usermode(s) '%s' has been disabled.", me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", sptr->name, RESTRICT_USERMODES); umode_restrict_err = 1; } continue; } switch (*m) { case '+': what = MODE_ADD; break; case '-': what = MODE_DEL; break; /* we may not get these, * but they shouldnt be in default */ case ' ': case '\t': break; case 'r': case 't': if (MyClient(sptr)) break; /* since we now use chatops define in unrealircd.conf, we have * to disallow it here */ case 's': if (what == MODE_DEL) { if (parc >= 4 && sptr->user->snomask) { set_snomask(sptr, parv[3]); if (sptr->user->snomask == 0) goto def; break; } else { set_snomask(sptr, NULL); goto def; } } if (what == MODE_ADD) { if (parc < 4) set_snomask(sptr, IsAnOper(sptr) ? SNO_DEFOPER : SNO_DEFUSER); else set_snomask(sptr, parv[3]); goto def; } case 'o': case 'O': if(sptr->from->flags & FLAGS_QUARANTINE) { sendto_serv_butone(NULL, ":%s KILL %s :%s (Quarantined: no global oper privileges allowed)", me.name, sptr->name, me.name); return exit_client(cptr, sptr, &me, "Quarantined: no global oper privileges allowed"); } /* A local user trying to set himself +o/+O is denied here. * A while later (outside this loop) it is handled as well (and +C, +N, etc too) * but we need to take care here too because it might cause problems * since otherwise all IsOper()/IsAnOper() calls cannot be trusted, * that's just asking for bugs! -- Syzop. */ if (MyClient(sptr) && (what == MODE_ADD)) /* Someone setting himself +o? Deny it. */ break; goto def; case 'x': switch (UHOST_ALLOWED) { case UHALLOW_ALWAYS: goto def; case UHALLOW_NEVER: if (MyClient(sptr)) { if (!modex_err) { sendto_one(sptr, ":%s %s %s :*** Setting %cx is disabled", me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", sptr->name, what == MODE_ADD ? '+' : '-'); modex_err = 1; } break; } goto def; case UHALLOW_NOCHANS: if (MyClient(sptr) && sptr->user->joined) { if (!modex_err) { sendto_one(sptr, ":%s %s %s :*** Setting %cx can not be done while you are on channels", me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", sptr->name, what == MODE_ADD ? '+' : '-'); modex_err = 1; } break; } goto def; case UHALLOW_REJOIN: /* Handled later */ goto def; } break; default: def: for (i = 0; i <= Usermode_highest; i++) { if (*m == Usermode_Table[i].flag) { if (Usermode_Table[i].allowed) if (!Usermode_Table[i].allowed(sptr,what)) break; if (what == MODE_ADD) sptr->umodes |= Usermode_Table[i].mode; else sptr->umodes &= ~Usermode_Table[i].mode; break; } else if (i == Usermode_highest && MyConnect(sptr) && !rpterror) { sendto_one(sptr, err_str(ERR_UMODEUNKNOWNFLAG), me.name, parv[0]); rpterror = 1; } } break; } /* switch */ } /* for */ /* * stop users making themselves operators too easily */ if (!(setflags & UMODE_OPER) && IsOper(sptr) && !IsServer(cptr)) ClearOper(sptr); if (!(setflags & UMODE_LOCOP) && IsLocOp(sptr) && !IsServer(cptr)) sptr->umodes &= ~UMODE_LOCOP; /* * Let only operators set HelpOp * Helpops get all /quote help <mess> globals -Donwulff */ if (MyClient(sptr) && IsHelpOp(sptr) && !OPCanHelpOp(sptr)) ClearHelpOp(sptr); /* * Let only operators set FloodF, ClientF; also * remove those flags if they've gone -o/-O. * FloodF sends notices about possible flooding -Cabal95 * ClientF sends notices about clients connecting or exiting * Admin is for server admins */ if (!IsAnOper(sptr) && !IsServer(cptr)) { sptr->umodes &= ~UMODE_WHOIS; ClearAdmin(sptr); ClearSAdmin(sptr); ClearNetAdmin(sptr); ClearHideOper(sptr); ClearCoAdmin(sptr); ClearHelpOp(sptr); ClearFailops(sptr); } /* * New oper access flags - Only let them set certian usermodes on * themselves IF they have access to set that specific mode in their * O:Line. */ if (MyClient(sptr)) { if (IsAnOper(sptr)) { if (IsAdmin(sptr) && !OPIsAdmin(sptr)) ClearAdmin(sptr); if (IsSAdmin(sptr) && !OPIsSAdmin(sptr)) ClearSAdmin(sptr); if (IsNetAdmin(sptr) && !OPIsNetAdmin(sptr)) ClearNetAdmin(sptr); if (IsCoAdmin(sptr) && !OPIsCoAdmin(sptr)) ClearCoAdmin(sptr); if (MyClient(sptr) && (sptr->umodes & UMODE_SECURE) && !IsSecure(sptr)) sptr->umodes &= ~UMODE_SECURE; } /* This is to remooove the kix bug.. and to protect some stuffie -techie */ if (MyClient(sptr)) { if ((sptr->umodes & UMODE_KIX) && (!OPCanUmodeq(sptr) || !IsAnOper(sptr))) sptr->umodes &= ~UMODE_KIX; if ((sptr->umodes & UMODE_SECURE) && !IsSecure(sptr)) sptr->umodes &= ~UMODE_SECURE; if (!(sptr->umodes & UMODE_SECURE) && IsSecure(sptr)) sptr->umodes |= UMODE_SECURE; } } /* * For Services Protection... */ if (!IsServer(cptr) && !IsULine(sptr)) { if (IsServices(sptr)) ClearServices(sptr); } if ((setflags & UMODE_HIDE) && !IsHidden(sptr)) sptr->umodes &= ~UMODE_SETHOST; if (IsHidden(sptr) && !(setflags & UMODE_HIDE)) { if (sptr->user->virthost) { MyFree(sptr->user->virthost); sptr->user->virthost = NULL; } sptr->user->virthost = strdup(sptr->user->cloakedhost); if (!dontspread) sendto_serv_butone_token_opt(cptr, OPT_VHP, sptr->name, MSG_SETHOST, TOK_SETHOST, "%s", sptr->user->virthost); if (UHOST_ALLOWED == UHALLOW_REJOIN) { DYN_LOCAL(char, did_parts, sptr->user->joined); /* LOL, this is ugly ;) */ sptr->umodes &= ~UMODE_HIDE; rejoin_doparts(sptr, did_parts); sptr->umodes |= UMODE_HIDE; rejoin_dojoinandmode(sptr, did_parts); if (MyClient(sptr)) sptr->since += 7; /* Add fake lag */ DYN_FREE(did_parts); } } if (!IsHidden(sptr) && (setflags & UMODE_HIDE)) { if (UHOST_ALLOWED == UHALLOW_REJOIN) { DYN_LOCAL(char, did_parts, sptr->user->joined); /* LOL, this is ugly ;) */ sptr->umodes |= UMODE_HIDE; rejoin_doparts(sptr, did_parts); sptr->umodes &= ~UMODE_HIDE; rejoin_dojoinandmode(sptr, did_parts); if (MyClient(sptr)) sptr->since += 7; /* Add fake lag */ DYN_FREE(did_parts); } if (sptr->user->virthost) { MyFree(sptr->user->virthost); sptr->user->virthost = NULL; } /* (Re)create the cloaked virthost, because it will be used * for ban-checking... free+recreate here because it could have * been a vhost for example. -- Syzop */ sptr->user->virthost = strdup(sptr->user->cloakedhost); } /* * If I understand what this code is doing correctly... * If the user WAS an operator and has now set themselves -o/-O * then remove their access, d'oh! * In order to allow opers to do stuff like go +o, +h, -o and * remain +h, I moved this code below those checks. It should be * O.K. The above code just does normal access flag checks. This * only changes the operflag access level. -Cabal95 */ if ((setflags & (UMODE_OPER | UMODE_LOCOP)) && !IsAnOper(sptr) && MyConnect(sptr)) {#ifndef NO_FDLIST delfrom_fdlist(sptr->slot, &oper_fdlist);#endif sptr->oflag = 0; remove_oper_snomasks(sptr); RunHook2(HOOKTYPE_LOCAL_OPER, sptr, 0); } if ((sptr->umodes & UMODE_BOT) && !(setflags & UMODE_BOT) && MyClient(sptr)) { /* now +B */ do_cmd(sptr, sptr, "BOTMOTD", 1, parv); } if (!(setflags & UMODE_OPER) && IsOper(sptr)) IRCstats.operators++; /* deal with opercounts and stuff */ if ((setflags & UMODE_OPER) && !IsOper(sptr)) { IRCstats.operators--; VERIFY_OPERCOUNT(sptr, "umode1"); } else /* YES this 'else' must be here, otherwise we can decrease twice. fixes opercount bug. */ if (!(setflags & UMODE_HIDEOPER) && IsHideOper(sptr)) { if (IsOper(sptr)) /* decrease, but only if GLOBAL oper */ IRCstats.operators--; VERIFY_OPERCOUNT(sptr, "umode2"); } /* end of dealing with opercounts */ if ((setflags & UMODE_HIDEOPER) && !IsHideOper(sptr)) { if (IsOper(sptr)) /* increase, but only if GLOBAL oper */ IRCstats.operators++; } if (!(setflags & UMODE_INVISIBLE) && IsInvisible(sptr)) IRCstats.invisible++; if ((setflags & UMODE_INVISIBLE) && !IsInvisible(sptr)) IRCstats.invisible--; /* *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -