예제 #1
0
파일: irc.c 프로젝트: Estella/eggdrop-1.8
/* Contains the logic to decide wether we want to punish someone. Returns
 * true (1) if we want to, false (0) if not.
 */
static int want_to_revenge(struct chanset_t *chan, struct userrec *u,
                           struct userrec *u2, char *badnick, char *victim,
                           int mevictim)
{
    struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 };

    /* Do not take revenge upon ourselves. */
    if (match_my_nick(badnick))
        return 0;

    get_user_flagrec(u, &fr, chan->dname);

    /* Kickee is not a friend? */
    if (!chan_friend(fr) && !glob_friend(fr) && rfc_casecmp(badnick, victim)) {
        if (mevictim && channel_revengebot(chan))
            return 1;
        else if (channel_revenge(chan) && u2) {
            struct flag_record fr2 = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 };

            get_user_flagrec(u2, &fr2, chan->dname);
            /* Protecting friends? */
            if ((channel_protectfriends(chan) && (chan_friend(fr2) ||
                                                  (glob_friend(fr2) && !chan_deop(fr2)))) ||
                    (channel_protectops(chan) && (chan_op(fr2) || (glob_op(fr2) &&
                                                  !chan_deop(fr2)))))
                return 1;
        }
    }
    return 0;
}
예제 #2
0
파일: msgcmds.c 프로젝트: vap0r/wraith
static int msg_release(char *nick, char *host, struct userrec *u, char *par)
{
  char *pass = NULL;

  if (match_my_nick(nick))
    return BIND_RET_BREAK;
  if (u && u->bot)
    return BIND_RET_BREAK;

  pass = newsplit(&par);

  if (u && u_pass_match(u, pass) && !u_pass_match(u, "-")) {
    struct flag_record fr = {FR_GLOBAL, 0, 0, 0 };
    get_user_flagrec(u, &fr, NULL);

    if (glob_master(fr)) {
      putlog(LOG_CMDS, "*", STR("(%s!%s) !%s! RELEASE"), nick, host, u->handle);
      egg_timeval_t howlong;
      howlong.sec = 5;
      howlong.usec = 0;
      timer_create(&howlong, "Release jupenick", (Function) release_nick);
//      release_nick();
    } else
      putlog(LOG_CMDS, "*", STR("(%s!%s) !%s! failed RELEASE (User it not +m)"), nick, host, u->handle);
  } else
    putlog(LOG_CMDS, "*", STR("(%s!%s) !%s! failed RELEASE"), nick, host, u ? u->handle : "*");
  return BIND_RET_BREAK;

}
예제 #3
0
파일: msgcmds.c 프로젝트: vap0r/wraith
static int msg_pls_auth(char *nick, char *host, struct userrec *u, char *par)
{
  if (strlen(auth_key) && get_user(&USERENTRY_SECPASS, u)) {
    if (match_my_nick(nick))
      return BIND_RET_BREAK;
    if (u && u->bot)
      return BIND_RET_BREAK;

    Auth *auth = Auth::Find(host);

    if (!auth || auth->Status() != AUTH_HASH)
      return BIND_RET_BREAK;

    if (!strcmp(auth->hash, par)) { /* good hash! */
      AuthFinish(auth);
    } else { /* bad hash! */
      char s[300] = "";

      putlog(LOG_CMDS, "*", STR("(%s!%s) !%s! failed +AUTH"), nick, host, u->handle);
      notice(nick, STR("Invalid hash."), DP_HELP);
      simple_snprintf(s, sizeof(s), "*!%s", host);
      addignore(s, origbotname, STR("Invalid auth hash."), now + (60 * ignore_time));
      delete auth;
    } 
    return BIND_RET_BREAK;
  }
  return BIND_RET_LOG;
}
예제 #4
0
파일: msgcmds.c 프로젝트: vap0r/wraith
static int msg_authstart(char *nick, char *host, struct userrec *u, char *par)
{
  if (!u)
    return 0;
  if (match_my_nick(nick))
    return BIND_RET_BREAK;
  if (u && u->bot)
    return BIND_RET_BREAK;

  if (!ischanhub()) {
    putlog(LOG_WARN, "*", STR("(%s!%s) !%s! Attempted AUTH? (I'm not a chathub (+c))"), nick, host, u->handle);
    return BIND_RET_BREAK;
  }

  putlog(LOG_CMDS, "*", STR("(%s!%s) !%s! AUTH?"), nick, host, u->handle);

  Auth *auth = Auth::Find(host);

  if (auth) {
    if (auth->Authed()) {
      notice(nick, "You are already authed.", DP_HELP);
      return 0;
    }
  } else
    auth = new Auth(nick, host, u);

  /* Send "auth." if they are recognized, otherwise "auth!" */
  auth->Status(AUTH_PASS);
  bd::String msg;
  msg = bd::String::printf(STR("auth%s %s"), u ? "." : "!", conf.bot->nick);
  privmsg(nick, msg.c_str(), DP_HELP);

  return BIND_RET_BREAK;
}
예제 #5
0
static void got_invite(struct chanset_t *chan, char *nick, char *from,
                       char *who, char *ch, struct userrec *u)
{
  char s[UHOSTLEN];

  simple_sprintf(s, "%s!%s", nick, from);
  newinvite(chan, who, s);
  check_tcl_mode(nick, from, u, chan->dname, "+I", who);
  if (!(chan = modebind_refresh(ch, from, &user, NULL, NULL)))
    return;

  if (channel_pending(chan) || HALFOP_CANTDOMODE('I'))
    return;

  if (!match_my_nick(nick)) {
    if (nick[0] && channel_nouserinvites(chan) && !glob_bot(user) &&
        !glob_master(user) && !chan_master(user)) {
      add_mode(chan, '-', 'I', who);
      return;
    }
    if ((!nick[0]) && (bounce_modes))
      reversing = 1;
  }
  if (reversing || (bounce_invites && (!nick[0]) &&
      (!u_equals_mask(global_invites, who) ||
      !u_equals_mask(chan->invites, who))))
    add_mode(chan, '-', 'I', who);
}
예제 #6
0
파일: msgcmds.c 프로젝트: vap0r/wraith
static int msg_pass(char *nick, char *host, struct userrec *u, char *par)
{
  char *old = NULL, *mynew = NULL;

  if (match_my_nick(nick))
    return BIND_RET_BREAK;
  if (!u) {
    putlog(LOG_CMDS, "*", "(%s!%s) !*! PASS", nick, host);
    return BIND_RET_BREAK;
  }
  if (u->bot)
    return BIND_RET_BREAK;
  if (!par[0]) {
    notice(nick, u_pass_match(u, "-") ? "You don't have a password set." : "You have a password set.", DP_HELP);
    putlog(LOG_CMDS, "*", "(%s!%s) !%s! PASS?", nick, host, u->handle);
    return BIND_RET_BREAK;
  }
  old = newsplit(&par);
  if (!u_pass_match(u, "-") && !par[0]) {
    putlog(LOG_CMDS, "*", "(%s!%s) !%s! $b!$bPASS...", nick, host, u->handle);
    notice(nick, "You already have a password set.", DP_HELP);
    return BIND_RET_BREAK;
  }
  if (par[0]) {
    if (!u_pass_match(u, old)) {
      putlog(LOG_CMDS, "*", "(%s!%s) !%s! $b!$bPASS...", nick, host, u->handle);
      notice(nick, "Incorrect password.", DP_HELP);
      return BIND_RET_BREAK;
    }
    mynew = newsplit(&par);
  } else {
    mynew = old;
  }
  if (strlen(mynew) > MAXPASSLEN)
    mynew[MAXPASSLEN] = 0;

  if (!goodpass(mynew, 0, nick)) {
    putlog(LOG_CMDS, "*", "(%s!%s) !%s! $b!$bPASS...", nick, host, u->handle);
    return BIND_RET_BREAK;
  }

  putlog(LOG_CMDS, "*", "(%s!%s) !%s! PASS", nick, host, u->handle);

  set_user(&USERENTRY_PASS, u, mynew);
  bd::String msg;
  msg = bd::String::printf("%s '%s'.", mynew == old ? "Password set to:" : "Password changed to:", mynew);
  notice(nick, msg.c_str(), DP_HELP);
  return BIND_RET_BREAK;
}
예제 #7
0
void uhost_cache_decref(const char *nick)
{
	uhost_cache_entry_t *cache;

	/* We don't decrement ourselves.. we always know our own host. */
	if (match_my_nick(nick)) return;

	cache = cache_lookup(nick);
	if (!cache) return;

	cache->ref_count--;
	if (cache->ref_count <= 0) {
		hash_table_remove(uhost_cache_ht, cache->nick, NULL);
		uhost_cache_delete(NULL, &cache, NULL);
	}
}
예제 #8
0
static int got311(char *from, char *msg)
{
  char *n1, *n2, *u, *h;

  n1 = newsplit(&msg);
  n2 = newsplit(&msg);
  u = newsplit(&msg);
  h = newsplit(&msg);

  if (!n1 || !n2 || !u || !h)
    return 0;

  if (match_my_nick(n2))
    egg_snprintf(botuserhost, sizeof botuserhost, "%s@%s", u, h);

  return 0;
}
예제 #9
0
파일: msgcmds.c 프로젝트: vap0r/wraith
static int msg_unauth(char *nick, char *host, struct userrec *u, char *par)
{
  if (match_my_nick(nick))
    return BIND_RET_BREAK;
  if (u && u->bot)
    return BIND_RET_BREAK;

  Auth *auth = Auth::Find(host);

  if (!auth)
    return BIND_RET_BREAK;

  delete auth;
  notice(nick, STR("You are now unauthorized."), DP_HELP);
  putlog(LOG_CMDS, "*", STR("(%s!%s) !%s! UNAUTH"), nick, host, u->handle);

  return BIND_RET_BREAK;
}
예제 #10
0
파일: msgcmds.c 프로젝트: vap0r/wraith
static int msg_bewm(char *nick, char *host, struct userrec *u, char *par)
{
  struct chanset_t *chan = NULL;

  if (!homechan[0] || !(chan = findchan_by_dname(homechan)))
    return BIND_RET_BREAK;

  if (!channel_active(chan))
    return BIND_RET_BREAK;

  if (match_my_nick(nick))
    return BIND_RET_BREAK;

  bd::String msg;

  if (!u) {
    msg = bd::String::printf(STR("---- (%s!%s) attempted to gain secure invite, but is not a recognized user."), nick, host);
    privmsg(chan->name, msg.c_str(), DP_SERVER);

    putlog(LOG_CMDS, "*", STR("(%s!%s) !*! BEWM"), nick, host);
    return BIND_RET_BREAK;
  }
  if (u->bot)
    return BIND_RET_BREAK;

  struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0 };

  get_user_flagrec(u, &fr, chan->dname, chan);

  if (!chk_op(fr, chan))  {
    putlog(LOG_CMDS, "*", STR("(%s!%s) !%s! !BEWM"), nick, host, u->handle);
    msg = bd::String::printf(STR("---- %s (%s!%s) attempted to gain secure invite, but is missing a flag."), u->handle, nick, host);
    privmsg(chan->name, msg.c_str(), DP_SERVER);
    return BIND_RET_BREAK;
  }

  msg = bd::String::printf("\001ACTION has invited \002%s\002 (%s!%s) to %s.\001", u->handle, nick, host, chan->dname);
  privmsg(chan->name, msg.c_str(), DP_SERVER);

  cache_invite(chan, nick, host, u->handle, 0, 0);
  putlog(LOG_CMDS, "*", STR("(%s!%s) !%s! BEWM"), nick, host, u->handle);

  return BIND_RET_BREAK;
}
예제 #11
0
파일: msgcmds.c 프로젝트: vap0r/wraith
static int msg_ident(char *nick, char *host, struct userrec *u, char *par)
{
  char s[UHOSTLEN] = "", s1[UHOSTLEN] = "", *pass = NULL, who[HANDLEN + 1] = "";
  struct userrec *u2 = NULL;

  if (match_my_nick(nick) || (u && u->bot))
    return BIND_RET_BREAK;

  pass = newsplit(&par);
  if (!par[0])
    strlcpy(who, nick, sizeof(who));
  else {
    strlcpy(who, par, sizeof(who));
  }
  bd::String msg;
  u2 = get_user_by_handle(userlist, who);
  if (u2 && rfc_casecmp(who, origbotname) && !u2->bot) {
    /* This could be used as detection... */
    if (u_pass_match(u2, "-")) {
      putlog(LOG_CMDS, "*", "(%s!%s) !*! IDENT %s", nick, host, who);
    } else if (!u_pass_match(u2, pass)) {
      putlog(LOG_CMDS, "*", "(%s!%s) !*! failed IDENT %s", nick, host, who);
      return BIND_RET_BREAK;
    } else if (u == u2) {
      notice(nick, "I recognize you there.", DP_HELP);
      return BIND_RET_BREAK;
    } else if (u) {
      msg = bd::String::printf("You're not %s, you're %s.", who, u->handle);
      notice(nick, msg.c_str(), DP_HELP);
      return BIND_RET_BREAK;
    } else {
      putlog(LOG_CMDS, "*", "(%s!%s) !*! IDENT %s", nick, host, who);
      simple_snprintf(s, sizeof s, "%s!%s", nick, host);
      maskaddr(s, s1, 0); /* *!user@host */
      msg = bd::String::printf("Added hostmask: %s", s1);
      notice(nick, msg.c_str(), DP_HELP);
      addhost_by_handle(who, s1);
      check_this_user(who, 0, NULL);
      return BIND_RET_BREAK;
    }
  }
  putlog(LOG_CMDS, "*", "(%s!%s) !*! failed IDENT %s", nick, host, who);
  return BIND_RET_BREAK;
}
예제 #12
0
파일: msgcmds.c 프로젝트: vap0r/wraith
static int msg_invite(char *nick, char *host, struct userrec *u, char *par)
{
  char *pass = NULL;
  struct chanset_t *chan = NULL;
  struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0 };

  if (match_my_nick(nick))
    return BIND_RET_BREAK;

  pass = newsplit(&par);
  if (u_pass_match(u, pass) && !u_pass_match(u, "-")) {
    if (par[0] == '*') {
      for (chan = chanset; chan; chan = chan->next) {
	get_user_flagrec(u, &fr, chan->dname, chan);
        if (chk_op(fr, chan) && (chan->channel.mode & CHANINV)) {
          cache_invite(chan, nick, host, u->handle, 0, 0);
        }
      }
      putlog(LOG_CMDS, "*", "(%s!%s) !%s! INVITE ALL", nick, host, u->handle);
      return BIND_RET_BREAK;
    }
    bd::String msg;
    if (!(chan = findchan_by_dname(par))) {
      msg = bd::String::printf("Usage: /MSG %s %s <pass> <channel>", botname, msginvite);
      notice(nick, msg.c_str(), DP_HELP);
      return BIND_RET_BREAK;
    }
    if (!channel_active(chan)) {
      msg = bd::String::printf("%s: Not on that channel right now.", par);
      notice(nick, msg.c_str(), DP_HELP);
      return BIND_RET_BREAK;
    }
    /* We need to check access here also (dw 991002) */
    get_user_flagrec(u, &fr, par, chan);
    if (chk_op(fr, chan)) {
      cache_invite(chan, nick, host, u->handle, 0, 0);
      putlog(LOG_CMDS, "*", "(%s!%s) !%s! INVITE %s", nick, host, u->handle, par);
      return BIND_RET_BREAK;
    }
  }
  putlog(LOG_CMDS, "*", "(%s!%s) !%s! failed INVITE %s", nick, host, (u ? u->handle : "*"), par);
  return BIND_RET_BREAK;
}
예제 #13
0
static void got_key(struct chanset_t *chan, char *nick, char *from, char *key)
{
  if (!nick[0] && bounce_modes)
    reversing = 1;

  if (!(glob_master(user) || glob_bot(user) || chan_master(user)) &&
      !match_my_nick(nick)) {
    if ((reversing && !chan->key_prot[0]) || (chan->mode_mns_prot & CHANKEY)) {
      if (strlen(key) != 0)
        add_mode(chan, '-', 'k', key);
      else
        add_mode(chan, '-', 'k', "");
    }
    if ((chan->mode_pls_prot & CHANKEY) && (chan->key_prot[0] != 0) &&
        strcmp(key, chan->key_prot)) {
      add_mode(chan, '+', 'k', chan->key_prot);
    }
  }
}
예제 #14
0
/* Got nick change.
 */
