示例#1
0
文件: irc.c 项目: Estella/eggdrop-1.8
static int check_tcl_pub(char *nick, char *from, char *chname, char *msg)
{
    struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 };
    int x;
    char buf[512], *args = buf, *cmd, host[161], *hand;
    struct userrec *u;

    strcpy(args, msg);
    cmd = newsplit(&args);
    simple_sprintf(host, "%s!%s", nick, from);
    u = get_user_by_host(host);
    hand = u ? u->handle : "*";
    get_user_flagrec(u, &fr, chname);
    Tcl_SetVar(interp, "_pub1", nick, 0);
    Tcl_SetVar(interp, "_pub2", from, 0);
    Tcl_SetVar(interp, "_pub3", hand, 0);
    Tcl_SetVar(interp, "_pub4", chname, 0);
    Tcl_SetVar(interp, "_pub5", args, 0);
    x = check_tcl_bind(H_pub, cmd, &fr, " $_pub1 $_pub2 $_pub3 $_pub4 $_pub5",
                       MATCH_EXACT | BIND_USE_ATTR | BIND_HAS_BUILTINS);
    if (x == BIND_NOMATCH)
        return 0;
    if (x == BIND_EXEC_LOG)
        putlog(LOG_CMDS, chname, "<<%s>> !%s! %s %s", nick, hand, cmd, args);
    return 1;
}
示例#2
0
文件: irc.c 项目: Estella/eggdrop-1.8
static int check_tcl_pubm(char *nick, char *from, char *chname, char *msg)
{
    struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 };
    int x;
    char buf[1024], host[161];
    struct userrec *u;

    simple_sprintf(buf, "%s %s", chname, msg);
    simple_sprintf(host, "%s!%s", nick, from);
    u = get_user_by_host(host);
    get_user_flagrec(u, &fr, chname);
    Tcl_SetVar(interp, "_pubm1", nick, 0);
    Tcl_SetVar(interp, "_pubm2", from, 0);
    Tcl_SetVar(interp, "_pubm3", u ? u->handle : "*", 0);
    Tcl_SetVar(interp, "_pubm4", chname, 0);
    Tcl_SetVar(interp, "_pubm5", msg, 0);
    x = check_tcl_bind(H_pubm, buf, &fr, " $_pubm1 $_pubm2 $_pubm3 $_pubm4 $_pubm5",
                       MATCH_MASK | BIND_USE_ATTR | BIND_STACKABLE | BIND_STACKRET);

    /*
     * 0 - no match
     * 1 - match, log
     * 2 - match, don't log
     */
    if (x == BIND_NOMATCH)
        return 0;
    if (x == BIND_EXEC_LOG)
        return 2;

    return 1;
}
示例#3
0
static void schan_members_update(struct stats_member *m, char *chan)
{
	char *host;
#ifndef NO_EGG
	struct userrec *u;
#endif

	m->user = NULL;
	host = nmalloc(strlen(m->nick) + 1 + strlen(m->uhost) + 1);
	sprintf(host, "%s!%s", m->nick, m->uhost);
#ifndef NO_EGG
	u = get_user_by_host(host);
	if (u) {
		m->user = findsuser_by_name(u->handle);
		if (!m->user) {
	  		m->user = addsuser(u->handle, now, now);
	  		debug1("Stats.Mod: Created suserrec for %s.", u->handle);
		}
	} else
#endif
		m->user = findsuser(host);
	nfree(host);
	if (m->user) {
		m->stats = findlocstats(chan, m->user->user);
		if (!m->stats)
			m->stats = initstats(chan, m->user->user);
	}
}
示例#4
0
/* This is called after a mode bind is processed. It will check if the
 * channel still exists and will refresh the user and victim flag records,
 * in case users were also modified.
 */
