const char* const PartFmt2serv = "%s%s " TOK_PART " %s :%s";
-static struct SLink* next_ban;
-static struct SLink* prev_ban;
-static struct SLink* removed_bans_list;
+static struct Ban* next_ban;
+static struct Ban* prev_ban;
+static struct Ban* removed_bans_list;
+static struct Ban* free_bans;
/**
* Use a global variable to remember if an oper set a mode on a local channel.
}
#endif
+/** Allocate a new Ban structure.
+ * @param[in] banstr Ban mask to use.
+ * @return Newly allocated ban.
+ */
+struct Ban *
+make_ban(const char *banstr)
+{
+ struct Ban *ban;
+ if (free_bans) {
+ ban = free_bans;
+ free_bans = free_bans->next;
+ }
+ else if (!(ban = MyMalloc(sizeof(*ban))))
+ return NULL;
+ memset(ban, 0, sizeof(*ban));
+ if (banstr)
+ DupString(ban->banstr, banstr);
+ return ban;
+}
+
+/** Deallocate a ban structure.
+ * @param[in] ban Ban to deallocate.
+ */
+void
+free_ban(struct Ban *ban)
+{
+ MyFree(ban->who);
+ MyFree(ban->banstr);
+ ban->next = free_bans;
+ free_bans = ban;
+}
+
/** return the struct Membership* that represents a client on a channel
* This function finds a struct Membership* which holds the state about
* a client on a specific channel. The code is smart enough to iterate
*/
int destruct_channel(struct Channel* chptr)
{
- struct SLink *tmp;
- struct SLink *obtmp;
+ struct Ban *ban, *next;
assert(0 == chptr->members);
/*
* Now, find all invite links from channel structure
*/
- while ((tmp = chptr->invites))
- del_invite(tmp->value.cptr, chptr);
+ while (chptr->invites)
+ del_invite(chptr->invites->value.cptr, chptr);
- tmp = chptr->banlist;
- while (tmp)
+ for (ban = chptr->banlist; ban; ban = next)
{
- obtmp = tmp;
- tmp = tmp->next;
- MyFree(obtmp->value.ban.banstr);
- MyFree(obtmp->value.ban.who);
- free_link(obtmp);
+ next = ban->next;
+ free_ban(ban);
}
if (chptr->prev)
chptr->prev->next = chptr->next;
int add_banid(struct Client *cptr, struct Channel *chptr, char *banid,
int change, int firsttime)
{
- struct SLink* ban;
- struct SLink** banp;
+ struct Ban* ban;
+ struct Ban** banp;
int cnt = 0;
int removed_bans = 0;
int len = strlen(banid);
collapse(banid);
for (banp = &chptr->banlist; *banp;)
{
- len += strlen((*banp)->value.ban.banstr);
+ len += strlen((*banp)->banstr);
++cnt;
if (((*banp)->flags & CHFL_BURST_BAN_WIPEOUT))
{
- if (!strcmp((*banp)->value.ban.banstr, banid))
+ if (!strcmp((*banp)->banstr, banid))
{
(*banp)->flags &= ~CHFL_BURST_BAN_WIPEOUT;
return -2;
}
}
- else if (!mmatch((*banp)->value.ban.banstr, banid))
+ else if (!mmatch((*banp)->banstr, banid))
return -1;
- if (!mmatch(banid, (*banp)->value.ban.banstr))
+ if (!mmatch(banid, (*banp)->banstr))
{
- struct SLink *tmp = *banp;
+ struct Ban *tmp = *banp;
if (change)
{
if (MyUser(cptr))
{
cnt--;
- len -= strlen(tmp->value.ban.banstr);
+ len -= strlen(tmp->banstr);
}
*banp = tmp->next;
/* These will be sent to the user later as -b */
{
char* ip_start;
struct Membership* member;
- ban = make_link();
+ ban = make_ban(banid);
ban->next = chptr->banlist;
- ban->value.ban.banstr = (char*) MyMalloc(strlen(banid) + 1);
- assert(0 != ban->value.ban.banstr);
- strcpy(ban->value.ban.banstr, banid);
-
if (IsServer(cptr) && feature_bool(FEAT_HIS_BANWHO))
- DupString(ban->value.ban.who, cli_name(&me));
+ DupString(ban->who, cli_name(&me));
else
- DupString(ban->value.ban.who, cli_name(cptr));
- assert(0 != ban->value.ban.who);
+ DupString(ban->who, cli_name(cptr));
+ assert(0 != ban->who);
- ban->value.ban.when = TStime();
+ ban->when = TStime();
ban->flags = CHFL_BAN; /* This bit is never used I think... */
if ((ip_start = strrchr(banid, '@')) && check_if_ipmask(ip_start + 1))
ban->flags |= CHFL_BAN_IPMASK;
/** return the next ban that is removed
* @returns the next ban that is removed because of overlapping
*/
-struct SLink *next_removed_overlapped_ban(void)
+struct Ban *next_removed_overlapped_ban(void)
{
- struct SLink *tmp = removed_bans_list;
if (prev_ban)
{
- if (prev_ban->value.ban.banstr) /* Can be set to NULL in set_mode() */
- MyFree(prev_ban->value.ban.banstr);
- MyFree(prev_ban->value.ban.who);
- free_link(prev_ban);
+ free_ban(prev_ban);
prev_ban = 0;
}
- if (tmp)
+ if ((prev_ban = removed_bans_list))
removed_bans_list = removed_bans_list->next;
- prev_ban = tmp;
- return tmp;
+ return prev_ban;
}
/** returns Membership * if a person is joined and not a zombie
static int is_banned(struct Client *cptr, struct Channel *chptr,
struct Membership* member)
{
- struct SLink* tmp;
+ struct Ban* tmp;
char tmphost[HOSTLEN + 1];
char nu_host[NUH_BUFSIZE];
char nu_realhost[NUH_BUFSIZE];
if (!ip_s)
ip_s = make_nick_user_ip(nu_ip, cli_name(cptr),
(cli_user(cptr))->username, &cli_ip(cptr));
- if (match(tmp->value.ban.banstr, ip_s) == 0)
+ if (match(tmp->banstr, ip_s) == 0)
break;
}
- if (match(tmp->value.ban.banstr, s) == 0)
+ if (match(tmp->banstr, s) == 0)
break;
- else if (sr && match(tmp->value.ban.banstr, sr) == 0)
+ else if (sr && match(tmp->banstr, sr) == 0)
break;
}
int new_mode = 0;
size_t len;
struct Membership* member;
- struct SLink* lp2;
+ struct Ban* lp2;
char modebuf[MODEBUFLEN];
char parabuf[MODEBUFLEN];
struct MsgBuf *mb;
/* Attach all bans, space seperated " :%ban ban ..." */
for (first = 2; lp2; lp2 = lp2->next)
{
- len = strlen(lp2->value.ban.banstr);
+ len = strlen(lp2->banstr);
if (msgq_bufleft(mb) < len + 1 + first)
/* The +1 stands for the added ' '.
* The +first stands for the added ":%".
break;
}
msgq_append(&me, mb, " %s%s", first ? ":%" : "",
- lp2->value.ban.banstr);
+ lp2->banstr);
first = 0;
}
}
*/
static void send_ban_list(struct Client* cptr, struct Channel* chptr)
{
- struct SLink* lp;
+ struct Ban* lp;
assert(0 != cptr);
assert(0 != chptr);
for (lp = chptr->banlist; lp; lp = lp->next)
- send_reply(cptr, RPL_BANLIST, chptr->chname, lp->value.ban.banstr,
- lp->value.ban.who, lp->value.ban.when);
+ send_reply(cptr, RPL_BANLIST, chptr->chname, lp->banstr,
+ lp->who, lp->when);
send_reply(cptr, RPL_ENDOFBANLIST, chptr->chname);
}
int args_used;
int max_args;
int numbans;
- struct SLink banlist[MAXPARA];
+ struct Ban banlist[MAXPARA];
struct {
unsigned int flag;
struct Client *client;
mode_parse_ban(struct ParseState *state, int *flag_p)
{
char *t_str, *s;
- struct SLink *ban, *newban = 0;
+ struct Ban *ban, *newban = 0;
if (state->parc <= 0) { /* Not enough args, send ban list */
if (MyUser(state->sptr) && !(state->done & DONE_BANLIST)) {
newban = state->banlist + (state->numbans++);
newban->next = 0;
- DupString(newban->value.ban.banstr, t_str);
- newban->value.ban.who = cli_name(state->sptr);
- newban->value.ban.when = TStime();
+ DupString(newban->banstr, t_str);
+ newban->who = cli_name(state->sptr);
+ newban->when = TStime();
newban->flags = CHFL_BAN | MODE_ADD;
* it when we process added bans
*/
- if (state->dir == MODE_DEL && !ircd_strcmp(ban->value.ban.banstr, t_str)) {
+ if (state->dir == MODE_DEL && !ircd_strcmp(ban->banstr, t_str)) {
ban->flags |= MODE_DEL; /* delete one ban */
if (state->done & DONE_BANCLEAN) /* If we're cleaning, finish */
break;
} 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)) {
+ if (!ircd_strcmp(ban->banstr, t_str)) {
newban->flags &= ~MODE_ADD; /* don't add ban at all */
- MyFree(newban->value.ban.banstr); /* stopper a leak */
+ MyFree(newban->banstr); /* stopper a leak */
state->numbans--; /* deallocate last ban */
if (state->done & DONE_BANCLEAN) /* If we're cleaning, finish */
break;
- } else if (!mmatch(ban->value.ban.banstr, t_str)) {
+ } else if (!mmatch(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))
+ } else if (!mmatch(t_str, ban->banstr))
ban->flags |= MODE_DEL; /* mark ban for deletion: overlapping */
if (!ban->next && (newban->flags & MODE_ADD))
static void
mode_process_bans(struct ParseState *state)
{
- struct SLink *ban, *newban, *prevban, *nextban;
+ struct Ban *ban, *newban, *prevban, *nextban;
int count = 0;
int len = 0;
int banlen;
for (prevban = 0, ban = state->chptr->banlist; ban; ban = nextban) {
count++;
- banlen = strlen(ban->value.ban.banstr);
+ banlen = strlen(ban->banstr);
len += banlen;
nextban = ban->next;
count--;
len -= banlen;
- MyFree(ban->value.ban.banstr);
+ MyFree(ban->banstr);
continue;
} else if (ban->flags & MODE_DEL) { /* Deleted a ban? */
modebuf_mode_string(state->mbuf, MODE_DEL | MODE_BAN,
- ban->value.ban.banstr,
+ ban->banstr,
state->flags & MODE_PARSE_SET);
if (state->flags & MODE_PARSE_SET) { /* Ok, make it take effect */
count--;
len -= banlen;
- MyFree(ban->value.ban.who);
- free_link(ban);
+ ban->banstr = NULL; /* do not free this string */
+ free_ban(ban);
changed++;
continue; /* next ban; keep prevban like it is */
!(state->flags & MODE_PARSE_BOUNCE)) {
count--;
len -= banlen;
-
- MyFree(ban->value.ban.banstr);
+ MyFree(ban->banstr);
} else {
if (state->flags & MODE_PARSE_SET && MyUser(state->sptr) &&
(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);
+ ban->banstr);
count--;
len -= banlen;
-
- MyFree(ban->value.ban.banstr);
+ MyFree(ban->banstr);
} else {
/* add the ban to the buffer */
modebuf_mode_string(state->mbuf, MODE_ADD | MODE_BAN,
- ban->value.ban.banstr,
+ ban->banstr,
!(state->flags & MODE_PARSE_SET));
if (state->flags & MODE_PARSE_SET) { /* create a new ban */
- newban = make_link();
- newban->value.ban.banstr = ban->value.ban.banstr;
- DupString(newban->value.ban.who, ban->value.ban.who);
- newban->value.ban.when = ban->value.ban.when;
+ newban = make_ban(ban->banstr);
+ DupString(newban->who, ban->who);
+ newban->when = ban->when;
newban->flags = ban->flags & (CHFL_BAN | CHFL_BAN_IPMASK);
newban->next = state->chptr->banlist; /* and link it in */
for (i = 0; i < MAXPARA; i++) { /* initialize ops/voices arrays */
state.banlist[i].next = 0;
- state.banlist[i].value.ban.banstr = 0;
- state.banlist[i].value.ban.who = 0;
- state.banlist[i].value.ban.when = 0;
+ state.banlist[i].who = 0;
+ state.banlist[i].when = 0;
state.banlist[i].flags = 0;
state.cli_change[i].flag = 0;
state.cli_change[i].client = 0;
struct Channel *chptr;
time_t timestamp;
struct Membership *member, *nmember;
- struct SLink *lp, **lp_p;
+ struct Ban *lp, **lp_p;
unsigned int parse_flags = (MODE_PARSE_FORCE | MODE_PARSE_BURST);
int param, nickpos = 0, banpos = 0;
char modestr[BUFSIZE], nickstr[BUFSIZE], banstr[BUFSIZE];
case '%': /* parameter contains bans */
if (parse_flags & MODE_PARSE_SET) {
char *banlist = parv[param] + 1, *p = 0, *ban, *ptr;
- struct SLink *newban;
+ struct Ban *newban;
for (ban = ircd_strtok(&p, banlist, " "); ban;
ban = ircd_strtok(&p, 0, " ")) {
* shown below *sigh*
*/
for (lp = chptr->banlist; lp; lp = lp->next) {
- if (!ircd_strcmp(lp->value.ban.banstr, ban)) {
+ if (!ircd_strcmp(lp->banstr, ban)) {
ban = 0; /* don't add ban */
lp->flags &= ~CHFL_BURST_BAN_WIPEOUT; /* not wiping out */
break; /* new ban already existed; don't even repropagate */
} else if (!(lp->flags & CHFL_BURST_BAN_WIPEOUT) &&
- !mmatch(lp->value.ban.banstr, ban)) {
+ !mmatch(lp->banstr, ban)) {
ban = 0; /* don't add ban unless wiping out bans */
break; /* new ban is encompassed by an existing one; drop */
- } else if (!mmatch(ban, lp->value.ban.banstr))
+ } else if (!mmatch(ban, lp->banstr))
lp->flags |= CHFL_BAN_OVERLAPPED; /* remove overlapping ban */
if (!lp->next)
for (ptr = ban; *ptr; ptr++) /* add ban to buffer */
banstr[banpos++] = *ptr;
- newban = make_link(); /* create new ban */
+ newban = make_ban(ban); /* create new ban */
- DupString(newban->value.ban.banstr, ban);
-
- DupString(newban->value.ban.who,
+ DupString(newban->who,
cli_name(feature_bool(FEAT_HIS_BANWHO) ? &me : sptr));
- newban->value.ban.when = TStime();
+ newban->when = TStime();
newban->flags = CHFL_BAN | CHFL_BURST_BAN; /* set flags */
if ((ptr = strrchr(ban, '@')) && check_if_ipmask(ptr + 1))
/* remove ban from channel */
if (lp->flags & (CHFL_BAN_OVERLAPPED | CHFL_BURST_BAN_WIPEOUT)) {
modebuf_mode_string(mbuf, MODE_DEL | MODE_BAN,
- lp->value.ban.banstr, 1); /* let it free banstr */
-
+ lp->banstr, 1); /* let it free banstr */
+ lp->banstr = NULL; /* do not free this string */
*lp_p = lp->next; /* clip out of list */
- MyFree(lp->value.ban.who); /* free who */
- free_link(lp); /* free ban */
+ free_ban(lp);
continue;
} else if (lp->flags & CHFL_BURST_BAN) /* add ban to channel */
modebuf_mode_string(mbuf, MODE_ADD | MODE_BAN,
- lp->value.ban.banstr, 0); /* don't free banstr */
+ lp->banstr, 0); /* don't free banstr */
lp->flags &= (CHFL_BAN | CHFL_BAN_IPMASK); /* reset the flag */
lp_p = &(*lp_p)->next;