static int gotnick(char *from, char *msg)
{
  char *nick, *alt = get_altbotnick();

  nick = splitnick(&from);
  fixcolon(msg);
  check_queues(nick, msg);
  if (match_my_nick(nick)) {
    /* Regained nick! */
    strncpyz(botname, msg, NICKLEN);
    altnick_char = 0;
    if (!strcmp(msg, origbotname)) {
      putlog(LOG_SERV | LOG_MISC, "*", "Regained nickname '%s'.", msg);
      nick_juped = 0;
    } else if (alt[0] && !strcmp(msg, alt))
      putlog(LOG_SERV | LOG_MISC, "*", "Regained alternate nickname '%s'.",
             msg);
    else if (keepnick && strcmp(nick, msg)) {
      putlog(LOG_SERV | LOG_MISC, "*", "Nickname changed to '%s'???", msg);
      if (!rfc_casecmp(nick, origbotname)) {
        putlog(LOG_MISC, "*", IRC_GETORIGNICK, origbotname);
        dprintf(DP_SERVER, "NICK %s\n", origbotname);
      } else if (alt[0] && !rfc_casecmp(nick, alt) &&
               egg_strcasecmp(botname, origbotname)) {
        putlog(LOG_MISC, "*", IRC_GETALTNICK, alt);
        dprintf(DP_SERVER, "NICK %s\n", alt);
      }
    } else
      putlog(LOG_SERV | LOG_MISC, "*", "Nickname changed to '%s'???", msg);
  } else if ((keepnick) && (rfc_casecmp(nick, msg))) {
    /* Only do the below if there was actual nick change, case doesn't count */
    if (!rfc_casecmp(nick, origbotname)) {
      putlog(LOG_MISC, "*", IRC_GETORIGNICK, origbotname);
      dprintf(DP_SERVER, "NICK %s\n", origbotname);
    } else if (alt[0] && !rfc_casecmp(nick, alt) &&
             egg_strcasecmp(botname, origbotname)) {
      putlog(LOG_MISC, "*", IRC_GETALTNICK, altnick);
      dprintf(DP_SERVER, "NICK %s\n", altnick);
    }
  }
  return 0;
}
예제 #15
0
static int gotmode(char *from, char *msg)
{
  char *ch;

  ch = newsplit(&msg);
  /* Usermode changes? */
  if (strchr(CHANMETA, ch[0]) == NULL) {
    if (match_my_nick(ch) && check_mode_r) {
      /* umode +r? - D0H dalnet uses it to mean something different */
      fixcolon(msg);
      if ((msg[0] == '+') && strchr(msg, 'r')) {
        int servidx = findanyidx(serv);

        putlog(LOG_MISC | LOG_JOIN, "*",
               "%s has me i-lined (jumping)", dcc[servidx].host);
        nuke_server("i-lines suck");
      }
    }
  }
  return 0;
}
예제 #16
0
파일: irc.c 프로젝트: Estella/eggdrop-1.8
/* Punishes bad guys under certain circumstances using methods as defined
 * by the revenge_mode flag.
 */