struct chanset_t *modebind_refresh(char *chname,
                                   char *usrhost, struct flag_record *usr,
                                   char *vcrhost, struct flag_record *vcr)
{
  struct userrec *u;
  struct chanset_t *chan;

  if (!chname || !(chan = findchan(chname)))
    return NULL;
  if (usrhost) {
    u = get_user_by_host(usrhost);
    get_user_flagrec(u, usr, chan->dname);
  }
  if (vcrhost) {
    u = get_user_by_host(vcrhost);
    get_user_flagrec(u, vcr, chan->dname);
  }
  return chan;
}
示例#5
0
文件: irc.c 项目: Estella/eggdrop-1.8
static int hand_on_chan(struct chanset_t *chan, struct userrec *u)
{
    char s[UHOSTLEN];
    memberlist *m;

    for (m = chan->channel.member; m && m->nick[0]; m = m->next) {
        sprintf(s, "%s!%s", m->nick, m->userhost);
        if (u == get_user_by_host(s))
            return 1;
    }
    return 0;
}
示例#6
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);
}
示例#7
0
/* Expire mask originally set by `who' on `chan'?
 *
 * We might not want to expire masks in all cases, as other bots
 * often tend to immediately reset masks they've listed in their
 * internal ban list, making it quite senseless for us to remove
 * them in the first place.
 *
 * Returns 1 if a mask on `chan' by `who' may be expired and 0 if
 * not.
 */
static int expired_mask(struct chanset_t *chan, char *who)
{
  memberlist *m, *m2;
  char buf[UHOSTLEN], *snick, *sfrom;
  struct userrec *u;

  /* Always expire masks, regardless of who set it? */
  if (force_expire)
    return 1;

  strcpy(buf, who);
  sfrom = buf;
  snick = splitnick(&sfrom);

  if (!snick[0])
    return 1;

  m = ismember(chan, snick);
  if (!m)
    for (m2 = chan->channel.member; m2 && m2->nick[0]; m2 = m2->next)
      if (!egg_strcasecmp(sfrom, m2->userhost)) {
        m = m2;
        break;
      }

  if (!m || !chan_hasop(m) || !rfc_casecmp(m->nick, botname))
    return 1;

  /* At this point we know the person/bot who set the mask is currently
   * present in the channel and has op.
   */

  if (m->user)
    u = m->user;
  else {
    simple_sprintf(buf, "%s!%s", m->nick, m->userhost);
    u = get_user_by_host(buf);
  }
  /* Do not expire masks set by bots. */
  if (u && u->flags & USER_BOT)
    return 0;
  else
    return 1;
}
示例#8
0
文件: notes.c 项目: ArNz8o8/Fr3shness
static void notes_hourly()
{
  expire_notes();
  if (notify_users) {
    register struct chanset_t *chan;
    register memberlist *m;
    int k;
    register int l;
    char s1[256];
    struct userrec *u;

    for (chan = chanset; chan; chan = chan->next) {
      for (m = chan->channel.member; m && m->nick[0]; m = m->next) {
        sprintf(s1, "%s!%s", m->nick, m->userhost);
        u = get_user_by_host(s1);
        if (u) {
          k = num_notes(u->handle);
          for (l = 0; l < dcc_total; l++)
            if ((dcc[l].type->flags & DCT_CHAT) &&
                !egg_strcasecmp(dcc[l].nick, u->handle)) {
              k = 0;            /* They already know they have notes */
              break;
            }
          if (k) {
            dprintf(DP_HELP, "NOTICE %s :You have %d note%s waiting on %s.\n",
                    m->nick, k, k == 1 ? "" : "s", botname);
            dprintf(DP_HELP, "NOTICE %s :%s /MSG %s NOTES <pass> INDEX\n",
                    m->nick, NOTES_FORLIST, botname);
          }
        }
      }
    }
    for (l = 0; l < dcc_total; l++) {
      k = num_notes(dcc[l].nick);
      if ((k > 0) && (dcc[l].type->flags & DCT_CHAT)) {
        dprintf(l, NOTES_WAITING2, k, (k == 1) ? "" : "s");
        dprintf(l, "### %s\n", (k != 1) ? NOTES_DCC_USAGE_READ : NOTES_DCC_USAGE_READ2);
      }
    }
  }
}
示例#9
0
/* Got a private message.
 */
