#define MODE_NOAMSGS 0x80000 /* +M */
#define MODE_ALTCHAN 0x100000 /* +F */
#define MODE_ACCESS 0x200000 /* +a */
+#define MODE_NOFLOOD 0x400000 /* +f */
+#define MODE_AUDITORIUM 0x800000 /* +u */
#define MODE_REMOVE 0x80000000
#define FLAGS_OPER 0x0001 /* +o global operator */
#define IsFakeIdent(x) ((x)->fakeident[0] != '\0')
#define IsLocal(x) ((x)->uplink == self)
+#define NOFLOODLEN 15
#define NICKLEN 30
#define USERLEN 10
#define HOSTLEN 63
unsigned int locks;
char key[KEYLEN + 1];
char altchan[CHANNELLEN + 1];
+ char noflood[NOFLOODLEN + 1];
char upass[KEYLEN + 1];
char apass[KEYLEN + 1];
unsigned long timestamp; /* creation time */
static MODCMD_FUNC(cmd_mode)
{
- if (!modcmd_chanmode(argv+1, argc-1, MCP_ALLOW_OVB|MCP_KEY_FREE|MC_ANNOUNCE)) {
+ if (!modcmd_chanmode(argv+1, argc-1, MCP_ALLOW_OVB|MCP_KEY_FREE|MC_ANNOUNCE|MCP_OPERMODE)) {
reply("MSG_INVALID_MODES", unsplit_string(argv+1, argc-1, NULL));
return 0;
}
res->new_limit = orig->new_limit;
res->new_access = orig->new_access;
memcpy(res->new_altchan, orig->new_altchan, sizeof(res->new_altchan));
+ memcpy(res->new_noflood, orig->new_noflood, sizeof(res->new_noflood));
memcpy(res->new_key, orig->new_key, sizeof(res->new_key));
memcpy(res->new_upass, orig->new_upass, sizeof(res->new_upass));
memcpy(res->new_apass, orig->new_apass, sizeof(res->new_apass));
strcpy(channel->key, change->new_key);
if (change->modes_set & MODE_ALTCHAN)
strcpy(channel->altchan, change->new_altchan);
+ if (change->modes_set & MODE_NOFLOOD)
+ strcpy(channel->noflood, change->new_noflood);
if (change->modes_set & MODE_UPASS)
strcpy(channel->upass, change->new_upass);
if (change->modes_set & MODE_APASS)
change.new_limit = chan->limit;
change.new_access = chan->access;
safestrncpy(change.new_altchan, chan->altchan, sizeof(change.new_altchan));
+ safestrncpy(change.new_noflood, chan->noflood, sizeof(change.new_noflood));
safestrncpy(change.new_key, chan->key, sizeof(change.new_key));
safestrncpy(change.new_upass, chan->upass, sizeof(change.new_upass));
safestrncpy(change.new_apass, chan->apass, sizeof(change.new_apass));
}
}
break;
+ case 'f':
+ if (add) {
+ if (in_arg >= argc)
+ goto error;
+ mode = modes[in_arg++];
+ if(mode[0] == '!' && !(flags & MCP_OPERMODE)) { //noflood flag also for overriders
+ //only allow opers
+ goto error;
+ }
+ if(mode[0] == '+' || mode[0] == '@') {
+ mode++;
+ }
+ char *p;
+ int count = 0, time = 0;
+ for(p = mode; p[0]; p++) {
+ if(p[0] == ':') {
+ char tmpchar = p[0];
+ p[0] = '\0';
+ count = strtoul(mode,0,10);
+ p[0] = tmpchar;
+ p++;
+ time = strtoul(p,0,10);
+ break;
+ }
+ }
+ if(count <= 0 || time <= 0 || count > 100 || time > 600)
+ goto error;
+ change->modes_set |= MODE_NOFLOOD;
+ safestrncpy(change->new_noflood, modes[in_arg - 1], sizeof(change->new_noflood));
+ } else {
+ change->modes_clear |= MODE_NOFLOOD;
+ }
case 'F':
if (add) {
if (in_arg >= argc)
DO_MODE_CHAR(LIMIT, 'l');
DO_MODE_CHAR(ACCESS, 'a');
DO_MODE_CHAR(ALTCHAN, 'F');
+ DO_MODE_CHAR(NOFLOOD, 'f');
DO_MODE_CHAR(DELAYJOINS, 'D');
DO_MODE_CHAR(REGONLY, 'r');
DO_MODE_CHAR(NOCOLORS, 'c');
}
if (change->modes_set & MODE_ALTCHAN)
mod_chanmode_append(&chbuf, 'F', change->new_altchan);
+ if (change->modes_set & MODE_NOFLOOD)
+ mod_chanmode_append(&chbuf, 'f', change->new_noflood);
}
for (arg = 0; arg < change->argc; ++arg) {
if (change->args[arg].mode & MODE_REMOVE)
DO_MODE_CHAR(LIMIT, 'l');
DO_MODE_CHAR(ACCESS, 'a');
DO_MODE_CHAR(ALTCHAN, 'F');
+ DO_MODE_CHAR(NOFLOOD, 'f');
DO_MODE_CHAR(KEY, 'k');
DO_MODE_CHAR(UPASS, 'U');
DO_MODE_CHAR(APASS, 'A');
DO_MODE_CHAR(KEY, 'k'), args_used += sprintf(args + args_used, " %s", change->new_key);
DO_MODE_CHAR(KEY, 'a'), args_used += sprintf(args + args_used, " %d", change->new_access);
DO_MODE_CHAR(KEY, 'F'), args_used += sprintf(args + args_used, " %s", change->new_altchan);
+ DO_MODE_CHAR(KEY, 'f'), args_used += sprintf(args + args_used, " %s", change->new_noflood);
DO_MODE_CHAR(UPASS, 'U'), args_used += sprintf(args + args_used, " %s", change->new_upass);
DO_MODE_CHAR(APASS, 'A'), args_used += sprintf(args + args_used, " %s", change->new_apass);
#undef DO_MODE_CHAR
cleared |= MODE_ALTCHAN;
channel->altchan[0] = '\0';
break;
+ case 'f':
+ cleared |= MODE_NOFLOOD;
+ channel->noflood[0] = '\0';
+ break;
case 'k':
cleared |= MODE_KEY;
channel->key[0] = '\0';
/* Channel mode manipulation */
#define KEYLEN 23
+#define NOFLOODLEN 15
#define CHANNELLEN 200
typedef unsigned long chan_mode_t;
/* Rules for struct mod_chanmode:
#endif
char new_key[KEYLEN + 1];
char new_altchan[CHANNELLEN + 1];
+ char new_noflood[NOFLOODLEN + 1];
char new_upass[KEYLEN + 1];
char new_apass[KEYLEN + 1];
struct {
#define MCP_IGN_REGISTERED 0x0080 /* chan is already registered; ignore changes to MODE_REGISTERED */
#define MC_ANNOUNCE 0x0100 /* send a mod_chanmode() change out */
#define MC_NOTIFY 0x0200 /* make local callbacks to announce */
+#define MCP_OPERMODE 0x0400
#ifdef NDEBUG
#define mod_chanmode_init(CHANMODE) do { memset((CHANMODE), 0, sizeof(*CHANMODE)); } while (0)
#else