*
* $Id$
*/
+#include "config.h"
+
#include "channel.h"
#include "client.h"
#include "hash.h"
#include "ircd_alloc.h"
#include "ircd_chattr.h"
#include "ircd_defs.h"
+#include "ircd_features.h"
#include "ircd_log.h"
+#include "ircd_policy.h"
#include "ircd_reply.h"
#include "ircd_snprintf.h"
#include "ircd_string.h"
#include "s_misc.h"
#include "s_user.h"
#include "send.h"
-#include "sprintf_irc.h"
#include "struct.h"
#include "support.h"
#include "sys.h"
if (who)
return who;
- if (!(who = get_history(user, KILLCHASETIMELIMIT))) {
+ if (!(who = get_history(user, feature_int(FEAT_KILLCHASETIMELIMIT)))) {
send_reply(sptr, ERR_NOSUCHNICK, user);
return 0;
}
const char *host)
{
static char namebuf[NICKLEN + USERLEN + HOSTLEN + 3];
- sprintf_irc(namebuf, "%s!%s@%s", nick, name, host);
+ ircd_snprintf(0, namebuf, sizeof(namebuf), "%s!%s@%s", nick, name, host);
return namebuf;
}
static char *make_nick_user_ip(char *nick, char *name, struct in_addr ip)
{
static char ipbuf[NICKLEN + USERLEN + 16 + 3];
- sprintf_irc(ipbuf, "%s!%s@%s", nick, name, ircd_ntoa((const char*) &ip));
+ ircd_snprintf(0, ipbuf, sizeof(ipbuf), "%s!%s@%s", nick, name,
+ ircd_ntoa((const char*) &ip));
return ipbuf;
}
len -= strlen(tmp->value.ban.banstr);
}
*banp = tmp->next;
-#if 0
- /* Silently remove overlapping bans */
- MyFree(tmp->value.ban.banstr);
- MyFree(tmp->value.ban.who);
- free_link(tmp);
- tmp = 0;
-#else
/* These will be sent to the user later as -b */
tmp->next = removed_bans_list;
removed_bans_list = tmp;
removed_bans = 1;
-#endif
}
else if (!(tmp->flags & CHFL_BURST_BAN_WIPEOUT))
{
banp = &(*banp)->next;
}
}
- if (MyUser(cptr) && !removed_bans && (len > MAXBANLENGTH || (cnt >= MAXBANS)))
+ if (MyUser(cptr) && !removed_bans &&
+ (len > (feature_int(FEAT_AVBANLEN) * feature_int(FEAT_MAXBANS)) ||
+ (cnt >= feature_int(FEAT_MAXBANS))))
{
send_reply(cptr, ERR_BANLISTFULL, chptr->chname, banid);
return -1;
assert(0 != ban->value.ban.banstr);
strcpy(ban->value.ban.banstr, banid);
- ban->value.ban.who = (char*) MyMalloc(strlen(cli_name(cptr)) + 1);
+#ifdef HEAD_IN_SAND_BANWHO
+ if (IsServer(cptr))
+ DupString(ban->value.ban.who, cli_name(&me));
+ else
+#endif
+ DupString(ban->value.ban.who, cli_name(cptr));
assert(0 != ban->value.ban.who);
- strcpy(ban->value.ban.who, cli_name(cptr));
ban->value.ban.when = TStime();
ban->flags = CHFL_BAN; /* This bit is never used I think... */
{
struct Membership* chan;
assert(0 != cptr);
- assert(0 != cptr->user);
+ assert(0 != cli_user(cptr));
while ((chan = (cli_user(cptr))->channel))
remove_user_from_channel(cptr, chan->channel);
/*
* You can't speak if your off channel, if the channel is modeless, or
- * +n.(no external messages)
+ * +n (no external messages) or +m (moderated).
*/
if (!member) {
- if ((chptr->mode.mode & MODE_NOPRIVMSGS) || IsModelessChannel(chptr->chname))
+ if ((chptr->mode.mode & (MODE_NOPRIVMSGS|MODE_MODERATED))
+ || IsModelessChannel(chptr->chname))
return 0;
else
return 1;
*mbuf++ = 'n';
if (chptr->mode.limit) {
*mbuf++ = 'l';
- sprintf_irc(pbuf, "%d", chptr->mode.limit);
+ ircd_snprintf(0, pbuf, sizeof(pbuf), "%d", chptr->mode.limit);
}
if (*chptr->mode.key) {
*mbuf++ = 'k';
+ if (chptr->mode.limit)
+ strcat(pbuf, " ");
if (is_chan_op(cptr, chptr) || IsServer(cptr)) {
- if (chptr->mode.limit)
- strcat(pbuf, " ");
strcat(pbuf, chptr->mode.key);
- }
+ } else
+ strcat(pbuf, "*");
}
*mbuf = '\0';
}
if (lp->value.chptr == chptr)
return 0;
-#ifdef OPER_WALK_THROUGH_LMODES
/* 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
to join normally. */
- if (IsOperOnLocalChannel(sptr,chptr->chname) && !BadPtr(key) && compall("OVERRIDE",key) == 0)
- {
+ if (IsLocalChannel(chptr->chname) && HasPriv(sptr, PRIV_WALK_LCHAN) &&
+ !BadPtr(key) && compall("OVERRIDE",key) == 0)
overrideJoin = MAGIC_OPER_OVERRIDE;
- }
-#endif
if (chptr->mode.mode & MODE_INVITEONLY)
return overrideJoin + ERR_INVITEONLYCHAN;
* Delete last link in chain if the list is max length
*/
assert(list_length((cli_user(cptr))->invited) == (cli_user(cptr))->invites);
- if ((cli_user(cptr))->invites>=MAXCHANNELSPERUSER)
+ if ((cli_user(cptr))->invites >= feature_int(FEAT_MAXCHANNELSPERUSER))
del_invite(cptr, (cli_user(cptr))->invited->value.chptr);
/*
* Add client to channel invite list
(cli_listing(cptr))->chptr = chptr;
chptr->mode.mode |= MODE_LISTED;
}
+
+ update_write(cptr);
}
/*
/* Ok, if we were given the OPMODE flag, hide the source if its a user */
if (mbuf->mb_dest & MODEBUF_DEST_OPMODE && !IsServer(mbuf->mb_source))
- app_source = (cli_user(mbuf->mb_source))->server;
+ app_source = &me;
else
app_source = mbuf->mb_source;
}
} else if (MB_TYPE(mbuf, i) & MODE_LIMIT) {
/* if it's a limit, we also format the number */
- sprintf_irc(limitbuf, "%d", MB_UINT(mbuf, i));
+ ircd_snprintf(0, limitbuf, sizeof(limitbuf), "%d", MB_UINT(mbuf, i));
tmp = strlen(limitbuf);
/* send the messages off to their destination */
if (mbuf->mb_dest & MODEBUF_DEST_HACK2) {
sendto_opmask_butone(0, SNO_HACK2, "HACK(2): %s MODE %s %s%s%s%s%s%s "
- "[%Tu]", cli_name(app_source),
+ "[%Tu]",
+#ifdef HEAD_IN_SAND_SNOTICES
+ cli_name(mbuf->mb_source),
+#else
+ cli_name(app_source),
+#endif
mbuf->mb_channel->chname,
rembuf_i ? "-" : "", rembuf, addbuf_i ? "+" : "",
addbuf, remstr, addstr,
mbuf->mb_channel->creationtime);
sendcmdto_serv_butone(&me, CMD_DESYNCH, mbuf->mb_connect,
":HACK: %s MODE %s %s%s%s%s%s%s [%Tu]",
- cli_name(app_source), mbuf->mb_channel->chname,
+#ifdef HEAD_IN_SAND_SNOTICES
+ cli_name(mbuf->mb_source),
+#else
+ cli_name(app_source),
+#endif
+ mbuf->mb_channel->chname,
rembuf_i ? "-" : "", rembuf,
addbuf_i ? "+" : "", addbuf, remstr, addstr,
mbuf->mb_channel->creationtime);
if (mbuf->mb_dest & MODEBUF_DEST_HACK3)
sendto_opmask_butone(0, SNO_HACK3, "BOUNCE or HACK(3): %s MODE %s "
- "%s%s%s%s%s%s [%Tu]", cli_name(app_source),
+ "%s%s%s%s%s%s [%Tu]",
+#ifdef HEAD_IN_SAND_SNOTICES
+ cli_name(mbuf->mb_source),
+#else
+ cli_name(app_source),
+#endif
mbuf->mb_channel->chname, rembuf_i ? "-" : "",
rembuf, addbuf_i ? "+" : "", addbuf, remstr, addstr,
mbuf->mb_channel->creationtime);
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]", cli_name(app_source),
+ "[%Tu]",
+#ifdef HEAD_IN_SAND_SNOTICES
+ cli_name(mbuf->mb_source),
+#else
+ cli_name(app_source),
+#endif
mbuf->mb_channel->chname,
rembuf_i ? "-" : "", rembuf, addbuf_i ? "+" : "",
addbuf, remstr, addstr,
newban->next = 0;
DupString(newban->value.ban.banstr, t_str);
- newban->value.ban.who = state->sptr->name;
+ newban->value.ban.who = cli_name(state->sptr);
newban->value.ban.when = TStime();
newban->flags = CHFL_BAN | MODE_ADD;
} else if (state->dir == MODE_ADD) {
/* if the ban already exists, don't worry about it */
if (!ircd_strcmp(ban->value.ban.banstr, t_str)) {
+ newban->flags &= ~MODE_ADD; /* don't add ban at all */
+ MyFree(newban->value.ban.banstr); /* stopper a leak */
+ state->numbans--; /* deallocate last ban */
if (state->done & DONE_BANCLEAN) /* If we're cleaning, finish */
break;
- continue;
} else if (!mmatch(ban->value.ban.banstr, t_str)) {
if (!(ban->flags & MODE_DEL))
newban->flags |= CHFL_BAN_OVERLAPPED; /* our ban overlaps */
} else if (!mmatch(t_str, ban->value.ban.banstr))
ban->flags |= MODE_DEL; /* mark ban for deletion: overlapping */
- if (!ban->next) {
+ if (!ban->next && (newban->flags & MODE_ADD)) {
ban->next = newban; /* add our ban with its flags */
break; /* get out of loop */
}
MyFree(ban->value.ban.banstr);
} else {
if (state->flags & MODE_PARSE_SET && MyUser(state->sptr) &&
- (len > MAXBANLENGTH || count >= MAXBANS)) {
+ (len > (feature_int(FEAT_AVBANLEN) * feature_int(FEAT_MAXBANS)) ||
+ count >= feature_int(FEAT_MAXBANS))) {
send_reply(state->sptr, ERR_BANLISTFULL, state->chptr->chname,
ban->value.ban.banstr);
count--;
}
}
-#ifdef NO_OPER_DEOP_LCHAN
/* don't allow local opers to be deopped on local channels */
if (MyUser(state->sptr) && state->cli_change[i].client != state->sptr &&
- IsOperOnLocalChannel(state->cli_change[i].client,
- state->chptr->chname)) {
+ IsLocalChannel(state->chptr->chname) &&
+ HasPriv(state->cli_change[i].client, PRIV_DEOP_LCHAN)) {
send_reply(state->sptr, ERR_ISOPERLCHAN,
cli_name(state->cli_change[i].client),
state->chptr->chname);
continue;
}
-#endif
}
/* accumulate the change */