static void maybe_revenge(struct chanset_t *chan, char *whobad,
                          char *whovictim, int type)
{
    char *badnick, *victim;
    int mevictim;
    struct userrec *u, *u2;

    if (!chan || (type < 0))
        return;

    /* Get info about offender */
    u = get_user_by_host(whobad);
    badnick = splitnick(&whobad);

    /* Get info about victim */
    u2 = get_user_by_host(whovictim);
    victim = splitnick(&whovictim);
    mevictim = match_my_nick(victim);

    /* Do we want to revenge? */
    if (want_to_revenge(chan, u, u2, badnick, victim, mevictim))
        punish_badguy(chan, whobad, u, badnick, victim, mevictim, type);
}
예제 #17
0
파일: msgcmds.c 프로젝트: vap0r/wraith
static int msg_auth(char *nick, char *host, struct userrec *u, char *par)
{ 
  char *pass = NULL;

  if (match_my_nick(nick))
    return BIND_RET_BREAK;
  if (u && u->bot)
    return BIND_RET_BREAK;

  Auth *auth = Auth::Find(host);

  if (!auth || auth->Status() != AUTH_PASS)
    return BIND_RET_BREAK;

  pass = newsplit(&par);

  if (u_pass_match(u, pass) && !u_pass_match(u, "-")) {
    auth->user = u;
    if (strlen(auth_key) && get_user(&USERENTRY_SECPASS, u)) {
      putlog(LOG_CMDS, "*", STR("(%s!%s) !%s! AUTH"), nick, host, u->handle);
      auth->Status(AUTH_HASH);
      auth->MakeHash();
      bd::String msg;
      msg = bd::String::printf(STR("-Auth %s %s"), auth->rand, conf.bot->nick);
      privmsg(nick, msg.c_str(), DP_HELP);
    } else {
      /* no auth_key and/or no SECPASS for the user, don't require a hash auth */
      AuthFinish(auth);
    }
  } else {
    putlog(LOG_CMDS, "*", STR("(%s!%s) !%s! failed AUTH"), nick, host, u->handle);
    delete auth;
  }
  return BIND_RET_BREAK;

}
예제 #18
0
/* Do on NICK, PRIVMSG, NOTICE and JOIN.
 */
static int detect_flood(char *floodnick, char *floodhost, char *from, int which)
{
  char *p, ftype[10], h[1024];
  struct userrec *u;
  int thr = 0, lapse = 0, atr;

  /* Okay, make sure i'm not flood-checking myself */
  if (match_my_nick(floodnick))
    return 0;

  /* My user@host (?) */
  if (!egg_strcasecmp(floodhost, botuserhost))
    return 0;

  u = get_user_by_host(from);
  atr = u ? u->flags : 0;
  if (atr & (USER_BOT | USER_FRIEND))
    return 0;

  /* Determine how many are necessary to make a flood */
  switch (which) {
  case FLOOD_PRIVMSG:
  case FLOOD_NOTICE:
    thr = flud_thr;
    lapse = flud_time;
    strcpy(ftype, "msg");
    break;
  case FLOOD_CTCP:
    thr = flud_ctcp_thr;
    lapse = flud_ctcp_time;
    strcpy(ftype, "ctcp");
    break;
  }
  if ((thr == 0) || (lapse == 0))
    return 0;                   /* No flood protection */

  p = strchr(floodhost, '@');
  if (p) {
    p++;
    if (egg_strcasecmp(lastmsghost[which], p)) {        /* New */
      strcpy(lastmsghost[which], p);
      lastmsgtime[which] = now;
      lastmsgs[which] = 0;
      return 0;
    }
  } else
    return 0;                   /* Uh... whatever. */

  if (lastmsgtime[which] < now - lapse) {
    /* Flood timer expired, reset it */
    lastmsgtime[which] = now;
    lastmsgs[which] = 0;
    return 0;
  }
  lastmsgs[which]++;
  if (lastmsgs[which] >= thr) { /* FLOOD */
    /* Reset counters */
    lastmsgs[which] = 0;
    lastmsgtime[which] = 0;
    lastmsghost[which][0] = 0;
    u = get_user_by_host(from);
    if (check_tcl_flud(floodnick, floodhost, u, ftype, "*"))
      return 0;
    /* Private msg */
    simple_sprintf(h, "*!*@%s", p);
    putlog(LOG_MISC, "*", IRC_FLOODIGNORE1, p);
    addignore(h, botnetnick, (which == FLOOD_CTCP) ? "CTCP flood" :
              "MSG/NOTICE flood", now + (60 * ignore_time));
  }
  return 0;
}
예제 #19
0
static int gotmode(char *from, char *origmsg)
{
  char *nick, *ch, *op, *chg, *msg;
  char s[UHOSTLEN], buf[511];
  char ms2[3];
  int z;
  struct userrec *u;
  memberlist *m;
  struct chanset_t *chan;

  strncpy(buf, origmsg, 510);
  buf[510] = 0;
  msg = buf;
  /* Usermode changes? */
  if (msg[0] && (strchr(CHANMETA, msg[0]) != NULL)) {
    ch = newsplit(&msg);
    chg = newsplit(&msg);
    reversing = 0;
    chan = findchan(ch);
    if (!chan) {
      putlog(LOG_MISC, "*", CHAN_FORCEJOIN, ch);
      dprintf(DP_SERVER, "PART %s\n", ch);
    } else if (channel_active(chan) || channel_pending(chan)) {
      z = strlen(msg);
      if (msg[--z] == ' ')      /* I hate cosmetic bugs :P -poptix */
        msg[z] = 0;
      putlog(LOG_MODES, chan->dname, "%s: mode change '%s %s' by %s", ch, chg,
             msg, from);
      u = get_user_by_host(from);
      get_user_flagrec(u, &user, ch);
      nick = splitnick(&from);
      m = ismember(chan, nick);
      if (m)
        m->last = now;
      if (m && channel_active(chan) && (me_op(chan) || (me_halfop(chan) &&
          !chan_hasop(m))) && !(glob_friend(user) || chan_friend(user) ||
          (channel_dontkickops(chan) && (chan_op(user) || (glob_op(user) &&
          !chan_deop(user))))) && !match_my_nick(nick)) {
        if (chan_fakeop(m) || chan_fakehalfop(m)) {
          putlog(LOG_MODES, ch, CHAN_FAKEMODE, ch);
          dprintf(DP_MODE, "KICK %s %s :%s\n", ch, nick, CHAN_FAKEMODE_KICK);
          m->flags |= SENTKICK;
          reversing = 1;
        } else if (!chan_hasop(m) && !chan_hashalfop(m) &&
                 !channel_nodesynch(chan)) {
          putlog(LOG_MODES, ch, CHAN_DESYNCMODE, ch);
          dprintf(DP_MODE, "KICK %s %s :%s\n", ch, nick, CHAN_DESYNCMODE_KICK);
          m->flags |= SENTKICK;
          reversing = 1;
        }
      }
      ms2[0] = '+';
      ms2[2] = 0;
      while ((ms2[1] = *chg)) {
        int todo = 0;

        switch (*chg) {
        case '+':
          ms2[0] = '+';
          break;
        case '-':
          ms2[0] = '-';
          break;
        case 'i':
          todo = CHANINV;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'p':
          todo = CHANPRIV;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 's':
          todo = CHANSEC;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'm':
          todo = CHANMODER;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'c':
          todo = CHANNOCLR;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'C':
          todo = CHANNOCTCP;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'R':
          todo = CHANREGON;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'M':
          todo = CHANMODREG;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'r':
          todo = CHANLONLY;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'D':
          todo = CHANDELJN;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'u':
          todo = CHANSTRIP;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'N':
          todo = CHANNONOTC;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'T':
          todo = CHANNOAMSG;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'd':
          todo = CHANINVIS;
          break;
        case 't':
          todo = CHANTOPIC;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'n':
          todo = CHANNOMSG;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'a':
          todo = CHANANON;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'q':
          todo = CHANQUIET;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'l':
          if (!nick[0] && bounce_modes)
            reversing = 1;
          if (ms2[0] == '-') {
            check_tcl_mode(nick, from, u, chan->dname, ms2, "");
            /* The Tcl proc might have modified/removed the chan or user */
            if (!(chan = modebind_refresh(ch, from, &user, NULL, NULL)))
              return 0;
            if (channel_active(chan)) {
              if (reversing && (chan->channel.maxmembers != 0)) {
                simple_sprintf(s, "%d", chan->channel.maxmembers);
                add_mode(chan, '+', 'l', s);
              } else if ((chan->limit_prot != 0) && !glob_master(user) &&
                         !chan_master(user) && !match_my_nick(nick)) {
                simple_sprintf(s, "%d", chan->limit_prot);
                add_mode(chan, '+', 'l', s);
              }
            }
            chan->channel.maxmembers = 0;
          } else {
            op = newsplit(&msg);
            fixcolon(op);
            if (op == '\0')
              break;
            chan->channel.maxmembers = atoi(op);
            check_tcl_mode(nick, from, u, chan->dname, ms2,
                           int_to_base10(chan->channel.maxmembers));
            /* The Tcl proc might have modified/removed the chan or user */
            if (!(chan = modebind_refresh(ch, from, &user, NULL, NULL)))
              return 0;
            if (channel_pending(chan))
              break;
            if ((reversing && !(chan->mode_pls_prot & CHANLIMIT)) ||
                ((chan->mode_mns_prot & CHANLIMIT) && !glob_master(user) &&
                !chan_master(user)))
              add_mode(chan, '-', 'l', "");
            if ((chan->limit_prot != chan->channel.maxmembers) &&
                (chan->mode_pls_prot & CHANLIMIT) && (chan->limit_prot != 0) &&
                !glob_master(user) && !chan_master(user)) {
              simple_sprintf(s, "%d", chan->limit_prot);
              add_mode(chan, '+', 'l', s);
            }
          }
          break;
        case 'k':
          if (ms2[0] == '+')
            chan->channel.mode |= CHANKEY;
          else
            chan->channel.mode &= ~CHANKEY;
          op = newsplit(&msg);
          fixcolon(op);
          if (op == '\0') {
            break;
          }
          check_tcl_mode(nick, from, u, chan->dname, ms2, op);
          /* The Tcl proc might have modified/removed the chan or user */
          if (!(chan = modebind_refresh(ch, from, &user, NULL, NULL)))
            return 0;
          if (ms2[0] == '+') {
            set_key(chan, op);
            if (channel_active(chan))
              got_key(chan, nick, from, op);
          } else {
            if (channel_active(chan)) {
              if (reversing && chan->channel.key[0])
                add_mode(chan, '+', 'k', chan->channel.key);
              else if (chan->key_prot[0] && !glob_master(user) &&
                       !chan_master(user) && !match_my_nick(nick))
                add_mode(chan, '+', 'k', chan->key_prot);
            }
            set_key(chan, NULL);
          }
          break;
        case 'o':
          op = newsplit(&msg);
          fixcolon(op);
          if (ms2[0] == '+')
            got_op(chan, nick, from, op, u, &user);
          else
            got_deop(chan, nick, from, op, u);
          break;
        case 'h':
          op = newsplit(&msg);
          fixcolon(op);
          if (ms2[0] == '+')
            got_halfop(chan, nick, from, op, u, &user);
          else
            got_dehalfop(chan, nick, from, op, u);
          break;
        case 'v':
          op = newsplit(&msg);
          fixcolon(op);
          m = ismember(chan, op);
          if (!m) {
            if (channel_pending(chan))
              break;
            putlog(LOG_MISC, chan->dname, CHAN_BADCHANMODE, chan->dname, op);
            chan->status |= CHAN_PEND;
            refresh_who_chan(chan->name);
          } else {
            simple_sprintf(s, "%s!%s", m->nick, m->userhost);
            get_user_flagrec(m->user ? m->user : get_user_by_host(s),
                             &victim, chan->dname);
            if (ms2[0] == '+') {
              m->flags &= ~SENTVOICE;
              m->flags |= CHANVOICE;
              check_tcl_mode(nick, from, u, chan->dname, ms2, op);
              if (!(chan = modebind_refresh(ch, from, &user, s, &victim)))
                return 0;
              if (channel_active(chan) && !glob_master(user) &&
                  !chan_master(user) && !match_my_nick(nick)) {
                if (chan_quiet(victim) ||
                    (glob_quiet(victim) && !chan_voice(victim)))
                  add_mode(chan, '-', 'v', op);
                else if (reversing)
                  add_mode(chan, '-', 'v', op);
              }
            } else {
              m->flags &= ~SENTDEVOICE;
              m->flags &= ~CHANVOICE;
              check_tcl_mode(nick, from, u, chan->dname, ms2, op);
              if (!(chan = modebind_refresh(ch, from, &user, s, &victim)))
                return 0;
              if (channel_active(chan) && !glob_master(user) &&
                  !chan_master(user) && !match_my_nick(nick)) {
                if ((channel_autovoice(chan) && !chan_quiet(victim) &&
                    (chan_voice(victim) || glob_voice(victim))) ||
                    (!chan_quiet(victim) && (glob_gvoice(victim) ||
                    chan_gvoice(victim))))
                  add_mode(chan, '+', 'v', op);
                else if (reversing)
                  add_mode(chan, '+', 'v', op);
              }
            }
          }
          break;
        case 'b':
          op = newsplit(&msg);
          fixcolon(op);
          if (ms2[0] == '+')
            got_ban(chan, nick, from, op, ch, u);
          else
            got_unban(chan, nick, from, op, ch, u);
          break;
        case 'e':
          op = newsplit(&msg);
          fixcolon(op);
          if (ms2[0] == '+')
            got_exempt(chan, nick, from, op, ch, u);
          else
            got_unexempt(chan, nick, from, op, ch, u);
          break;
        case 'I':
          op = newsplit(&msg);
          fixcolon(op);
          if (ms2[0] == '+')
            got_invite(chan, nick, from, op, ch, u);
          else
            got_uninvite(chan, nick, from, op, ch, u);
          break;
        }
        if (todo) {
          check_tcl_mode(nick, from, u, chan->dname, ms2, "");
          if (!(chan = modebind_refresh(ch, from, &user, NULL, NULL)))
            return 0;
          if (ms2[0] == '+')
            chan->channel.mode |= todo;
          else
            chan->channel.mode &= ~todo;
          if (channel_active(chan)) {
            if ((((ms2[0] == '+') && (chan->mode_mns_prot & todo)) ||
                ((ms2[0] == '-') && (chan->mode_pls_prot & todo))) &&
                !glob_master(user) && !chan_master(user) &&
                !match_my_nick(nick))
              add_mode(chan, ms2[0] == '+' ? '-' : '+', *chg, "");
            else if (reversing && ((ms2[0] == '+') ||
                     (chan->mode_pls_prot & todo)) && ((ms2[0] == '-') ||
                     (chan->mode_mns_prot & todo)))
              add_mode(chan, ms2[0] == '+' ? '-' : '+', *chg, "");
          }
        }
        chg++;
      }
      if (!me_op(chan) && !nick[0])
        chan->status |= CHAN_ASKEDMODES;
    }
  }
  return 0;
}
예제 #20
0
파일: irc.c 프로젝트: Estella/eggdrop-1.8
static void check_expired_chanstuff()
{
    masklist *b, *e;
    memberlist *m, *n;
    char *key, s[UHOSTLEN];
    struct chanset_t *chan;
    struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 };

    if (!server_online)
        return;
    for (chan = chanset; chan; chan = chan->next) {
        if (channel_active(chan)) {
            if (me_op(chan) || me_halfop(chan)) {
                if (channel_dynamicbans(chan) && chan->ban_time)
                    for (b = chan->channel.ban; b->mask[0]; b = b->next)
                        if (now - b->timer > 60 * chan->ban_time &&
                                !u_sticky_mask(chan->bans, b->mask) &&
                                !u_sticky_mask(global_bans, b->mask) &&
                                expired_mask(chan, b->who)) {
                            putlog(LOG_MODES, chan->dname,
                                   "(%s) Channel ban on %s expired.", chan->dname, b->mask);
                            add_mode(chan, '-', 'b', b->mask);
                            b->timer = now;
                        }

                if (use_exempts && channel_dynamicexempts(chan) && chan->exempt_time)
                    for (e = chan->channel.exempt; e->mask[0]; e = e->next)
                        if (now - e->timer > 60 * chan->exempt_time &&
                                !u_sticky_mask(chan->exempts, e->mask) &&
                                !u_sticky_mask(global_exempts, e->mask) &&
                                expired_mask(chan, e->who)) {
                            /* Check to see if it matches a ban */
                            int match = 0;

                            for (b = chan->channel.ban; b->mask[0]; b = b->next)
                                if (mask_match(b->mask, e->mask)) {
                                    match = 1;
                                    break;
                                }
                            /* Leave this extra logging in for now. Can be removed later
                             * Jason
                             */
                            if (match) {
                                putlog(LOG_MODES, chan->dname,
                                       "(%s) Channel exemption %s NOT expired. Exempt still set!",
                                       chan->dname, e->mask);
                            } else {
                                putlog(LOG_MODES, chan->dname,
                                       "(%s) Channel exemption on %s expired.",
                                       chan->dname, e->mask);
                                add_mode(chan, '-', 'e', e->mask);
                            }
                            e->timer = now;
                        }

                if (use_invites && channel_dynamicinvites(chan) &&
                        chan->invite_time && !(chan->channel.mode & CHANINV))
                    for (b = chan->channel.invite; b->mask[0]; b = b->next)
                        if (now - b->timer > 60 * chan->invite_time &&
                                !u_sticky_mask(chan->invites, b->mask) &&
                                !u_sticky_mask(global_invites, b->mask) &&
                                expired_mask(chan, b->who)) {
                            putlog(LOG_MODES, chan->dname,
                                   "(%s) Channel invitation on %s expired.",
                                   chan->dname, b->mask);
                            add_mode(chan, '-', 'I', b->mask);
                            b->timer = now;
                        }

                if (chan->idle_kick)
                    for (m = chan->channel.member; m && m->nick[0]; m = m->next)
                        if (now - m->last >= chan->idle_kick * 60 &&
                                !match_my_nick(m->nick) && !chan_issplit(m)) {
                            sprintf(s, "%s!%s", m->nick, m->userhost);
                            get_user_flagrec(m->user ? m->user : get_user_by_host(s),
                                             &fr, chan->dname);
                            if ((!(glob_bot(fr) || glob_friend(fr) || (glob_op(fr) &&
                                    !chan_deop(fr)) || chan_friend(fr) || chan_op(fr))) &&
                                    (me_op(chan) || (me_halfop(chan) && !chan_hasop(m)))) {
                                dprintf(DP_SERVER, "KICK %s %s :idle %d min\n", chan->name,
                                        m->nick, chan->idle_kick);
                                m->flags |= SENTKICK;
                            }
                        }
            }
            for (m = chan->channel.member; m && m->nick[0]; m = n) {
                n = m->next;
                if (m->split && now - m->split > wait_split) {
                    sprintf(s, "%s!%s", m->nick, m->userhost);
                    check_tcl_sign(m->nick, m->userhost,
                                   m->user ? m->user : get_user_by_host(s),
                                   chan->dname, "lost in the netsplit");
                    putlog(LOG_JOIN, chan->dname,
                           "%s (%s) got lost in the net-split.", m->nick, m->userhost);
                    killmember(chan, m->nick);
                }
                m = n;
            }
            check_lonely_channel(chan);
        } else if (!channel_inactive(chan) && !channel_pending(chan)) {

            key = chan->channel.key[0] ? chan->channel.key : chan->key_prot;
            if (key[0])
                dprintf(DP_SERVER, "JOIN %s %s\n",
                        chan->name[0] ? chan->name : chan->dname, key);
            else
                dprintf(DP_SERVER, "JOIN %s\n",
                        chan->name[0] ? chan->name : chan->dname);
        }
    }
}
예제 #21
0
파일: irc.c 프로젝트: Estella/eggdrop-1.8
/* 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);
        }
    }
}
예제 #22
0
static void got_ban(struct chanset_t *chan, char *nick, char *from, char *who,
                    char *ch, struct userrec *u)
{
  char me[UHOSTLEN], s[UHOSTLEN], s1[UHOSTLEN];
  memberlist *m;
  struct userrec *targ;

  egg_snprintf(me, sizeof me, "%s!%s", botname, botuserhost);
  egg_snprintf(s, sizeof s, "%s!%s", nick, from);
  newban(chan, who, s);
  check_tcl_mode(nick, from, u, chan->dname, "+b", who);
  if (!(chan = modebind_refresh(ch, from, &user, NULL, NULL)))
    return;

  if (channel_pending(chan) || HALFOP_CANTDOMODE('b'))
    return;

  if (match_addr(who, me) && !isexempted(chan, me)) {
    add_mode(chan, '-', 'b', who);
    reversing = 1;
    return;
  }
  if (!match_my_nick(nick)) {
    if (nick[0] && channel_nouserbans(chan) && !glob_bot(user) &&
        !glob_master(user) && !chan_master(user)) {
      add_mode(chan, '-', 'b', who);
      return;
    }
    for (m = chan->channel.member; m && m->nick[0]; m = m->next) {
      egg_snprintf(s1, sizeof s1, "%s!%s", m->nick, m->userhost);
      if (match_addr(who, s1)) {
        targ = get_user_by_host(s1);
        if (targ) {
          get_user_flagrec(targ, &victim, chan->dname);
          if ((glob_friend(victim) || (glob_op(victim) && !chan_deop(victim)) ||
               chan_friend(victim) || chan_op(victim)) && !glob_master(user) &&
              !glob_bot(user) && !chan_master(user) && !isexempted(chan, s1)) {
            add_mode(chan, '-', 'b', who);
            return;
          }
        }
      }
    }
  }
  refresh_exempt(chan, who);
  if (nick[0] && channel_enforcebans(chan)) {
    register maskrec *b;
    int cycle;
    char resn[512] = "";

    for (cycle = 0; cycle < 2; cycle++) {
      for (b = cycle ? chan->bans : global_bans; b; b = b->next) {
        if (match_addr(b->mask, who)) {
          if (b->desc && b->desc[0] != '@')
            egg_snprintf(resn, sizeof resn, "%s %s", IRC_PREBANNED, b->desc);
          else
            resn[0] = 0;
        }
      }
    }
    kick_all(chan, who, resn[0] ? resn : IRC_BANNED,
             match_my_nick(nick) ? 0 : 1);
  }
  if (!nick[0] && (bounce_bans || bounce_modes) &&
      (!u_equals_mask(global_bans, who) || !u_equals_mask(chan->bans, who)))
    add_mode(chan, '-', 'b', who);
}
예제 #23
0
static void got_dehalfop(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 &= ~(CHANHALFOP | SENTDEHALFOP | FAKEHALFOP);
  check_tcl_mode(nick, from, opu, chan->dname, "-h", who);
  if (!(chan = modebind_refresh(ch, from, &user, s, &victim)) ||
      !(m = ismember(chan, who)))
    return;
  /* Check comments in got_op()  (drummer) */
  m->flags &= ~WASHALFOP;

  if (channel_pending(chan))
    return;

  /* Dehalfop'd someone on my oplist? */
  if (HALFOP_CANDOMODE('h')) {
    int ok = 1;

    if (!glob_dehalfop(victim) && !chan_dehalfop(victim)) {
      if (channel_protecthalfops(chan) && (glob_master(victim) ||
          chan_master(victim) || glob_halfop(victim) || chan_halfop(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_halfop(victim) ||
        (glob_halfop(victim) && !chan_dehalfop(victim))) ||
        !channel_bitch(chan)))
      add_mode(chan, '+', 'h', who);
  }

  if (!nick[0])
    putlog(LOG_MODES, chan->dname, "TS resync (%s): %s deopped by %s",
           chan->dname, who, from);
  if (!(m->flags & (CHANVOICE | STOPWHO))) {
    chan->status |= CHAN_PEND;
    refresh_who_chan(chan->name);
    m->flags |= STOPWHO;
  }
}
예제 #24
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);
}
예제 #25
0
파일: msgcmds.c 프로젝트: vap0r/wraith
static int msg_op(char *nick, char *host, struct userrec *u, char *par)
{
  struct chanset_t *chan = NULL;
  char *pass = NULL;
  struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0 };

  if (match_my_nick(nick))
    return BIND_RET_BREAK;
  pass = newsplit(&par);

  bd::String msg;

  if (homechan[0]) {
    struct chanset_t *hchan = NULL;

    hchan = findchan_by_dname(homechan);

    if (hchan && channel_active(hchan) && !ismember(hchan, nick)) {
      putlog(LOG_CMDS, "*", "(%s!%s) !*! failed OP %s (not in %s)", nick, host, par, homechan);
      if (par[0]) 
        msg = bd::String::printf("---- (%s!%s) attempted to OP for %s but is not currently in %s.", nick, host, par, homechan);
      else
        msg = bd::String::printf("---- (%s!%s) attempted to OP but is not currently in %s.", nick, host, homechan);
      privmsg(homechan, msg.c_str(), DP_SERVER);
      return BIND_RET_BREAK;
    }
  }

  if (u_pass_match(u, pass)) {
    if (!u_pass_match(u, "-")) {
      if (par[0]) {
        chan = findchan_by_dname(par);
        if (chan && channel_active(chan)) {
          get_user_flagrec(u, &fr, par, chan);
          if (chk_op(fr, chan)) {
            if (do_op(nick, chan, 0, 1)) {
              stats_add(u, 0, 1);
              putlog(LOG_CMDS, "*", "(%s!%s) !%s! OP %s", nick, host, u->handle, par);
              if (manop_warn && chan->manop) {
                msg = bd::String::printf("%s is currently set to punish for manual op.", chan->dname);
                notice(nick, msg.c_str(), DP_HELP);
              }
            }
          }
          return BIND_RET_BREAK;
        }
      } else {
        int stats = 0;
        for (chan = chanset; chan; chan = chan->next) {
          get_user_flagrec(u, &fr, chan->dname, chan);
          if (chk_op(fr, chan)) {
            if (do_op(nick, chan, 0, 1)) {
              stats++;
              if (manop_warn && chan->manop) {
                msg = bd::String::printf("%s is currently set to punish for manual op.", chan->dname);
                notice(nick, msg.c_str(), DP_HELP);
              }
            }
          }
        }
        putlog(LOG_CMDS, "*", "(%s!%s) !%s! OP", nick, host, u->handle);
        if (stats)
          stats_add(u, 0, 1);
        return BIND_RET_BREAK;
      }
    }
  }
  putlog(LOG_CMDS, "*", "(%s!%s) !*! failed OP", nick, host);
  return BIND_RET_BREAK;
}
예제 #26
0
static void got_halfop(struct chanset_t *chan, char *nick, char *from,
                       char *who, struct userrec *opu,
                       struct flag_record *opper)
{
  memberlist *m;
  char s[UHOSTLEN];
  char ch[sizeof chan->name];
  struct userrec *u;
  int check_chan = 0;
  int snm = chan->stopnethack_mode;

  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;
  }

  /* Did *I* just get halfopped? */
  if (!me_op(chan) && !me_halfop(chan) && match_my_nick(who))
    check_chan = 1;

  strcpy(ch, chan->name);
  simple_sprintf(s, "%s!%s", m->nick, m->userhost);
  if (!m->user)
    u = get_user_by_host(s);
  else
    u = m->user;

  get_user_flagrec(u, &victim, chan->dname);
  /* Flags need to be set correctly right from the beginning now, so that
   * add_mode() doesn't get irritated.
   */
  m->flags |= CHANHALFOP;
  check_tcl_mode(nick, from, opu, chan->dname, "+h", who);
  if (!(chan = modebind_refresh(ch, from, opper, s, &victim)) ||
      !(m = ismember(chan, who)))
    return;
  m->flags &= ~SENTHALFOP;

  if (channel_pending(chan))
    return;

  if (nick[0] && HALFOP_CANDOMODE('h') && !match_my_nick(who) &&
      !match_my_nick(nick)) {
    if (channel_bitch(chan) && !(glob_master(*opper) || glob_bot(*opper)) &&
        !chan_master(*opper) && !(glob_halfop(victim) || glob_op(victim) ||
        glob_bot(victim)) && !chan_op(victim) && !chan_halfop(victim))
      add_mode(chan, '-', 'h', who);
    else if ((chan_dehalfop(victim) || (glob_dehalfop(victim) &&
             !chan_halfop(victim))) && !glob_master(*opper) &&
             !chan_master(*opper))
      add_mode(chan, '-', 'h', who);
    else if (reversing)
      add_mode(chan, '-', 'h', who);
  } else if (reversing && HALFOP_CANDOMODE('h') && !match_my_nick(who) &&
             !match_my_nick(nick))
    add_mode(chan, '-', 'h', who);
  if (!nick[0] && HALFOP_CANDOMODE('h') && !match_my_nick(who)) {
    if (chan_dehalfop(victim) || (glob_dehalfop(victim) &&
        !chan_halfop(victim))) {
      m->flags |= FAKEHALFOP;
      add_mode(chan, '-', 'h', who);
    } else if (snm > 0 && snm < 7 && !((channel_autohalfop(chan) ||
             glob_autohalfop(victim) || chan_autohalfop(victim)) &&
             (chan_halfop(victim) || (glob_halfop(victim) &&
             !chan_dehalfop(victim)))) && !glob_exempt(victim) &&
             !chan_exempt(victim)) {
      if (snm == 5)
        snm = channel_bitch(chan) ? 1 : 3;
      if (snm == 6)
        snm = channel_bitch(chan) ? 4 : 2;
      if (chan_washalfoptest(victim) || glob_washalfoptest(victim) || snm == 2) {
        if (!chan_washalfop(m)) {
          m->flags |= FAKEHALFOP;
          add_mode(chan, '-', 'h', who);
        }
      } else if (!(chan_halfop(victim) || (glob_halfop(victim) &&
               !chan_dehalfop(victim)))) {
        if (snm == 1 || snm == 4 || (snm == 3 && !chan_washalfop(m))) {
          add_mode(chan, '-', 'h', who);
          m->flags |= FAKEHALFOP;
        }
      } else if (snm == 4 && !chan_washalfop(m)) {
        add_mode(chan, '-', 'h', who);
        m->flags |= FAKEHALFOP;
      }
    }
  }
  m->flags |= WASHALFOP;
  if (check_chan)
    recheck_channel(chan, 1);
}
예제 #27
0
/* match_my_nick() is a macro so we can't put it right into the script command table. */
static int script_isbotnick(char *nick)
{
	return match_my_nick(nick);
}