+2004-05-15 Michael Poole <mdpoole@troilus.org>
+
+ * ircd/channel.c (can_join): Revert to using IsInvited() rather
+ than walking the list directly.
+ (modebuf_flush_int): Fix errant HEAD_IN_SAND_SNOTICES check to
+ use feature_bool(FEAT_HIS_SNOTICES) instead.
+
+2004-05-15 Kevin L Mitchell <klmitch@mit.edu>
+
+ [Original ChangeLog date: 2004-01-31 -MDP]
+
+ * ircd/channel.c (mode_parse_key): don't allow , in keys!
+
+2003-04-12 David Mansell (splidge) <splidge@sf.net>
+
+ [Original ChangeLog date: 2003-04-14 -MDP]
+
+ * ircd/channel.c: When keys and limits conflict on burst, the key
+ which is first alphabetically or the limit which is lower will be
+ used by both servers. This matches pre-2.10.11 behaviour.
+ Closes: (#713930)
+
+2004-05-15 David Mansell <splidge@quakenet.org>
+
+ [Original ChangeLog date: 2002-12-28 -MDP]
+
+ * ircd/channel.c (mode_parse_limit): don't allow -l when no limit is
+ set, don't allow -l with negative parameter (or unsigned >2^31).
+
2004-05-15 David Mansell <splidge@quakenet.org>
[Original ChangeLog date: 2002-12-31 -MDP]
(MODE_PRIVATE | MODE_SECRET)) == 0)
#define is_listed(x) ((x)->mode.mode & MODE_LISTED)
+#define IsGlobalChannel(name) (*(name) == '#')
#define IsLocalChannel(name) (*(name) == '&')
-#define IsChannelName(name) (*(name) == '#' || \
- IsLocalChannel(name))
+#define IsChannelName(name) (IsGlobalChannel(name) || IsLocalChannel(name))
typedef enum ChannelGetType {
CGT_NO_CREATE,
#define MODE_ADD 0x40000000
#define MODE_DEL 0x20000000
+/* used in ListingArgs.flags */
+
+#define LISTARG_TOPICLIMITS 0x0001
+#define LISTARG_SHOWSECRET 0x0002
+
/*
* Maximum acceptable lag time in seconds: A channel younger than
* this is not protected against hacking admins.
time_t min_time;
unsigned int max_users;
unsigned int min_users;
- unsigned int topic_limits;
+ unsigned int flags;
time_t max_topic_time;
time_t min_topic_time;
struct Channel *chptr;
int can_join(struct Client *sptr, struct Channel *chptr, char *key)
{
- struct SLink *lp;
int overrideJoin = 0;
/*
* Now a user CAN escape anything if invited -- Isomer
*/
- for (lp = (cli_user(sptr))->invited; lp; lp = lp->next)
- if (lp->value.chptr == chptr)
- return 0;
+ if (IsInvited(sptr, chptr))
+ return 0;
/* An oper can force a join on a local channel using "OVERRIDE" as the key.
a HACK(4) notice will be sent if he would not have been supposed
{
for (; chptr; chptr = chptr->next)
{
- if (!cli_user(cptr) || (!(HasPriv(cptr, PRIV_LIST_CHAN) && IsAnOper(cptr)) &&
+ if (!cli_user(cptr))
+ continue;
+ if (!(HasPriv(cptr, PRIV_LIST_CHAN) && IsAnOper(cptr)) &&
SecretChannel(chptr) && !find_channel_member(cptr, chptr)))
continue;
if (chptr->users > args->min_users && chptr->users < args->max_users &&
chptr->creationtime > args->min_time &&
chptr->creationtime < args->max_time &&
- (!args->topic_limits || (*chptr->topic &&
+ (!(args->flags & LISTARG_TOPICLIMITS) || (*chptr->topic &&
chptr->topic_time > args->min_topic_time &&
chptr->topic_time < args->max_topic_time)))
{
- if (ShowChannel(cptr,chptr))
+ if ((args->flags & LISTARG_SHOWSECRET) || ShowChannel(cptr,chptr))
send_reply(cptr, RPL_LIST, chptr->chname, chptr->users,
chptr->topic);
chptr = chptr->next;
if (mbuf->mb_dest & MODEBUF_DEST_HACK4)
sendto_opmask_butone(0, SNO_HACK4, "HACK(4): %s MODE %s %s%s%s%s%s%s "
"[%Tu]",
-#ifdef HEAD_IN_SAND_SNOTICES
- cli_name(mbuf->mb_source),
-#else
- cli_name(app_source),
-#endif
+ cli_name(feature_bool(FEAT_HIS_SNOTICES) ?
+ mbuf->mb_source : app_source),
mbuf->mb_channel->chname,
rembuf_i ? "-" : "", rembuf, addbuf_i ? "+" : "",
addbuf, remstr, addstr,
state->parc--;
state->max_args--;
+ if ((int)t_limit<0) /* don't permit a negative limit */
+ return;
+
if (!(state->flags & MODE_PARSE_WIPEOUT) &&
(!t_limit || t_limit == state->chptr->mode.limit))
return;
return;
}
+ /* Can't remove a limit that's not there */
+ if (state->dir == MODE_DEL && !state->chptr->mode.limit)
+ return;
+
+ /* Skip if this is a burst and a lower limit than this is set already */
+ if ((state->flags & MODE_PARSE_BURST) &&
+ (state->chptr->mode.mode & flag_p[0]) &&
+ (state->chptr->mode.limit < t_limit))
+ return;
+
if (state->done & DONE_LIMIT) /* allow limit to be set only once */
return;
state->done |= DONE_LIMIT;
/* clean up the key string */
s = t_str;
- while (*++s > ' ' && *s != ':' && --t_len)
- ;
+ while (*s > ' ' && *s != ':' && *s != ',' && t_len--)
+ s++;
*s = '\0';
if (!*t_str) { /* warn if empty */
if (!state->mbuf)
return;
+ /* Skip if this is a burst, we have a key already and the new key is
+ * after the old one alphabetically */
+ if ((state->flags & MODE_PARSE_BURST) &&
+ *(state->chptr->mode.key) &&
+ ircd_strcmp(state->chptr->mode.key, t_str) <= 0)
+ return;
+
/* can't add a key if one is set, nor can one remove the wrong key */
if (!(state->flags & MODE_PARSE_FORCE))
if ((state->dir == MODE_ADD && *state->chptr->mode.key) ||
if (MyUser(state->sptr)) {
/* don't allow local opers to be deopped on local channels */
- if (MyUser(state->sptr) &&
- state->cli_change[i].client != state->sptr &&
+ if (state->cli_change[i].client != state->sptr &&
IsLocalChannel(state->chptr->chname) &&
HasPriv(state->cli_change[i].client, PRIV_DEOP_LCHAN)) {
send_reply(state->sptr, ERR_ISOPERLCHAN,
send_reply(sptr, RPL_LISTUSAGE,
" \002T>\002\037min_minutes\037 ; Channels with a topic last "
"set more than \037min_minutes\037 ago.");
+ if (IsAnOper(sptr))
+ send_reply(sptr, RPL_LISTUSAGE,
+ " \002S\002 ; Show secret channels.");
send_reply(sptr, RPL_LISTUSAGE,
"Example: LIST <3,>1,C<10,T>0 ; 2 users, younger than 10 "
"min., topic set.");
case 'T':
case 't':
is_time++;
- args->topic_limits = 1;
+ args->flags |= LISTARG_TOPICLIMITS;
/*FALLTHROUGH*/
case 'C':
}
break;
+ case 'S':
+ case 's':
+ if (!IsAnOper(sptr))
+ return show_usage(sptr);
+
+ args->flags |= LISTARG_SHOWSECRET;
+ param++;
+
+ if (*param != ',' && *param != ' ' && *param !+ '\0') /* check syntax */
+ return show_usage(sptr);
+ break;
+
default: /* channel name? */
if (!permit_chan || !IsChannelName(param))
return show_usage(sptr);