コード例 #1
0
ファイル: irc.c プロジェクト: Estella/eggdrop-1.8
/* Set the key.
 */
static void set_key(struct chanset_t *chan, char *k)
{
    nfree(chan->channel.key);
    if (k == NULL) {
        chan->channel.key = (char *) channel_malloc(1);
        chan->channel.key[0] = 0;
        return;
    }
    chan->channel.key = (char *) channel_malloc(strlen(k) + 1);
    strcpy(chan->channel.key, k);
}
コード例 #2
0
ファイル: irc.c プロジェクト: Estella/eggdrop-1.8
/* Adds a ban, exempt or invite mask to the list
 * m should be chan->channel.(exempt|invite|ban)
 */
static void newmask(masklist *m, char *s, char *who)
{
    for (; m && m->mask[0] && rfc_casecmp(m->mask, s); m = m->next);
    if (m->mask[0])
        return;                     /* Already existent mask */

    m->next = (masklist *) channel_malloc(sizeof(masklist));
    m->next->next = NULL;
    m->next->mask = (char *) channel_malloc(1);
    m->next->mask[0] = 0;
    nfree(m->mask);
    m->mask = (char *) channel_malloc(strlen(s) + 1);
    strcpy(m->mask, s);
    m->who = (char *) channel_malloc(strlen(who) + 1);
    strcpy(m->who, who);
    m->timer = now;
}
コード例 #3
0
ファイル: irc.c プロジェクト: Estella/eggdrop-1.8
/* Reset channel information.
 */
static void reset_chan_info(struct chanset_t *chan, int reset)
{
    char beI[4] = "\0";
    /* Leave the channel if we aren't supposed to be there */
    if (channel_inactive(chan)) {
        dprintf(DP_MODE, "PART %s\n", chan->name);
        return;
    }

    /* Don't reset the channel if we're already resetting it */
    if (channel_pending(chan))
        return;

    clear_channel(chan, reset);
    if ((reset & CHAN_RESETBANS) && !(chan->status & CHAN_ASKEDBANS)) {
        chan->status |= CHAN_ASKEDBANS;
        strcat(beI, "b");
    }
    if ((reset & CHAN_RESETEXEMPTS) &&
            !(chan->ircnet_status & CHAN_ASKED_EXEMPTS) && (use_exempts == 1)) {
        chan->ircnet_status |= CHAN_ASKED_EXEMPTS;
        strcat(beI, "e");
    }
    if ((reset & CHAN_RESETINVITED) &&
            !(chan->ircnet_status & CHAN_ASKED_INVITED) && (use_invites == 1)) {
        chan->ircnet_status |= CHAN_ASKED_INVITED;
        strcat(beI, "I");
    }
    if (beI[0])
        dprintf(DP_MODE, "MODE %s +%s\n", chan->name, beI);
    if (reset & CHAN_RESETMODES) {
        /* done here to keep expmem happy, as this is accounted in
           irc.mod, not channels.mod where clear_channel() resides */
        nfree(chan->channel.key);
        chan->channel.key = (char *) channel_malloc (1);
        chan->channel.key[0] = 0;
        chan->status &= ~CHAN_ASKEDMODES;
        dprintf(DP_MODE, "MODE %s\n", chan->name);
    }
    if (reset & CHAN_RESETWHO) {
        chan->status |= CHAN_PEND;
        chan->status &= ~CHAN_ACTIVE;
        refresh_who_chan(chan->name);
    }
    if (reset & CHAN_RESETTOPIC)
        dprintf(DP_MODE, "TOPIC %s\n", chan->name);
}
コード例 #4
0
ファイル: irc.c プロジェクト: Estella/eggdrop-1.8
/* Removes a nick from the channel member list (returns 1 if successful)
 */
static int killmember(struct chanset_t *chan, char *nick)
{
    memberlist *x, *old;

    old = NULL;
    for (x = chan->channel.member; x && x->nick[0]; old = x, x = x->next)
        if (!rfc_casecmp(x->nick, nick))
            break;
    if (!x || !x->nick[0]) {
        if (!channel_pending(chan) && !channel_djoins(chan))
            putlog(LOG_MISC, "*", "(!) killmember(%s) -> nonexistent", nick);
        return 0;
    }
    if (old)
        old->next = x->next;
    else
        chan->channel.member = x->next;
    nfree(x);
    chan->channel.members--;

    /* The following two errors should NEVER happen. We will try to correct
     * them though, to keep the bot from crashing.
     */
    if (chan->channel.members < 0) {
        chan->channel.members = 0;
        for (x = chan->channel.member; x && x->nick[0]; x = x->next)
            chan->channel.members++;
        putlog(LOG_MISC, "*", "(!) actually I know of %d members.",
               chan->channel.members);
    }
    if (!chan->channel.member) {
        chan->channel.member = (memberlist *) channel_malloc(sizeof(memberlist));
        chan->channel.member->nick[0] = 0;
        chan->channel.member->next = NULL;
    }
    return 1;
}
コード例 #5
0
ファイル: mode.c プロジェクト: DrRemorse/eggdrop-1.8
/* Queue a channel mode change
 */
static void real_add_mode(struct chanset_t *chan,
                          char plus, char mode, char *op)
{
  int i, type, modes, l;
  masklist *m;
  memberlist *mx;
  char s[21];

  /* Some IRCds do not allow halfops to set certain modes. The modes halfops
   * are not allowed to set can be changed in chan.h. */
#ifdef NO_HALFOP_CHANMODES
  if (!me_op(chan))
#else
  if (HALFOP_CANTDOMODE(mode))
#endif
    return;

  if (mode == 'o' || mode == 'h' || mode == 'v') {
    mx = ismember(chan, op);
    if (!mx)
      return;
    if (plus == '-' && mode == 'o') {
      if (chan_sentdeop(mx) || !chan_hasop(mx))
        return;
      mx->flags |= SENTDEOP;
    }
    if (plus == '+' && mode == 'o') {
      if (chan_sentop(mx) || chan_hasop(mx))
        return;
      mx->flags |= SENTOP;
    }
    if (plus == '-' && mode == 'h') {
      if (chan_sentdehalfop(mx) || !chan_hashalfop(mx))
        return;
      mx->flags |= SENTDEHALFOP;
    }
    if (plus == '+' && mode == 'h') {
      if (chan_senthalfop(mx) || chan_hashalfop(mx))
        return;
      mx->flags |= SENTHALFOP;
    }
    if (plus == '-' && mode == 'v') {
      if (chan_sentdevoice(mx) || !chan_hasvoice(mx))
        return;
      mx->flags |= SENTDEVOICE;
    }
    if (plus == '+' && mode == 'v') {
      if (chan_sentvoice(mx) || chan_hasvoice(mx))
        return;
      mx->flags |= SENTVOICE;
    }
  }

  if (chan->compat == 0) {
    if (mode == 'e' || mode == 'I')
      chan->compat = 2;
    else
      chan->compat = 1;
  } else if (mode == 'e' || mode == 'I') {
    if (prevent_mixing && chan->compat == 1)
      flush_mode(chan, NORMAL);
  } else if (prevent_mixing && chan->compat == 2)
    flush_mode(chan, NORMAL);

  if (mode == 'o' || mode == 'h' || mode == 'b' || mode == 'v' || mode == 'e' ||
      mode == 'I') {
    type = (plus == '+' ? PLUS : MINUS) | (mode == 'o' ? CHOP : (mode == 'h' ?
           CHHOP : (mode == 'b' ? BAN : (mode == 'v' ? VOICE : (mode == 'e' ?
           EXEMPT : INVITE)))));
    /*
     * FIXME: Some networks remove overlapped bans,
     *        IRCnet does not (poptix/drummer)
     *
     * Note:  On IRCnet ischanXXX() should be used, otherwise isXXXed().
     */
    if ((plus == '-' && ((mode == 'b' && !ischanban(chan, op)) ||
        (mode == 'e' && !ischanexempt(chan, op)) ||
        (mode == 'I' && !ischaninvite(chan, op)))) || (plus == '+' &&
        ((mode == 'b' && ischanban(chan, op)) ||
        (mode == 'e' && ischanexempt(chan, op)) ||
        (mode == 'I' && ischaninvite(chan, op)))))
      return;

    /* If there are already max_bans bans, max_exempts exemptions,
     * max_invites invitations or max_modes +b/+e/+I modes on the
     * channel, don't try to add one more.
     */
    if (plus == '+' && (mode == 'b' || mode == 'e' || mode == 'I')) {
      int bans = 0, exempts = 0, invites = 0;

      for (m = chan->channel.ban; m && m->mask[0]; m = m->next)
        bans++;
      if ((mode == 'b') && (bans >= max_bans))
        return;

      for (m = chan->channel.exempt; m && m->mask[0]; m = m->next)
        exempts++;
      if ((mode == 'e') && (exempts >= max_exempts))
        return;

      for (m = chan->channel.invite; m && m->mask[0]; m = m->next)
        invites++;
      if ((mode == 'I') && (invites >= max_invites))
        return;

      if (bans + exempts + invites >= max_modes)
        return;
    }

    /* op-type mode change */
    for (i = 0; i < modesperline; i++)
      if (chan->cmode[i].type == type && chan->cmode[i].op != NULL &&
          !rfc_casecmp(chan->cmode[i].op, op))
        return;                 /* Already in there :- duplicate */
    l = strlen(op) + 1;
    if (chan->bytes + l > mode_buf_len)
      flush_mode(chan, NORMAL);
    for (i = 0; i < modesperline; i++)
      if (chan->cmode[i].type == 0) {
        chan->cmode[i].type = type;
        chan->cmode[i].op = (char *) channel_malloc(l);
        chan->bytes += l;       /* Add 1 for safety */
        strcpy(chan->cmode[i].op, op);
        break;
      }
  }

  /* +k ? store key */
  else if (plus == '+' && mode == 'k') {
    if (chan->key)
      nfree(chan->key);
    chan->key = (char *) channel_malloc(strlen(op) + 1);
    if (chan->key)
      strcpy(chan->key, op);
  }
  /* -k ? store removed key */
  else if (plus == '-' && mode == 'k') {
    if (chan->rmkey)
      nfree(chan->rmkey);
    chan->rmkey = (char *) channel_malloc(strlen(op) + 1);
    if (chan->rmkey)
      strcpy(chan->rmkey, op);
  }
  /* +l ? store limit */
  else if (plus == '+' && mode == 'l')
    chan->limit = atoi(op);
  else {
    /* Typical mode changes */
    if (plus == '+')
      strcpy(s, chan->pls);
    else
      strcpy(s, chan->mns);
    if (!strchr(s, mode)) {
      if (plus == '+') {
        chan->pls[strlen(chan->pls) + 1] = 0;
        chan->pls[strlen(chan->pls)] = mode;
      } else {
        chan->mns[strlen(chan->mns) + 1] = 0;
        chan->mns[strlen(chan->mns)] = mode;
      }
    }
  }
  modes = modesperline;         /* Check for full buffer. */
  for (i = 0; i < modesperline; i++)
    if (chan->cmode[i].type)
      modes--;
  if (include_lk && chan->limit)
    modes--;
  if (include_lk && chan->rmkey)
    modes--;
  if (include_lk && chan->key)
    modes--;
  if (modes < 1)
    flush_mode(chan, NORMAL);   /* Full buffer! Flush modes. */
}