📄 m_mode.c
字号:
ChanFloodProt newf; memset(&newf, 0, sizeof(newf)); if (!param || *pcount >= MAXMODEPARAMS) { retval = 0; break; } /* old +f was like +f 10:5 or +f *10:5 * new is +f [5c,30j,10t#b]:15 * +f 10:5 --> +f [10t]:5 * +f *10:5 --> +f [10t#b]:5 */ if (param[0] != '[') { /* <<OLD +f>> */ /* like 1:1 and if its less than 3 chars then ahem.. */ if (strlen(param) < 3) { break; } /* may not contain other chars than 0123456789: & NULL */ hascolon = 0; for (xp = param; *xp; xp++) { if (*xp == ':') hascolon++; /* fast alpha check */ if (((*xp < '0') || (*xp > '9')) && (*xp != ':') && (*xp != '*')) goto break_flood; /* uh oh, not the first char */ if (*xp == '*' && (xp != param)) goto break_flood; } /* We can avoid 2 strchr() and a strrchr() like this * it should be much faster. -- codemastr */ if (hascolon != 1) break; if (*param == '*') { xzi = 1; // chptr->mode.kmode = 1; } else { xzi = 0; // chptr->mode.kmode = 0; } xp = index(param, ':'); *xp = '\0'; xxi = atoi((*param == '*' ? (param + 1) : param)); xp++; xyi = atoi(xp); if (xxi > 500 || xyi > 500) break; xp--; *xp = ':'; if ((xxi == 0) || (xyi == 0)) break; /* ok, we passed */ newf.l[FLD_TEXT] = xxi; newf.per = xyi; if (xzi == 1) newf.a[FLD_TEXT] = 'b'; } else { /* NEW +F */ char xbuf[256], c, a, *p, *p2, *x = xbuf+1; int v; unsigned short warnings = 0, breakit; unsigned char r; /* '['<number><1 letter>[optional: '#'+1 letter],[next..]']'':'<number> */ strlcpy(xbuf, param, sizeof(xbuf)); p2 = strchr(xbuf+1, ']'); if (!p2) break; *p2 = '\0'; if (*(p2+1) != ':') break; breakit = 0; for (x = strtok(xbuf+1, ","); x; x = strtok(NULL, ",")) { /* <number><1 letter>[optional: '#'+1 letter] */ p = x; while(isdigit(*p)) { p++; } if ((*p == '\0') || !((*p == 'c') || (*p == 'j') || (*p == 'k') || (*p == 'm') || (*p == 'n') || (*p == 't'))) { if (MyClient(cptr) && *p && (warnings++ < 3)) sendto_one(cptr, ":%s NOTICE %s :warning: channelmode +f: floodtype '%c' unknown, ignored.", me.name, cptr->name, *p); continue; /* continue instead of break for forward compatability. */ } c = *p; *p = '\0'; v = atoi(x); if ((v < 1) || (v > 999)) /* out of range... */ { if (MyClient(cptr)) { sendto_one(cptr, err_str(ERR_CANNOTCHANGECHANMODE), me.name, cptr->name, 'f', "value should be from 1-999"); breakit = 1; break; } else continue; /* just ignore for remote servers */ } p++; a = '\0'; r = MyClient(cptr) ? MODEF_DEFAULT_UNSETTIME : 0; if (*p != '\0') { if (*p == '#') { p++; a = *p; p++; if (*p != '\0') { int tv; tv = atoi(p); if (tv <= 0) tv = 0; /* (ignored) */ if (tv > (MyClient(cptr) ? MODEF_MAX_UNSETTIME : 255)) tv = (MyClient(cptr) ? MODEF_MAX_UNSETTIME : 255); /* set to max */ r = (unsigned char)tv; } } } switch(c) { case 'c': newf.l[FLD_CTCP] = v; if ((a == 'm') || (a == 'M')) newf.a[FLD_CTCP] = a; else newf.a[FLD_CTCP] = 'C'; newf.r[FLD_CTCP] = r; break; case 'j': newf.l[FLD_JOIN] = v; if (a == 'R') newf.a[FLD_JOIN] = a; else newf.a[FLD_JOIN] = 'i'; newf.r[FLD_JOIN] = r; break; case 'k': newf.l[FLD_KNOCK] = v; newf.a[FLD_KNOCK] = 'K'; newf.r[FLD_KNOCK] = r; break; case 'm': newf.l[FLD_MSG] = v; if (a == 'M') newf.a[FLD_MSG] = a; else newf.a[FLD_MSG] = 'm'; newf.r[FLD_MSG] = r; break; case 'n': newf.l[FLD_NICK] = v; newf.a[FLD_NICK] = 'N'; newf.r[FLD_NICK] = r; break; case 't': newf.l[FLD_TEXT] = v; if (a == 'b') newf.a[FLD_TEXT] = a; /** newf.r[FLD_TEXT] ** not supported */ break; default: breakit=1; break; } if (breakit) break; } /* for */ if (breakit) break; /* parse 'per' */ p2++; if (*p2 != ':') break; p2++; if (!*p2) break; v = atoi(p2); if ((v < 1) || (v > 999)) /* 'per' out of range */ { if (MyClient(cptr)) sendto_one(cptr, err_str(ERR_CANNOTCHANGECHANMODE), me.name, cptr->name, 'f', "time range should be 1-999"); break; } newf.per = v; /* Is anything turned on? (to stop things like '+f []:15' */ breakit = 1; for (v=0; v < NUMFLD; v++) if (newf.l[v]) breakit=0; if (breakit) break; } /* if param[0] == '[' */ if (chptr->mode.floodprot && !memcmp(chptr->mode.floodprot, &newf, sizeof(ChanFloodProt))) break; /* They are identical */ /* Good.. store the mode (and alloc if needed) */ if (!chptr->mode.floodprot) chptr->mode.floodprot = MyMalloc(sizeof(ChanFloodProt)); memcpy(chptr->mode.floodprot, &newf, sizeof(ChanFloodProt)); strcpy(tmpbuf, channel_modef_string(chptr->mode.floodprot)); tmpstr = tmpbuf; } else { /* bounce... */ tmpstr = param; } retval = 1; } else { /* MODE_DEL */ if (!chptr->mode.floodprot) break; /* no change */ if (!bounce) { strcpy(tmpbuf, channel_modef_string(chptr->mode.floodprot)); tmpstr = tmpbuf; free(chptr->mode.floodprot); chptr->mode.floodprot = NULL; chanfloodtimer_stopchantimers(chptr); } else { /* bounce.. */ tmpstr = param; } retval = 1; }#endif (void)ircsprintf(pvar[*pcount], "%cf%s", what == MODE_ADD ? '+' : '-', tmpstr); (*pcount)++; break_flood: break; } return retval;}#ifdef EXTCMODE/** Check access and if granted, set the extended chanmode to the requested value in memory. * note: if bounce is requested then the mode will not be set. * @returns amount of params eaten (0 or 1) */int do_extmode_char(aChannel *chptr, int modeindex, char *param, u_int what, aClient *cptr, u_int *pcount, char pvar[MAXMODEPARAMS][MODEBUFLEN + 3], char bounce){int paracnt = (what == MODE_ADD) ? Channelmode_Table[modeindex].paracount : 0;int x; /* Expected a param and it isn't there? */ if (paracnt && (!param || (*pcount >= MAXMODEPARAMS))) return 0; if (MyClient(cptr)) { x = Channelmode_Table[modeindex].is_ok(cptr, chptr, param, EXCHK_ACCESS, what); if ((x == EX_ALWAYS_DENY) || ((x == EX_DENY) && !op_can_override(cptr) && !samode_in_progress)) { Channelmode_Table[modeindex].is_ok(cptr, chptr, param, EXCHK_ACCESS_ERR, what); return paracnt; /* Denied & error msg sent */ } if (x == EX_DENY) opermode = 1; /* override in progress... */ } else { /* remote user: we only need to check if we need to generate an operoverride msg */ if (!IsULine(cptr) && IsPerson(cptr) && op_can_override(cptr) && (Channelmode_Table[modeindex].is_ok(cptr, chptr, param, EXCHK_ACCESS, what) != EX_ALLOW)) opermode = 1; /* override in progress... */ } /* Check for multiple changes in 1 command (like +y-y+y 1 2, or +yy 1 2). */ for (x = 0; x < *pcount; x++) { if (pvar[x][1] == Channelmode_Table[modeindex].flag) { /* this is different than the old chanmode system, coz: * "mode #chan +kkL #a #b #c" will get "+kL #a #b" which is wrong :p. * we do eat the parameter. -- Syzop */ return paracnt; } } /* w00t... a parameter mode */ if (Channelmode_Table[modeindex].paracount) { if (what == MODE_DEL) { if (!(chptr->mode.extmode & Channelmode_Table[modeindex].mode)) return paracnt; /* There's nothing to remove! */ /* del means any parameter is ok, the one-who-is-set will be used */ ircsprintf(pvar[*pcount], "-%c", Channelmode_Table[modeindex].flag); } else { /* add: is the parameter ok? */ if (Channelmode_Table[modeindex].is_ok(cptr, chptr, param, EXCHK_PARAM, what) == FALSE) return paracnt; /* is it already set at the same value? if so, ignore it. */ if (chptr->mode.extmode & Channelmode_Table[modeindex].mode) { char *p, *p2; p = Channelmode_Table[modeindex].get_param(extcmode_get_struct(chptr->mode.extmodeparam,Channelmode_Table[modeindex].flag)); p2 = Channelmode_Table[modeindex].conv_param(param); if (p && p2 && !strcmp(p, p2)) return paracnt; /* ignore... */ } ircsprintf(pvar[*pcount], "+%c%s", Channelmode_Table[modeindex].flag, Channelmode_Table[modeindex].conv_param(param)); (*pcount)++; } } if (bounce) /* bounce here means: only check access and return return value */ return paracnt; if (what == MODE_ADD) { /* + */ chptr->mode.extmode |= Channelmode_Table[modeindex].mode; if (Channelmode_Table[modeindex].paracount) { CmodeParam *p = extcmode_get_struct(chptr->mode.extmodeparam, Channelmode_Table[modeindex].flag); CmodeParam *r; r = Channelmode_Table[modeindex].put_param(p, param); if (r != p) AddListItem(r, chptr->mode.extmodeparam); } } else { /* - */ chptr->mode.extmode &= ~(Channelmode_Table[modeindex].mode); if (Channelmode_Table[modeindex].paracount) { CmodeParam *p = extcmode_get_struct(chptr->mode.extmodeparam, Channelmode_Table[modeindex].flag); if (p) { DelListItem(p, chptr->mode.extmodeparam); Channelmode_Table[modeindex].free_param(p); } } } return paracnt;}#endif /* EXTCMODE *//* * ListBits(bitvalue, bitlength); * written by Stskeeps*/#ifdef DEVELOPchar *ListBits(long bits, long length){ char *bitstr, *p; long l, y; y = 1; bitstr = (char *)MyMalloc(length + 1); p = bitstr; for (l = 1; l <= length; l++) { if (bits & y) *p = '1'; else *p = '0'; p++; y = y + y; } *p = '\0'; return (bitstr);}#endif/* set_mode * written by binary */DLLFUNC void _set_mode(aChannel *chptr, aClient *cptr, int parc, char *parv[], u_int *pcount, char pvar[MAXMODEPARAMS][MODEBUFLEN + 3], int bounce){ char *curchr; u_int what = MODE_ADD; long modetype = 0; int paracount = 1;#ifdef DEVELOP char *tmpo = NULL;#endif aCtab *tab = &cFlagTab[0]; aCtab foundat; int found = 0; unsigned int htrig = 0; long oldm, oldl; int checkrestr = 0, warnrestr = 1;#ifdef EXTCMODE int extm = 1000000; /* (default value not used but stops gcc from complaining) */ Cmode_t oldem;#endif long my_access; paracount = 1; *pcount = 0; oldm = chptr->mode.mode; oldl = chptr->mode.limit;#ifdef EXTCMODE oldem = chptr->mode.extmode;#endif if (RESTRICT_CHANNELMODES && MyClient(cptr) && !IsAnOper(cptr) && !IsServer(cptr)) /* "cache" this */ checkrestr = 1; /* Set access to the status we have */ my_access = IsPerson(cptr) ? get_access(cptr, chptr) : 0; for (curchr = parv[0]; *curchr; curchr++) { switch (*curchr) { case '+': what = MODE_ADD; break; case '-': what = MODE_DEL; break;#ifdef DEVELOP case '^': tmpo = (char *)ListBits(chptr->mode.mode, 64); sendto_one(cptr, ":%s NOTICE %s :*** %s mode is %li (0x%lx) [%s]", me.name, cptr->name, chptr->chname, chptr->mode.mode, chptr->mode.mode, tmpo); MyFree(tmpo); break;#endif default: found = 0; tab = &cFlagTab[0]; while ((tab->mode != 0x0) && found == 0) { if (tab->flag == *curchr) { found = 1; foundat = *tab; } tab++; } if (found == 1) { modetype = foundat.mode; } else {#ifdef EXTCMODE /* Maybe in extmodes */ for (extm=0; extm <= Channelmode_highest; extm++) { if (Channelmode_Table[extm].flag == *curchr) { found = 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -