Example #1
0
/* If i'm the only person on the channel, and i'm not op'd,
 * might as well leave and rejoin. If i'm NOT the only person
 * on the channel, but i'm still not op'd, demand ops.
 */
static void check_lonely_channel(struct chanset_t *chan)
{
    memberlist *m;
    char s[UHOSTLEN];
    int i = 0;

    if (channel_pending(chan) || !channel_active(chan) || me_op(chan) ||
            channel_inactive(chan) || (chan->channel.mode & CHANANON))
        return;
    /* Count non-split channel members */
    for (m = chan->channel.member; m && m->nick[0]; m = m->next)
        if (!chan_issplit(m))
            i++;
    if (i == 1 && channel_cycle(chan) && !channel_stop_cycle(chan)) {
        if (chan->name[0] != '+') { /* Its pointless to cycle + chans for ops */
            putlog(LOG_MISC, "*", "Trying to cycle %s to regain ops.", chan->dname);
            dprintf(DP_MODE, "PART %s\n", chan->name);

            /* If it's a !chan, we need to recreate the channel with !!chan <cybah> */
            if (chan->key_prot[0])
                dprintf(DP_MODE, "JOIN %s%s %s\n", (chan->dname[0] == '!') ? "!" : "",
                        chan->dname, chan->key_prot);
            else
                dprintf(DP_MODE, "JOIN %s%s\n", (chan->dname[0] == '!') ? "!" : "",
                        chan->dname);
            chan->status &= ~CHAN_WHINED;
        }
    } else if (any_ops(chan)) {
        chan->status &= ~CHAN_WHINED;
        check_tcl_need(chan->dname, "op");
        if (chan->need_op[0])
            do_tcl("need-op", chan->need_op);
    } else {
        /* Other people here, but none are ops. If there are other bots make
         * them LEAVE!
         */
        int ok = 1;
        struct userrec *u;

        if (!channel_whined(chan)) {
            /* + is opless. Complaining about no ops when without special
             * help(services), we cant get them - Raist
             */
            if (chan->name[0] != '+' && channel_logstatus(chan))
                putlog(LOG_MISC, "*", "%s is active but has no ops :(", chan->dname);
            chan->status |= CHAN_WHINED;
        }
        for (m = chan->channel.member; m && m->nick[0]; m = m->next) {
            sprintf(s, "%s!%s", m->nick, m->userhost);
            u = get_user_by_host(s);
            if (!match_my_nick(m->nick) && (!u || !(u->flags & USER_BOT))) {
                ok = 0;
                break;
            }
        }
        if (ok && channel_cycle(chan)) {
            /* ALL bots!  make them LEAVE!!! */
            for (m = chan->channel.member; m && m->nick[0]; m = m->next)
                if (!match_my_nick(m->nick))
                    dprintf(DP_SERVER, "PRIVMSG %s :go %s\n", m->nick, chan->dname);
        } else {
            /* Some humans on channel, but still op-less */
            check_tcl_need(chan->dname, "op");
            if (chan->need_op[0])
                do_tcl("need-op", chan->need_op);
        }
    }
}
Example #2
0
static void got_deop(struct chanset_t *chan, char *nick, char *from,
                     char *who, struct userrec *opu)
{
  memberlist *m;
  char ch[sizeof chan->name];
  char s[UHOSTLEN], s1[UHOSTLEN];
  struct userrec *u;
  int had_halfop;

  m = ismember(chan, who);
  if (!m) {
    if (channel_pending(chan))
      return;
    putlog(LOG_MISC, chan->dname, CHAN_BADCHANMODE, chan->dname, who);
    chan->status |= CHAN_PEND;
    refresh_who_chan(chan->name);
    return;
  }

  strcpy(ch, chan->name);
  simple_sprintf(s, "%s!%s", m->nick, m->userhost);
  simple_sprintf(s1, "%s!%s", nick, from);
  u = get_user_by_host(s);
  get_user_flagrec(u, &victim, chan->dname);

  had_halfop = chan_hasop(m);
  /* Flags need to be set correctly right from the beginning now, so that
   * add_mode() doesn't get irritated.
   */
  m->flags &= ~(CHANOP | SENTDEOP | FAKEOP);
  check_tcl_mode(nick, from, opu, chan->dname, "-o", who);
  if (!(chan = modebind_refresh(ch, from, &user, s, &victim)) ||
      !(m = ismember(chan, who)))
    return;
  m->flags &= ~WASOP;

  if (channel_pending(chan))
    return;

  if (HALFOP_CANDOMODE('o')) {
    int ok = 1;

    if (!glob_deop(victim) && !chan_deop(victim)) {
      if (channel_protectops(chan) && (glob_master(victim) ||
          chan_master(victim) || glob_op(victim) || chan_op(victim)))
        ok = 0;
      else if (channel_protectfriends(chan) && (glob_friend(victim) ||
               chan_friend(victim)))
        ok = 0;
    }
    if ((reversing || !ok) && had_halfop && !match_my_nick(nick) &&
        rfc_casecmp(who, nick) && !match_my_nick(who) && !glob_master(user) &&
        !chan_master(user) && !glob_bot(user) && ((chan_op(victim) ||
        (glob_op(victim) && !chan_deop(victim))) || !channel_bitch(chan)))
      add_mode(chan, '+', 'o', who);
  }

  if (!nick[0])
    putlog(LOG_MODES, chan->dname, "TS resync (%s): %s deopped by %s",
           chan->dname, who, from);

  /* Check for mass deop */
  if (nick[0])
    detect_chan_flood(nick, from, s1, chan, FLOOD_DEOP, who, 0);

  /* Having op hides your +v and +h status -- so now that someone's lost ops,
   * check to see if they have +v or +h
   */
  if (!(m->flags & (CHANVOICE | CHANHALFOP | STOPWHO))) {
    chan->status |= CHAN_PEND;
    refresh_who_chan(chan->name);
    m->flags |= STOPWHO;
  }

  /* Was the bot deopped? */
  if (match_my_nick(who)) {
    /* Cancel any pending kicks and modes */
    memberlist *m2;

    for (m2 = chan->channel.member; m2 && m2->nick[0]; m2 = m2->next)
      m2->flags &= ~(SENTKICK | SENTDEOP | SENTOP | SENTVOICE | SENTDEVOICE);

    check_tcl_need(chan->dname, "op");
    if (chan->need_op[0])
      do_tcl("need-op", chan->need_op);
    if (!nick[0])
      putlog(LOG_MODES, chan->dname, "TS resync deopped me on %s :(",
             chan->dname);
  }
  if (nick[0])
    maybe_revenge(chan, s1, s, REVENGE_DEOP);
}