Logo Search packages:      
Sourcecode: rageircd version File versions  Download package

channel_ban.c

/*
 * RageIRCd: an advanced Internet Relay Chat daemon (ircd).
 * (C) 2000-2005 the RageIRCd Development Team, all rights reserved.
 *
 * This software is free, licensed under the General Public License.
 * Please refer to doc/LICENSE and doc/README for further details.
 *
 * $Id: channel_ban.c,v 1.14.2.1 2004/12/07 03:05:06 pneumatus Exp $
 */

#include "struct.h"
#include "common.h"
#include "sys.h"
#include "numeric.h"
#include "channel.h"
#include "h.h"
#include "memory.h"
#include "hook.h"
#include "xmode.h"

BlockHeap *channelban_heap;

void init_channelbans()
{
      channelban_heap = BlockHeapCreate(sizeof(channelBan), CHANNELBAN_HEAP_SIZE);
}

#define BanList(ch, t) ((t == CMODE_INVEX) ? &chptr->invexlist : ((t == CMODE_EXCEPT) ? &chptr->exceptlist : &chptr->banlist))
#define BanFlag(t) ((t == CMODE_INVEX) ? 'I' : ((t == CMODE_EXCEPT) ? 'e' : 'b'))

void destroy_channelban(channelBan *ban)
{
      ASSERT(ban != NULL);
      MyFree(ban->id);
      MyFree(ban->set_by);
      free_channelban(ban);
}

int add_id(char *id, aChannel *chptr, long type, aClient *cptr)
{
      dlink_list *list;
      dlink_node *node;
      channelBan *ban;

      ASSERT(!BadPtr(id));
      ASSERT(chptr != NULL);
      ASSERT(cptr != NULL);

      list = BanList(chptr, type);

      if (MyClient(cptr) && (dlink_length(list) >= GeneralConfig.max_bans)) {
            send_me_numeric(cptr, ERR_BANLISTFULL, chptr->chname, id);
            return 0;
      }
      DLINK_FOREACH_DATA(list->head, node, ban, channelBan) {
            if (MyClient(cptr)) {
                  if (!match(ban->id, id)) {
                        return 0;
                  }
            }
            else if (!mycmp(ban->id, id)) {
                  return 0;
            }
      }

      ban = make_channelban();
      ban->when = timeofday;
      DupString(ban->id, id);

      if (IsPerson(cptr)) {
            ban->set_by = (char *)MyMalloc(strlen(cptr->name) + strlen(cptr->username) + strlen(MaskedHost(cptr)) + 3);
            ircsprintf(ban->set_by, "%s!%s@%s", cptr->name, cptr->username, MaskedHost(cptr));
      }
      else {
            DupString(ban->set_by, cptr->name);
      }

      dlink_add(list, ban);

      if (type != CMODE_INVEX) {
            chptr->banserial++;
      }

      return 1;
}

int del_id(char *id, aChannel *chptr, long type)
{
      dlink_list *list;
      dlink_node *node = NULL, *next = NULL;
      channelBan *ban;

      ASSERT(!BadPtr(id));
      ASSERT(chptr != NULL);

      list = BanList(chptr, type);

      DLINK_FOREACH_SAFE_DATA(list->head, node, next, ban, channelBan) {
            if (mycmp(id, ban->id)) {
                  continue;
            }

            dlink_del(list, NULL, node);
            destroy_channelban(ban);

            if (type != CMODE_INVEX) {
                  chptr->banserial++;
            }

            return 1;
      }

      return 0;
}

int is_invited(aClient *cptr, aChannel *chptr)
{
      dlink_node *node;
      channelBan *invex;
      char s_nuh_masked[NICKLEN + USERLEN + HOSTLEN + 3];
      char s_nuh_host[NICKLEN + USERLEN + HOSTLEN + 3];
      char *s_nuh_ip;

      if (!IsPerson(cptr)) {
            return 0;
      }

      if (HasMode(cptr, UMODE_MASKED)) {
            strcpy(s_nuh_masked, make_nick_user_host(cptr->name, cptr->username, MaskedHost(cptr)));
      }
      strcpy(s_nuh_host, make_nick_user_host(cptr->name, cptr->username, cptr->host));
      s_nuh_ip = make_nick_user_host(cptr->name, cptr->username, cptr->hostip);

      DLINK_FOREACH_DATA(chptr->invexlist.head, node, invex, channelBan) {
            if (HasMode(cptr, UMODE_MASKED)) {
                  if (!match(invex->id, s_nuh_masked)) {
                        return 1;
                  }
            }
            if (!match(invex->id, s_nuh_host) || !match(invex->id, s_nuh_ip)) {
                  return 1;
            }
      }

      return 0;
}