static int gotmsg(char *from, char *msg)
{
  char *to, buf[UHOSTLEN], *nick, ctcpbuf[512], *uhost = buf, *ctcp,
       *p, *p1, *code;
  struct userrec *u;
  int ctcp_count = 0;
  int ignoring;

  /* Notice to a channel, not handled here */
  if (msg[0] && ((strchr(CHANMETA, *msg) != NULL) || (*msg == '@')))
    return 0;

  ignoring = match_ignore(from);
  to = newsplit(&msg);
  fixcolon(msg);
  strncpyz(uhost, from, sizeof(buf));
  nick = splitnick(&uhost);
 
  /* Check for CTCP: */
  ctcp_reply[0] = 0;
  p = strchr(msg, 1);
  while ((p != NULL) && (*p)) {
    p++;
    p1 = p;
    while ((*p != 1) && (*p != 0))
      p++;
    if (*p == 1) {
      *p = 0;
      strncpyz(ctcpbuf, p1, sizeof(ctcpbuf));
      ctcp = ctcpbuf;

      /* remove the ctcp in msg */
      memmove(p1 - 1, p + 1, strlen(p + 1) + 1);

      if (!ignoring)
        detect_flood(nick, uhost, from,
                     strncmp(ctcp, "ACTION ", 7) ? FLOOD_CTCP : FLOOD_PRIVMSG);
      /* Respond to the first answer_ctcp */
      p = strchr(msg, 1);
      if (ctcp_count < answer_ctcp) {
        ctcp_count++;
        if (ctcp[0] != ' ') {
          code = newsplit(&ctcp);

          /* CTCP from oper, don't interpret */
          if ((to[0] == '$') || strchr(to, '.')) {
            if (!ignoring)
              putlog(LOG_PUBLIC, to, "CTCP %s: %s from %s (%s) to %s",
                     code, ctcp, nick, uhost, to);
          } else {
            u = get_user_by_host(from);
            if (!ignoring || trigger_on_ignore) {
              if (!check_tcl_ctcp(nick, uhost, u, to, code, ctcp) && !ignoring) {
                if ((lowercase_ctcp && !egg_strcasecmp(code, "DCC")) ||
                    (!lowercase_ctcp && !strcmp(code, "DCC"))) {
                  /* If it gets this far unhandled, it means that
                   * the user is totally unknown.
                   */
                  code = newsplit(&ctcp);
                  if (!strcmp(code, "CHAT")) {
                    if (!quiet_reject) {
                      if (u)
                        dprintf(DP_HELP, "NOTICE %s :I'm not accepting calls "
                                "at the moment.\n", nick);
                      else
                        dprintf(DP_HELP, "NOTICE %s :%s\n", nick,
                                DCC_NOSTRANGERS);
                    }
                    putlog(LOG_MISC, "*", "%s: %s", DCC_REFUSED, from);
                  } else
                    putlog(LOG_MISC, "*", "Refused DCC %s: %s", code, from);
                }
              }
              if (!strcmp(code, "ACTION")) {
                putlog(LOG_MSGS, "*", "Action to %s: %s %s", to, nick, ctcp);
              } else {
                putlog(LOG_MSGS, "*", "CTCP %s: %s from %s (%s)", code, ctcp,
                       nick, uhost);
              }                 /* I love a good close cascade ;) */
            }
          }
        }
      }
    }
  }
  /* Send out possible ctcp responses */
  if (ctcp_reply[0]) {
    if (ctcp_mode != 2) {
      dprintf(DP_HELP, "NOTICE %s :%s\n", nick, ctcp_reply);
    } else {
      if (now - last_ctcp > flud_ctcp_time) {
        dprintf(DP_HELP, "NOTICE %s :%s\n", nick, ctcp_reply);
        count_ctcp = 1;
      } else if (count_ctcp < flud_ctcp_thr) {
        dprintf(DP_HELP, "NOTICE %s :%s\n", nick, ctcp_reply);
        count_ctcp++;
      }
      last_ctcp = now;
    }
  }
  if (msg[0]) {
    int result = 0;

    /* Msg from oper, don't interpret */
    if ((to[0] == '$') || (strchr(to, '.') != NULL)) {
      if (!ignoring) {
        detect_flood(nick, uhost, from, FLOOD_PRIVMSG);
        putlog(LOG_MSGS | LOG_SERV, "*", "[%s!%s to %s] %s",
               nick, uhost, to, msg);
      }
      return 0;
    }

    detect_flood(nick, uhost, from, FLOOD_PRIVMSG);
    u = get_user_by_host(from);
    code = newsplit(&msg);
    rmspace(msg);

    if (!ignoring || trigger_on_ignore) {
      result = check_tcl_msgm(code, nick, uhost, u, msg);

      if (!result || !exclusive_binds)
        if (check_tcl_msg(code, nick, uhost, u, msg))
          return 0;
    }

    if (!ignoring && result != 2)
      putlog(LOG_MSGS, "*", "[%s] %s %s", from, code, msg);
  }
  return 0;
}
示例#10
0
/* Got a private notice.
 */
static int gotnotice(char *from, char *msg)
{
  char *to, *nick, ctcpbuf[512], *p, *p1, buf[512], *uhost = buf, *ctcp;
  struct userrec *u;
  int ignoring;

  /* Notice to a channel, not handled here */
  if (msg[0] && ((strchr(CHANMETA, *msg) != NULL) || (*msg == '@')))
    return 0;

  ignoring = match_ignore(from);
  to = newsplit(&msg);
  fixcolon(msg);
  strcpy(uhost, from);
  nick = splitnick(&uhost);

  /* Check for CTCP: */
  p = strchr(msg, 1);
  while ((p != NULL) && (*p)) {
    p++;
    p1 = p;
    while ((*p != 1) && (*p != 0))
      p++;
    if (*p == 1) {
      *p = 0;
      ctcp = strcpy(ctcpbuf, p1);
      strcpy(p1 - 1, p + 1);
      if (!ignoring)
        detect_flood(nick, uhost, from, FLOOD_CTCP);
      p = strchr(msg, 1);
      if (ctcp[0] != ' ') {
        char *code = newsplit(&ctcp);

        /* CTCP reply from oper, don't interpret */
        if ((to[0] == '$') || strchr(to, '.')) {
          if (!ignoring)
            putlog(LOG_PUBLIC, "*",
                   "CTCP reply %s: %s from %s (%s) to %s", code, ctcp,
                   nick, uhost, to);
        } else {
          u = get_user_by_host(from);
          if (!ignoring || trigger_on_ignore) {
            check_tcl_ctcr(nick, uhost, u, to, code, ctcp);
            if (!ignoring)
              /* Who cares? */
              putlog(LOG_MSGS, "*",
                     "CTCP reply %s: %s from %s (%s) to %s",
                     code, ctcp, nick, uhost, to);
          }
        }
      }
    }
  }
  if (msg[0]) {

    /* Notice from oper, don't interpret */
    if ((to[0] == '$') || (strchr(to, '.') != NULL)) {
      if (!ignoring) {
        detect_flood(nick, uhost, from, FLOOD_NOTICE);
        putlog(LOG_MSGS | LOG_SERV, "*", "-%s (%s) to %s- %s",
               nick, uhost, to, msg);
      }
      return 0;
    }

    /* Server notice? */
    if ((nick[0] == 0) || (uhost[0] == 0)) {

      /* Hidden `250' connection count message from server */
      if (strncmp(msg, "Highest connection count:", 25))
        putlog(LOG_SERV, "*", "-NOTICE- %s", msg);

      return 0;
    }

    detect_flood(nick, uhost, from, FLOOD_NOTICE);
    u = get_user_by_host(from);

    if (!ignoring || trigger_on_ignore)
      if (check_tcl_notc(nick, uhost, u, botname, msg) == 2)
        return 0;

    if (!ignoring)
      putlog(LOG_MSGS, "*", "-%s (%s)- %s", nick, uhost, msg);
  }
  return 0;
}
示例#11
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);
}
示例#12
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;
}
示例#13
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);
        }
    }
}
示例#14
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);
}
示例#15
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);
        }
    }
}
示例#16
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;
  }
}
示例#17
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;
}
示例#18
0
文件: seen.c 项目: Abysim/NyanLion
static void do_seen(int idx, char *prefix, char *nick, char *hand,
                    char *channel, char *text)
{
  char stuff[512], word1[512], word2[512], whotarget[512], object[512],
       whoredirect[512], *oix, *lastonplace = 0;
  struct userrec *urec;
  struct chanset_t *chan;
  struct laston_info *li;
  struct chanuserrec *cr;
  memberlist *m = NULL;
  int onchan = 0, i;
  long tv;
  time_t laston = 0, work;

  whotarget[0]   = 0;
  whoredirect[0] = 0;
  object[0]      = 0;

  /* Was ANYONE specified */
  if (!text[0]) {
    dprintf(idx, "%sUm, %s, it might help if you ask me about _someone_...\n",
            prefix, nick);
    return;
  }

  wordshift(word1, text);
  oix = strchr(word1, '\'');
  /* Have we got a NICK's target? */
  if (oix == word1)
    return;                     /* Skip anything starting with ' */
  if (oix && *oix && ((oix[1] && (oix[1] == 's' || oix[1] == 'S') &&
      !oix[2]) || (!oix[1] && (oix[-1] == 's' || oix[-1] == 'z' ||
      oix[-1] == 'x' || oix[-1] == 'S' || oix[-1] == 'Z' ||
      oix[-1] == 'X')))) {
    strncpy(object, word1, oix - word1);
    object[oix - word1] = 0;
    wordshift(word1, text);
    if (!word1[0]) {
      dprintf(idx, "%s%s's what, %s?\n", prefix, object, nick);
      return;
    }
    urec = get_user_by_handle(userlist, object);
    if (!urec) {
      chan = chanset;
      while (chan) {
        onchan = 0;
        m = ismember(chan, object);
        if (m) {
          onchan = 1;
          sprintf(stuff, "%s!%s", object, m->userhost);
          urec = get_user_by_host(stuff);
          if (!urec || !egg_strcasecmp(object, urec->handle))
            break;
          strcat(whoredirect, object);
          strcat(whoredirect, " is ");
          strcat(whoredirect, urec->handle);
          strcat(whoredirect, ", and ");
          strcpy(object, urec->handle);
          break;
        }
        chan = chan->next;
      }
      if (!onchan) {
        dprintf(idx, "%sI don't think I know who %s is, %s.\n",
                prefix, object, nick);
        return;
      }
    }
    if (!egg_strcasecmp(word1, "bf") || !egg_strcasecmp(word1, "boyfriend")) {
      strcpy(whotarget, getxtra(object, "BF"));
      if (whotarget[0]) {
        sprintf(whoredirect, "%s boyfriend is %s, and ",
                fixnick(object), whotarget);
        goto targetcont;
      }
      dprintf(idx,
              "%sI don't know who %s boyfriend is, %s.\n",
              prefix, fixnick(object), nick);
      return;
    }
    if (!egg_strcasecmp(word1, "gf") || !egg_strcasecmp(word1, "girlfriend")) {
      strcpy(whotarget, getxtra(object, "GF"));
      if (whotarget[0]) {
        sprintf(whoredirect, "%s girlfriend is %s, and ",
                fixnick(object), whotarget);
        goto targetcont;
      }
      dprintf(idx,
              "%sI don't know who %s girlfriend is, %s.\n",
              prefix, fixnick(object), nick);
      return;
    }
    dprintf(idx,
            "%sWhy are you bothering me with questions about %s %s, %s?\n",
            prefix, fixnick(object), word1, nick);
    return;
  }
  /* Keyword "my" */
  if (!egg_strcasecmp(word1, "my")) {
    wordshift(word1, text);
    if (!word1[0]) {
      dprintf(idx, "%sYour what, %s?\n", prefix, nick);
      return;
    }
    /* Do I even KNOW the requestor? */
    if (hand[0] == '*' || !hand[0]) {
      dprintf(idx,
              "%sI don't know you, %s, so I don't know about your %s.\n",
              prefix, nick, word1);
      return;
    }
    /* "my boyfriend" */
    if (!egg_strcasecmp(word1, "boyfriend") || !egg_strcasecmp(word1, "bf")) {
      strcpy(whotarget, getxtra(hand, "BF"));
      if (whotarget[0]) {
        sprintf(whoredirect, "%s, your boyfriend is %s, and ", nick, whotarget);
      } else {
        dprintf(idx, "%sI didn't know you had a boyfriend, %s\n", prefix, nick);
        return;
      }
    }
    /* "my girlfriend" */
    else if (!egg_strcasecmp(word1, "girlfriend") ||
             !egg_strcasecmp(word1, "gf")) {
      strcpy(whotarget, getxtra(hand, "GF"));
      if (whotarget[0]) {
        sprintf(whoredirect, "%s, your girlfriend is %s, and ",
                nick, whotarget);
      } else {
        dprintf(idx, "%sI didn't know you had a girlfriend, %s\n", prefix,
                nick);
        return;
      }
    } else {
      dprintf(idx, "%sI don't know anything about your %s, %s.\n", prefix,
              word1, nick);
      return;
    }
  }
  /* "your" keyword */
  else if (!egg_strcasecmp(word1, "your")) {
    wordshift(word1, text);
    /* "your admin" */
    if (!egg_strcasecmp(word1, "owner") || !egg_strcasecmp(word1, "admin")) {
      if (admin[0]) {
        strcpy(word2, admin);
        wordshift(whotarget, word2);
        strcat(whoredirect, "My owner is ");
        strcat(whoredirect, whotarget);
        strcat(whoredirect, ", and ");
        if (!egg_strcasecmp(whotarget, hand)) {
          strcat(whoredirect, "that's YOU");
          if (!egg_strcasecmp(hand, nick))
            strcat(whoredirect, "!!!");
          else {
            strcat(whoredirect, ", ");
            strcat(whoredirect, nick);
            strcat(whoredirect, "!");
          }
          dprintf(idx, "%s%s\n", prefix, whoredirect);
          return;
        }
      } else {                    /* owner variable munged or not set */
        dprintf(idx,
                "%sI don't seem to recall who my owner is right now...\n",
                prefix);
        return;
      }
    } else {                      /* no "your" target specified */
      dprintf(idx, "%sLet's not get personal, %s.\n", prefix, nick);
      return;
    }
  }
  /* Check for keyword match in the internal table */
  else if (match_trigger(word1)) {
    sprintf(word2, "%s%s\n", prefix, match_trigger(word1));
    dprintf(idx, word2, nick);
    return;
  }
  /* Otherwise, make the target to the first word and continue */
  else
    strcpy(whotarget, word1);

targetcont:
  /* Looking for ones own nick? */
  if (!rfc_casecmp(nick, whotarget)) {
    dprintf(idx, "%s%sLooking for yourself, eh %s?\n",
            prefix, whoredirect, nick);
    return;
  }
  /* Check if nick is on a channel */
  chan = chanset;
  while (chan) {
    m = ismember(chan, whotarget);
    if (m) {
      onchan = 1;
      sprintf(word1, "%s!%s", whotarget, m->userhost);
      urec = get_user_by_host(word1);
      if (!urec || !egg_strcasecmp(whotarget, urec->handle))
        break;
      strcat(whoredirect, whotarget);
      strcat(whoredirect, " is ");
      strcat(whoredirect, urec->handle);
      strcat(whoredirect, ", and ");
      break;
    }
    chan = chan->next;
  }
  /* Check if nick is on a channel by xref'ing to handle */
  if (!onchan) {
    chan = chanset;
    while (chan) {
      m = chan->channel.member;
      while (m && m->nick[0]) {
        sprintf(word2, "%s!%s", m->nick, m->userhost);
        urec = get_user_by_host(word2);
        if (urec && !egg_strcasecmp(urec->handle, whotarget)) {
          onchan = 1;
          strcat(whoredirect, whotarget);
          strcat(whoredirect, " is ");
          strcat(whoredirect, m->nick);
          strcat(whoredirect, ", and ");
          strcpy(whotarget, m->nick);
          break;
        }
        m = m->next;
      }
      chan = chan->next;
    }
  }
  /* Check if the target was on the channel, but is netsplit */
  chan = findchan_by_dname(channel);
  if (chan) {
    m = ismember(chan, whotarget);
    if (m && chan_issplit(m)) {
      dprintf(idx, "%s%s%s was just here, but got netsplit.\n",
              prefix, whoredirect, whotarget);
      return;
    }
  }
  /* Check if the target IS on the channel */
  if (chan && m) {
    dprintf(idx, "%s%s%s is on the channel right now!\n",
            prefix, whoredirect, whotarget);
    return;
  }
  /* Target not on this channel.   Check other channels */
  chan = chanset;
  while (chan) {
    m = ismember(chan, whotarget);
    if (m && chan_issplit(m)) {
      dprintf(idx,
              "%s%s%s was just on %s, but got netsplit.\n",
              prefix, whoredirect, whotarget, chan->dname);
      return;
    }
    if (m) {
      dprintf(idx,
              "%s%s%s is on %s right now!\n",
              prefix, whoredirect, whotarget, chan->dname);
      return;
    }
    chan = chan->next;
  }
  /* Target isn't on any of my channels. */
  /* See if target matches a handle in my userlist. */
  urec = get_user_by_handle(userlist, whotarget);
  /* No match, then bail out */
  if (!urec) {
    dprintf(idx, "%s%sI don't know who %s is.\n",
            prefix, whoredirect, whotarget);
    return;
  }
  /* We had a userlist match to a handle */
  /* Is the target currently DCC CHAT to me on the botnet? */
  for (i = 0; i < dcc_total; i++) {
    if (dcc[i].type->flags & DCT_CHAT) {
      if (!egg_strcasecmp(whotarget, dcc[i].nick)) {
        if (!rfc_casecmp(channel, dcc[i].u.chat->con_chan) &&
            dcc[i].u.chat->con_flags & LOG_PUBLIC) {
          strcat(whoredirect, whotarget);
          strcat(whoredirect,
                 " is 'observing' this channel right now from my party line!");
          dprintf(idx, "%s%s\n", prefix, whoredirect);
        } else {
          dprintf(idx,
                  "%s%s%s is linked to me via DCC CHAT right now!\n",
                  prefix, whoredirect, whotarget);
        }
        return;
      }
    }
  }
  /* Target known, but nowhere to be seen.  Give last IRC and botnet time */
  wordshift(word1, text);
  if (!egg_strcasecmp(word1, "anywhere"))
    cr = NULL;
  else
    for (cr = urec->chanrec; cr; cr = cr->next) {
      if (!rfc_casecmp(cr->channel, channel)) {
        if (cr->laston) {
          laston = cr->laston;
          lastonplace = channel;
          break;
        }
      }
    }
  if (!cr) {
    li = get_user(&USERENTRY_LASTON, urec);
    if (!li || !li->lastonplace || !li->lastonplace[0]) {
      dprintf(idx, "%s%sI've never seen %s around.\n",
              prefix, whoredirect, whotarget);
      return;
    }
    lastonplace = li->lastonplace;
    laston = li->laston;
  }
  word1[0] = 0;
  word2[0] = 0;
  work = now - laston;
  if (work >= 86400) {
    tv = work / 86400;
    sprintf(word2, "%lu day%s, ", tv, (tv == 1) ? "" : "s");
    work = work % 86400;
  }
  if (work >= 3600) {
    tv = work / 3600;
    sprintf(word2 + strlen(word2), "%lu hour%s, ", tv, (tv == 1) ? "" : "s");
    work = work % 3600;
  }
  if (work >= 60) {
    tv = work / 60;
    sprintf(word2 + strlen(word2), "%lu minute%s, ", tv,
            (tv == 1) ? "" : "s");
  }
  if (!word2[0] && (work < 60)) {
    strcpy(word2, "just moments ago!!");
  } else {
    strcpy(word2 + strlen(word2) - 2, " ago.");
  }
  if (lastonplace[0] && (strchr(CHANMETA, lastonplace[0]) != NULL))
    sprintf(word1, "on IRC channel %s", lastonplace);
  else if (lastonplace[0] == '@')
    sprintf(word1, "on %s", lastonplace + 1);
  else if (lastonplace[0] != 0)
    sprintf(word1, "on my %s", lastonplace);
  else
    strcpy(word1, "seen");
  dprintf(idx, "%s%s%s was last %s %s\n",
          prefix, whoredirect, whotarget, word1, word2);
}
示例#19
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);
}