static void ms_tmode(struct MsgBuf *, struct Client *, struct Client *, int, const char **);
static void ms_mlock(struct MsgBuf *, struct Client *, struct Client *, int, const char **);
static void ms_bmask(struct MsgBuf *, struct Client *, struct Client *, int, const char **);
+static void ms_ebmask(struct MsgBuf *, struct Client *, struct Client *, int, const char **);
struct Message mode_msgtab = {
"MODE", 0, 0, 0, 0,
"BMASK", 0, 0, 0, 0,
{mg_ignore, mg_ignore, mg_ignore, {ms_bmask, 5}, mg_ignore, mg_ignore}
};
+struct Message ebmask_msgtab = {
+ "EBMASK", 0, 0, 0, 0,
+ {mg_ignore, mg_ignore, mg_ignore, {ms_ebmask, 5}, mg_ignore, mg_ignore}
+};
-mapi_clist_av1 mode_clist[] = { &mode_msgtab, &tmode_msgtab, &mlock_msgtab, &bmask_msgtab, NULL };
+mapi_clist_av1 mode_clist[] = { &mode_msgtab, &tmode_msgtab, &mlock_msgtab, &bmask_msgtab, &ebmask_msgtab, NULL };
DECLARE_MODULE_AV2(mode, NULL, NULL, mode_clist, NULL, NULL, NULL, NULL, mode_desc);
operspy ? channel_modes(chptr, &me) : channel_modes(chptr, source_p));
sendto_one(source_p, form_str(RPL_CREATIONTIME),
- me.name, source_p->name, parv[1], chptr->channelts);
+ me.name, source_p->name, parv[1], (long long)chptr->channelts);
}
else
{
msptr = find_channel_membership(chptr, source_p);
- /* Finish the flood grace period... */
- if(MyClient(source_p) && !IsFloodDone(source_p))
- {
- if(!((parc == 3) && (parv[2][0] == 'b' || parv[2][0] == 'q') && (parv[2][1] == '\0')))
- flood_endgrace(source_p);
- }
-
set_channel_mode(client_p, source_p, chptr, msptr, parc - n, parv + n);
}
}
(actualBan->forward == NULL ||
irccmp(actualBan->forward, forward) < 0))
{
- sendto_channel_local(mems, chptr, ":%s MODE %s -%c %s%s%s",
+ sendto_channel_local(fakesource_p, mems, chptr, ":%s MODE %s -%c %s%s%s",
fakesource_p->name,
chptr->chname,
mchar,
}
static void
-ms_bmask(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+do_bmask(bool extended, struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
- static char modebuf[BUFSIZE];
+ static char output[BUFSIZE];
static char parabuf[BUFSIZE];
+ static char degrade[BUFSIZE];
+ static char squitreason[120];
struct Channel *chptr;
+ struct Ban *banptr;
rb_dlink_list *banlist;
- char *s, *forward;
- char *t;
- char *mbuf;
- char *pbuf;
+ char *s, *mask, *forward, *who;
+ char *output_ptr;
+ char *param_ptr;
+ char *degrade_ptr;
long mode_type;
int mlen;
int plen = 0;
int modecount = 0;
int needcap = NOCAPS;
int mems;
+ time_t when = (long)rb_current_time();
struct Client *fakesource_p;
if(!IsChanPrefix(parv[2][0]) || !check_channel_name(parv[2]))
fakesource_p = &me;
else
fakesource_p = source_p;
- mlen = sprintf(modebuf, ":%s MODE %s +", fakesource_p->name, chptr->chname);
- mbuf = modebuf + mlen;
- pbuf = parabuf;
+ who = fakesource_p->name;
+
+ mlen = sprintf(output, ":%s MODE %s +", fakesource_p->name, chptr->chname);
+ output_ptr = output + mlen;
+ param_ptr = parabuf;
+ degrade_ptr = degrade;
while(*s == ' ')
s++;
- /* next char isnt a space, point t to the next one */
- if((t = strchr(s, ' ')) != NULL)
- {
- *t++ = '\0';
-
- /* double spaces will break the parser */
- while(*t == ' ')
- t++;
- }
+ s = strtok(s, " ");
- /* couldve skipped spaces and got nothing.. */
while(!EmptyString(s))
{
- /* ban with a leading ':' -- this will break the protocol */
if(*s == ':')
- goto nextban;
+ {
+ /* ban with a leading ':' -- this will break the protocol */
+ sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
+ "Link %s dropped, invalid BMASK mask (%s)", source_p->name, s);
+ snprintf(squitreason, sizeof squitreason, "Invalid BMASK mask (%s)", s);
+ exit_client(client_p, client_p, client_p, squitreason);
+ return;
+ }
tlen = strlen(s);
parv[3][0], s, forward);
}
- if(add_id(fakesource_p, chptr, s, forward, banlist, mode_type))
+ mask = s;
+ if (extended) {
+ when = atol(strtok(NULL, " "));
+ who = strtok(NULL, " ");
+ if (who == NULL)
+ {
+ /* EBMASK params don't divide by 3, so we have an incomplete chunk */
+ sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
+ "Link %s dropped, invalid EBMASK chunk", source_p->name);
+ snprintf(squitreason, sizeof squitreason, "Invalid EBMASK chunk");
+ exit_client(client_p, client_p, client_p, squitreason);
+ return;
+ }
+
+ arglen = sprintf(degrade_ptr, "%s ", mask);
+ degrade_ptr += arglen;
+ }
+
+ if((banptr = add_id(fakesource_p, chptr, mask, forward, banlist, mode_type)) != NULL)
{
+ banptr->when = when;
+ rb_free(banptr->who);
+ banptr->who = rb_strdup(who);
+
/* this new one wont fit.. */
if(mlen + MAXMODEPARAMS + plen + tlen > BUFSIZE - 5 ||
modecount >= MAXMODEPARAMS)
{
- *mbuf = '\0';
- *(pbuf - 1) = '\0';
- sendto_channel_local(mems, chptr, "%s %s", modebuf, parabuf);
+ *output_ptr = '\0';
+ *(param_ptr - 1) = '\0';
+ sendto_channel_local(fakesource_p, mems, chptr, "%s %s", output, parabuf);
- mbuf = modebuf + mlen;
- pbuf = parabuf;
+ output_ptr = output + mlen;
+ param_ptr = parabuf;
plen = modecount = 0;
}
if (forward != NULL)
forward[-1] = '$';
- *mbuf++ = parv[3][0];
- arglen = sprintf(pbuf, "%s ", s);
- pbuf += arglen;
+ *output_ptr++ = parv[3][0];
+ arglen = sprintf(param_ptr, "%s ", mask);
+ param_ptr += arglen;
plen += arglen;
modecount++;
}
- nextban:
- s = t;
-
- if(s != NULL)
- {
- if((t = strchr(s, ' ')) != NULL)
- {
- *t++ = '\0';
-
- while(*t == ' ')
- t++;
- }
- }
+ s = strtok(NULL, " ");
}
if(modecount)
{
- *mbuf = '\0';
- *(pbuf - 1) = '\0';
- sendto_channel_local(mems, chptr, "%s %s", modebuf, parabuf);
+ *output_ptr = '\0';
+ *(param_ptr - 1) = '\0';
+ sendto_channel_local(fakesource_p, mems, chptr, "%s %s", output, parabuf);
}
- sendto_server(client_p, chptr, CAP_TS6 | needcap, NOCAPS, ":%s BMASK %ld %s %s :%s",
- source_p->id, (long) chptr->channelts, chptr->chname, parv[3], parv[4]);
+ if (extended) {
+ *(degrade_ptr - 1) = '\0';
+ sendto_server(client_p, chptr, CAP_EBMASK | CAP_TS6 | needcap, NOCAPS, ":%s EBMASK %ld %s %s :%s",
+ source_p->id, (long) chptr->channelts, chptr->chname, parv[3], parv[4]);
+ sendto_server(client_p, chptr, CAP_TS6 | needcap, CAP_EBMASK, ":%s BMASK %ld %s %s :%s",
+ source_p->id, (long) chptr->channelts, chptr->chname, parv[3], degrade);
+ }
+ else
+ sendto_server(client_p, chptr, CAP_TS6 | needcap, NOCAPS, ":%s BMASK %ld %s %s :%s",
+ source_p->id, (long) chptr->channelts, chptr->chname, parv[3], parv[4]);
}
+
+static void
+ms_bmask(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ do_bmask(false, msgbuf_p, client_p, source_p, parc, parv);
+}
+static void
+ms_ebmask(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ do_bmask(true, msgbuf_p, client_p, source_p, parc, parv);
+}
+