int is_banned(aClient *cptr, aChannel *chptr, chanMember *cm)
{
      dlink_node *node;
      channelBan *ban, *found = NULL;
      char s_nuh_masked[NICKLEN + USERLEN + HOSTLEN + 3];
      char s_nuh_host[NICKLEN + USERLEN + HOSTLEN + 3];
      char *s_nuh_ip;

      if (!IsPerson(cptr)) {
            return 0;
      }

      if (cm != NULL) {
            if (cm->banserial == chptr->banserial) {
                  return (cm->flags & CMODE_BAN);
            }

            cm->banserial = chptr->banserial;
            cm->flags &= ~CMODE_BAN;
      }

      if (HasMode(cptr, UMODE_MASKED)) {
            strcpy(s_nuh_masked, make_nick_user_host(cptr->name, cptr->username, MaskedHost(cptr)));
      }
      strcpy(s_nuh_host, make_nick_user_host(cptr->name, cptr->username, cptr->host));
      s_nuh_ip = make_nick_user_host(cptr->name, cptr->username, cptr->hostip);

      DLINK_FOREACH_DATA(chptr->exceptlist.head, node, ban, channelBan) {
            if (HasMode(cptr, UMODE_MASKED)) {
                  if (!match(ban->id, s_nuh_masked)) {
                        return 0;
                  }
            }
            if (!match(ban->id, s_nuh_host) || !match(ban->id, s_nuh_ip)) {
                  return 0;
            }
      }

      DLINK_FOREACH_DATA(chptr->banlist.head, node, ban, channelBan) {
            if (HasMode(cptr, UMODE_MASKED)) {
                  if (!match(ban->id, s_nuh_masked)) {
                        found = ban;
                        break;
                  }
            }
            if (!match(ban->id, s_nuh_host) || !match(ban->id, s_nuh_ip)) {
                  found = ban;
                  break;
            }
      }

      if (found != NULL) {
            if (cm != NULL) {
                  cm->flags |= CMODE_BAN;
            }
            return CMODE_BAN;
      }

      return 0;
}

void send_ban_list(aClient *sptr, aChannel *chptr, dlink_list *list, int listn, int endn)
{
      dlink_node *node;
      channelBan *ban;

      ASSERT(sptr != NULL);
      ASSERT(chptr != NULL);
      ASSERT(list != NULL);

      DLINK_FOREACH_DATA(list->head, node, ban, channelBan) {
            send_me_numeric(sptr, listn, chptr->chname, ban->id, ban->set_by, ban->when);
      }
      send_me_numeric(sptr, endn, chptr->chname);
}

void synch_ban_list(aClient *sptr, aChannel *chptr, long mode)
{
      dlink_list *list;
      dlink_node *node;
      char flag;
      channelBan *ban;
      int n = 0, send_it = 0;

      ASSERT(sptr != NULL);
      ASSERT(chptr != NULL);

      flag = BanFlag(mode);
      list = BanList(chptr, mode);

      midx = pidx = 0;
      modebuf[0] = parabuf[0] = '\0';
      ADD_MODE('+');

      DLINK_FOREACH_DATA(list->head, node, ban, channelBan) {
            if ((pidx + strlen(ban->id) + 10) < MODEBUFLEN) {
                  ADD_MODE(flag);
                  ADD_NPARA(ban->id);
                  n++;
            }
            else if (pidx) {
                  send_it = 1;
            }
            if (n == MAXTSMODEPARAMS) {
                  send_it = 1;
            }
            if (send_it) {
                  sendto_one_client_nopostfix(sptr, &me, &CMD_MODE, "%s %ld %s %s",
                        chptr->chname, chptr->channelts, modebuf, parabuf);

                  midx = pidx = send_it = 0;
                  modebuf[0] = parabuf[0] = '\0';
                  ADD_MODE('+');

                  if (n != MAXTSMODEPARAMS) {
                        ADD_MODE(flag);
                        ADD_NPARA(ban->id);
                        n = 1;
                        continue;
                  }
                  n = 0;
            }
      }
      if (midx > 1) {
            sendto_one_client_nopostfix(sptr, &me, &CMD_MODE, "%s %ld %s %s", chptr->chname,
                  chptr->channelts, modebuf, parabuf);
      }
}

void kill_ban_list(aClient *sptr, aChannel *chptr, long mode)
{
      dlink_list *list;
      dlink_node *node, *next = NULL;
      char flag;
      channelBan *ban;
      int n = 0, send_it = 0;

      ASSERT(sptr != NULL);
      ASSERT(chptr != NULL);

      flag = BanFlag(mode);
      list = BanList(chptr, mode);

      midx = pidx = 0;
      modebuf[0] = parabuf[0] = '\0';
      ADD_MODE('-');

      DLINK_FOREACH_SAFE_DATA(list->head, node, next, ban, channelBan) {
            if ((pidx + strlen(ban->id) + 10) < MODEBUFLEN) {
                  ADD_MODE(flag);
                  ADD_NPARA(ban->id);
                  n++;
            }
            else if (pidx) {
                  send_it = 1;
            }
            if (n >= MAXMODEPARAMS) {
                  send_it = 1;
            }

            if (send_it) {
                  sendto_channel_local_msg_butone(NULL, &me, chptr, ALL_MEMBERS,
                        &CMD_MODE, "%s %s %s", chptr->chname, modebuf, parabuf);
                  send_it = 0;

                  midx = pidx = 0;
                  modebuf[0] = parabuf[0] = '\0';
                  ADD_MODE('-');

                  if (n != MAXMODEPARAMS) {
                        ADD_MODE(flag);
                        ADD_NPARA(ban->id);
                        n = 1;
                        continue;
                  }

                  n = 0;
            }

            dlink_del(list, NULL, node);
            destroy_channelban(ban);
      }
      if (midx > 1) {
            sendto_channel_local_msg_butone(NULL, &me, chptr, ALL_MEMBERS, &CMD_MODE,
                  "%s %s %s", chptr->chname, modebuf, parabuf);
      }

      if (mode != CMODE_INVEX) {
            chptr->banserial++;
      }
}

Generated by  Doxygen 1.6.0   Back to index