예제 #1
0
파일: chanprog.c 프로젝트: asterIRC/kaosdal
void reaffirm_owners()
{
  char *p, *q, s[121];
  struct userrec *u;

  /* Please stop breaking this function. */
  if (owner[0]) {
    q = owner;
    p = strchr(q, ',');
    while (p) {
      strncpyz(s, q, (p - q) + 1);
      rmspace(s);
      u = get_user_by_handle(userlist, s);
      if (u)
        u->flags = sanity_check(u->flags | USER_OWNER);
      q = p + 1;
      p = strchr(q, ',');
    }
    strcpy(s, q);
    rmspace(s);
    u = get_user_by_handle(userlist, s);
    if (u)
      u->flags = sanity_check(u->flags | USER_OWNER);
  }
}
예제 #2
0
파일: botcmd.c 프로젝트: vap0r/wraith
/* idx nick conmask cmd par */
static void bot_rsim(char *botnick, char *code, char *msg)
{
  int ridx = -1, idx = -1, i = 0, rconmask;
  unsigned long status = 0;
  char *nick = NULL, *cmd = NULL, *rconchan = NULL, buf[UHOSTMAX] = "", *par = NULL, *parp = NULL;
  struct userrec *u = get_user_by_handle(userlist, botnick);

  if (bot_hublevel(u) == 999) {
    putlog(LOG_WARN, "*", "BOTCMD received from a leaf. HIJACK.");
    return;
  }

  par = parp = strdup(msg);
  ridx = atoi(newsplit(&par));
  nick = newsplit(&par);
  rconmask = atoi(newsplit(&par));
  rconchan = newsplit(&par);
  if (egg_isdigit(par[0]))
    status = (unsigned long) atoi(newsplit(&par));
  cmd = newsplit(&par);
  if (ridx < 0 || !nick || !cmd) {
    free(parp);
    return;
  }

  for (i = 0; i < dcc_total; i++) {
   /* See if we can find a simul-idx for the same ridx/nick */
   if (dcc[i].type && dcc[i].simul == ridx && !strcasecmp(dcc[i].nick, nick)) {
     putlog(LOG_DEBUG, "*", "Simul found old idx for %s: %d (ridx: %d)", nick, i, ridx);
     dcc[i].simultime = now;
     idx = i;
     break;
   }
  }

  if (idx < 0) {
    idx = new_dcc(&DCC_CHAT, sizeof(struct chat_info));
    putlog(LOG_DEBUG, "*", "Making new idx for %s@%s: %d ridx: %d", nick, botnick, idx, ridx);
    dcc[idx].sock = -1;
    dcc[idx].timeval = now;
    dcc[idx].simultime = now;
    dcc[idx].simul = ridx;
    dcc[idx].status = status;
    strlcpy(dcc[idx].simulbot, botnick, sizeof(dcc[idx].simulbot));
    dcc[idx].u.chat->con_flags = rconmask;
    struct chat_info dummy;
    strlcpy(dcc[idx].u.chat->con_chan, rconchan, sizeof(dummy.con_chan));
    dcc[idx].u.chat->strip_flags = STRIP_ALL;
    strlcpy(dcc[idx].nick, nick, sizeof(dcc[idx].nick));
    simple_snprintf(buf, sizeof buf, "%s@%s", nick, botnick);
    strlcpy(dcc[idx].host, buf, sizeof(dcc[idx].host));
    dcc[idx].addr = 0L;
    dcc[idx].user = get_user_by_handle(userlist, nick);
  }
  rmspace(par);
  check_bind_dcc(cmd, idx, par);
  free(parp);
}
예제 #3
0
파일: seen.c 프로젝트: Abysim/NyanLion
static char *getxtra(char *hand, char *field)
{

  struct userrec *urec;
  struct user_entry *ue;
  struct xtra_key *xk;

  urec = get_user_by_handle(userlist, hand);
  if (urec) {
    ue = find_user_entry(&USERENTRY_XTRA, urec);
    if (ue)
      for (xk = ue->u.extra; xk; xk = xk->next)
        if (xk->key && !egg_strcasecmp(xk->key, field)) {
          if (xk->data[0] == '{' && xk->data[strlen(xk->data) - 1] == '}' &&
              strlen(xk->data) > 2) {
            strncpy(fixit, &xk->data[1], strlen(xk->data) - 2);
            fixit[strlen(xk->data) - 2] = 0;
            return fixit;
          } else {
            return xk->data;
          }
        }
  }
  return "";
}
예제 #4
0
파일: chanprog.c 프로젝트: x90/wraith
void setup_HQ(int n) {
    dcc[n].addr = iptolong(getmyip());
    dcc[n].sock = STDOUT;
    dcc[n].timeval = now;
    dcc[n].u.chat->con_flags = conmask | LOG_ALL;
    dcc[n].u.chat->strip_flags = STRIP_ALL;
    dcc[n].status = STAT_ECHO;
    strlcpy(dcc[n].nick, STR("HQ"), sizeof(dcc[n].nick));
    strlcpy(dcc[n].host, STR("llama@console"), sizeof(dcc[n].host));
    dcc[n].user = get_user_by_handle(userlist, dcc[n].nick);
    /* Make sure there's an innocuous HQ user if needed */
    if (!dcc[n].user) {
      userlist = adduser(userlist, dcc[n].nick, "none", "-", USER_ADMIN | USER_OWNER | USER_MASTER | USER_VOICE | USER_OP | USER_PARTY | USER_CHUBA | USER_HUBA, 0);
      dcc[n].user = get_user_by_handle(userlist, dcc[n].nick);
    }
}
예제 #5
0
파일: userent.c 프로젝트: Mafaioz/wraith
void update_mod(char *handle, char *nick, char *cmd, char *par)
{
  char tmp[100] = "";

  simple_snprintf(tmp, sizeof tmp, "%li, %s (%s %s)", (long) now, nick, cmd, (par && par[0]) ? par : "");
  set_user(&USERENTRY_MODIFIED, get_user_by_handle(userlist, handle), tmp);
}
예제 #6
0
파일: core_binds.c 프로젝트: Estella/wraith
void check_bind_chof(char *hand, int idx)
{
  struct userrec        *u = NULL;

  u = get_user_by_handle(userlist, hand);
  touch_laston(u, "partyline", now);
}
예제 #7
0
static void set_handle_chaninfo(struct userrec *bu, char *handle,
                                char *chname, char *info)
{
  struct userrec *u;
  struct chanuserrec *ch;
  struct chanset_t *cst;

  u = get_user_by_handle(bu, handle);
  if (!u)
    return;
  ch = get_chanrec(u, chname);
  if (!ch) {
    add_chanrec_by_handle(bu, handle, chname);
    ch = get_chanrec(u, chname);
  }
  if (ch->info != NULL)
    nfree(ch->info);
  if (info && info[0]) {
    ch->info = (char *) user_malloc(strlen(info) + 1);
    strcpy(ch->info, info);
  } else
    ch->info = NULL;
  cst = findchan_by_dname(chname);
  if ((!noshare) && (bu == userlist) &&
      !(u->flags & (USER_UNSHARED | USER_BOT)) && share_greet) {
    shareout(cst, "chchinfo %s %s %s\n", handle, chname, info ? info : "");
  }
}
예제 #8
0
static void tell_file_stats(int idx, char *hand)
{
  struct userrec *u;
  struct filesys_stats *fs;
  float fr = (-1.0), kr = (-1.0);

  u = get_user_by_handle(userlist, hand);
  if (u == NULL)
    return;
  if (!(fs = get_user(&USERENTRY_FSTAT, u))) {
    dprintf(idx, "No file statistics for %s.\n", hand);
  } else {
    dprintf(idx, "  uploads: %4u / %6luk\n", fs->uploads, fs->upload_ks);
    dprintf(idx, "downloads: %4u / %6luk\n", fs->dnloads, fs->dnload_ks);
    if (fs->uploads)
      fr = ((float) fs->dnloads / (float) fs->uploads);
    if (fs->upload_ks)
      kr = ((float) fs->dnload_ks / (float) fs->upload_ks);
    if (fr < 0.0)
      dprintf(idx, "(infinite file leech)\n");
    else
      dprintf(idx, "leech ratio (files): %6.2f\n", fr);
    if (kr < 0.0)
      dprintf(idx, "(infinite size leech)\n");
    else
      dprintf(idx, "leech ratio (size) : %6.2f\n", kr);
  }
}
예제 #9
0
파일: channels.c 프로젝트: Mafaioz/wraith
/* This will close channels if the HUB:leaf count is skewed from config setting */
static void 
check_should_close()
{
  int H = close_threshold.count, L = close_threshold.time;

  if ((H <= 0) || (L <= 0))
    return;

  int hc = 1, lc = 0;
  struct userrec *u = NULL;

  for (tand_t *bot = tandbot; bot; bot = bot->next) {
    if ((u = get_user_by_handle(userlist, bot->bot))) {
      if (bot_hublevel(u) < 999)
        hc++;
      else
        lc++;
    }
  }
  if ((hc >= H) && (lc <= L)) {
    for (struct chanset_t *chan = chanset; chan; chan = chan->next) {
      if (!channel_closed(chan)) {
        do_chanset(NULL, chan, "+closed chanmode +stni", DO_LOCAL | DO_NET);
#ifdef G_BACKUP
        chan->channel.backup_time = now + 30;
#endif /* G_BACKUP */
      }
    }
  }
}
예제 #10
0
파일: misc.c 프로젝트: kirune/wraith
void show_channels(int idx, char *handle)
{
  struct userrec *u = NULL;
  size_t maxChannelLength = 0;
  bd::Array<bd::String> channelNames;
  bd::HashTable<bd::String, struct chanset_t*> channels;
  bd::String group;

  if (handle && handle[0] != '%') {
    u = get_user_by_handle(userlist, handle);
  } else {
    u = dcc[idx].user;
    if (handle && handle[0] == '%') {
      group = handle + 1;
    }
  }

  for (struct chanset_t* chan = chanset; chan; chan = chan->next) {
    struct flag_record fr = { FR_CHAN | FR_GLOBAL, 0, 0, 0 };
    const bd::String chname(chan->dname);
    // If a group was passed, ensure it matches
    if (group.length() && chan->groups->find(group) == chan->groups->npos) {
      continue;
    }
    get_user_flagrec(u, &fr, chan->dname);
    if (group.length() || real_chk_op(fr, chan, 0)) {
      if (maxChannelLength < chname.length()) {
        maxChannelLength = chname.length();
      }
      channelNames << chname;
      channels[chname] = chan;
    }
  }

  if (channelNames.length()) {
    char format[120] = "";
    simple_snprintf(format, sizeof(format), "  %%c%%-%zus %%-s%%-s%%-s%%-s%%-s%%-s\n", (maxChannelLength+2));
    if (group.length()) {
      dprintf(idx, "group '%s' is in %zu channel%s:\n", group.c_str(), channelNames.length(), (channelNames.length() > 1) ? "s" : "");
    } else {
      dprintf(idx, "%s %s access to %zu channel%s:\n", handle ? u->handle : "You", handle ? "has" : "have", channelNames.length(), (channelNames.length() > 1) ? "s" : "");
    }

    for (size_t i = 0; i < channelNames.length(); ++i) {
      const bd::String chname(channelNames[i]);
      const struct chanset_t* chan = channels[chname];
      dprintf(idx, format, !conf.bot->hub && me_op(chan) ? '@' : ' ', chan->dname, ((conf.bot->hub && channel_inactive(chan)) || (!conf.bot->hub && !shouldjoin(chan))) ? "(inactive) " : "",
          channel_privchan(chan) ? "(private)  " : "", chan->manop ? "(no manop) " : "", 
          channel_bitch(chan) && !channel_botbitch(chan) ? "(bitch)    " : channel_botbitch(chan) ? "(botbitch) " : "",
          channel_closed(chan) ?  "(closed) " : "", channel_backup(chan) ? "(backup)" : "");
    }
  } else {
    if (group.length()) {
      dprintf(idx, "No channels found for group '%s'\n", group.c_str());
    } else {
      dprintf(idx, "%s %s not have access to any channels.\n", handle ? u->handle : "You", handle ? "does" : "do");
    }
  }
}
예제 #11
0
파일: chanprog.c 프로젝트: x90/wraith
static struct userrec* add_bot_userlist(char* bot) {
  struct userrec *u = NULL;
  if (!(u = get_user_by_handle(userlist, bot))) {
    /* I need to be on the userlist... doh. */
    userlist = adduser(userlist, bot, "none", "-", USER_OP, 1);
    u = get_user_by_handle(userlist, bot);

    struct bot_addr *bi = (struct bot_addr *) my_calloc(1, sizeof(struct bot_addr));
    bi->uplink = (char *) my_calloc(1, 1);
    bi->address = (char *) my_calloc(1, 1);
    bi->telnet_port = 3333;
    bi->relay_port = 3333;
    bi->hublevel = 999;
    set_user(&USERENTRY_BOTADDR, u, bi);
  }
  return u;
}
예제 #12
0
static void bot_handshake(int idx, char *par)
{
  struct userrec *u = get_user_by_handle(userlist, dcc[idx].nick);

  /* We *don't* want botnet passwords migrating */
  noshare = 1;
  set_user(&USERENTRY_PASS, u, par);
  noshare = 0;
}
예제 #13
0
파일: ctcp.c 프로젝트: asterIRC/kaosdal
static int ctcp_PING(char *nick, char *uhost, char *handle,
                     char *object, char *keyword, char *text)
{
  struct userrec *u = get_user_by_handle(userlist, handle);
  int atr = u ? u->flags : 0;

  if ((ctcp_mode != 1 || (atr & USER_OP)) && strlen(text) <= 80)
    simple_sprintf(ctcp_reply, "%s\001%s %s\001", ctcp_reply, keyword, text);
  return 1;
}
예제 #14
0
static void add_chanrec_by_handle(struct userrec *bu, char *hand, char *chname)
{
  struct userrec *u;

  u = get_user_by_handle(bu, hand);
  if (!u)
    return;
  if (!get_chanrec(u, chname))
    add_chanrec(u, chname);
}
예제 #15
0
파일: core_binds.c 프로젝트: Estella/wraith
void check_bind_chon(char *hand, int idx)
{
  struct flag_record     fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0 };
  struct userrec        *u = NULL;

  u = get_user_by_handle(userlist, hand);
  touch_laston(u, "partyline", now);
  get_user_flagrec(u, &fr, NULL);
  check_bind(BT_chon, hand, &fr, hand, idx);
}
예제 #16
0
파일: ctcp.c 프로젝트: asterIRC/kaosdal
static int ctcp_CHAT(char *nick, char *uhost, char *handle, char *object,
                     char *keyword, char *text)
{
  struct userrec *u = get_user_by_handle(userlist, handle);
  int atr = u ? u->flags : 0, i;
  char s[INET6_ADDRSTRLEN];
#ifdef TLS
  int ssl = 0;
#endif

  if ((atr & (USER_PARTY | USER_XFER)) || ((atr & USER_OP) && !require_p)) {

    if (u_pass_match(u, "-")) {
      simple_sprintf(ctcp_reply, "%s\001ERROR no password set\001",
                     ctcp_reply);
      return 1;
    }

#ifdef TLS
    if (!egg_strcasecmp(keyword, "SCHAT"))
      ssl = 1;
#endif
    for (i = 0; i < dcc_total; i++) {
      if ((dcc[i].type->flags & DCT_LISTEN) &&
#ifdef TLS
          (ssl == dcc[i].ssl) &&
#endif
          (!strcmp(dcc[i].nick, "(telnet)") ||
           !strcmp(dcc[i].nick, "(users)")) &&
          getdccaddr(&dcc[i].sockname, s, sizeof s)) {
        /* Do me a favour and don't change this back to a CTCP reply,
         * CTCP replies are NOTICE's this has to be a PRIVMSG
         * -poptix 5/1/1997 */
#ifdef TLS
	  dprintf(DP_SERVER, ":%s PRIVMSG %s :\001DCC %sCHAT chat %s %u\001\n",
		  botname, nick, (ssl ? "S" : ""), s, dcc[i].port);
#else
          dprintf(DP_SERVER, ":%s PRIVMSG %s :\001DCC CHAT chat %s %u\001\n",
                  botname, nick, s, dcc[i].port);
#endif
        return 1;
      }
    }
#ifdef TLS
    simple_sprintf(ctcp_reply, "%s\001ERROR no %stelnet port\001", ctcp_reply,
	 	   (ssl ? "SSL enabled " : ""));
#else
    simple_sprintf(ctcp_reply, "%s\001ERROR no telnet port\001", ctcp_reply);
#endif
  }
  return 1;
}
예제 #17
0
파일: botcmd.c 프로젝트: vap0r/wraith
/* part <bot> <nick> <sock> [etc..]
 */
static void bot_part(int idx, char *par)
{
  char *bot = NULL, *nick = NULL, *etc = NULL;
  struct userrec *u = NULL;
  int sock, partyidx;
  int silent = 0;

  bot = newsplit(&par);
  if (bot[0] == '!') {
    silent = 1;
    bot++;
  }
  nick = newsplit(&par);
  etc = newsplit(&par);
  sock = base64_to_int(etc);

  u = get_user_by_handle(userlist, nick);
  if (u) {
    simple_snprintf(TBUF, sizeof(TBUF), "@%s", bot);
    touch_laston(u, TBUF, now);
  }
  if ((partyidx = getparty(bot, sock)) != -1) {
    if (!silent) {
      register int chan = party[partyidx].chan;

      if (par[0])
	chanout_but(-1, chan, "*** (%s) %s %s %s (%s).\n", conf.bot->hub ? bot : "[botnet]", nick,
		    "has left the",
		    chan ? "channel" : "party line", par);
      else
	chanout_but(-1, chan, "*** (%s) %s %s %s.\n", conf.bot->hub ? bot : "[botnet]", nick,
		    "has left the",
		    chan ? "channel" : "party line");
    }
    botnet_send_part_party(idx, partyidx, par, silent);
    remparty(bot, sock);
  }

  /* check if we have a remote idx for them */
  int i = 0;

  for (i = 0; i < dcc_total; i++) {
    /* This will potentially close all simul-idxs with matching nick, even though they may be connected multiple times
       but, it won't matter as a new will just be made as needed. */
    if (dcc[i].type && dcc[i].simul >= 0 && !strcasecmp(dcc[i].nick, nick)) {
        dcc[i].simul = -1;
        lostdcc(i);
    }
  }

}
예제 #18
0
파일: cmdschan.c 프로젝트: kirune/wraith
static void cmd_mns_chrec(int idx, char *par)
{
  char *nick = NULL, *chn = NULL;
  struct userrec *u1 = NULL;
  struct chanuserrec *chanrec = NULL;

  if (!par[0]) {
    dprintf(idx, "Usage: -chrec <user> [channel]\n");
    return;
  }
  nick = newsplit(&par);
  u1 = get_user_by_handle(userlist, nick);
  if (!u1) {
    dprintf(idx, "No such user.\n");
    return;
  }
  if (!par[0]) {
    struct chanset_t *chan;

    chan = findchan_by_dname(dcc[idx].u.chat->con_chan);
    if (chan)
      chn = chan->dname;
    else {
      dprintf(idx, "Invalid console channel.\n");
      return;
    }
  } else
    chn = newsplit(&par);
  get_user_flagrec(dcc[idx].user, &user, chn);
  get_user_flagrec(u1, &victim, chn);
  if (privchan(user, findchan_by_dname(chn), PRIV_OP)) {
    dprintf(idx, "No such channel.\n");
    return;
  }
  if ((!glob_master(user) && !chan_master(user)) ||  /* drummer */
      (chan_owner(victim) && !chan_owner(user) && !glob_owner(user)) ||
      (glob_owner(victim) && !glob_owner(user))) {
    dprintf(idx, "You have no permission to do that.\n");
    return;
  }
  chanrec = get_chanrec(u1, chn);
  if (!chanrec) {
    dprintf(idx, "User %s doesn't have a channel record for %s.\n", nick, chn);
    return;
  }
  putlog(LOG_CMDS, "*", "#%s# -chrec %s %s", dcc[idx].nick, nick, chn);
  del_chanrec(u1, chn);
  dprintf(idx, "Removed %s channel record from %s.\n", chn, nick);
  if (conf.bot->hub)
    write_userfile(idx);
}
예제 #19
0
static void dcc_files_pass(int idx, char *buf, int x)
{
  struct userrec *u = get_user_by_handle(userlist, dcc[idx].nick);

  if (!x)
    return;
  if (u_pass_match(u, buf)) {
    if (too_many_filers()) {
      dprintf(idx, "Too many people are in the file system right now.\n");
      dprintf(idx, "Please try again later.\n");
      putlog(LOG_MISC, "*", "File area full: DCC chat [%s]%s", dcc[idx].nick,
	     dcc[idx].host);
      killsock(dcc[idx].sock);
      lostdcc(idx);
      return;
    }
    dcc[idx].type = &DCC_FILES;
    if (dcc[idx].status & STAT_TELNET)
      dprintf(idx, "\377\374\001\n");	/* turn echo back on */
    putlog(LOG_FILES, "*", "File system: [%s]%s/%d", dcc[idx].nick,
	   dcc[idx].host, dcc[idx].port);
    if (!welcome_to_files(idx)) {
      putlog(LOG_FILES, "*", "File system broken.");
      killsock(dcc[idx].sock);
      lostdcc(idx);
    } else {
      struct userrec *u = get_user_by_handle(userlist, dcc[idx].nick);

      touch_laston(u, "filearea", now);
    }
    return;
  }
  dprintf(idx, "Negative on that, Houston.\n");
  putlog(LOG_MISC, "*", "Bad password: DCC chat [%s]%s", dcc[idx].nick,
	 dcc[idx].host);
  killsock(dcc[idx].sock);
  lostdcc(idx);
}
예제 #20
0
파일: chanprog.c 프로젝트: x90/wraith
void reaffirm_owners()
{
  /* Make sure perm owners are +a */
  if (owner[0]) {
    char *q = owner, *p = strchr(q, ','), s[121] = "";
    struct userrec *u = NULL;

    while (p) {
      strlcpy(s, q, (p - q) + 1);
      rmspace(s);
      u = get_user_by_handle(userlist, s);
      if (u)
	u->flags = sanity_check(u->flags | USER_ADMIN, 0);
      q = p + 1;
      p = strchr(q, ',');
    }
    strlcpy(s, q, sizeof(s));
    rmspace(s);
    u = get_user_by_handle(userlist, s);
    if (u)
      u->flags = sanity_check(u->flags | USER_ADMIN, 0);
  }
}
예제 #21
0
void check_tcl_chonof(char *hand, int sock, tcl_bind_list_t *tl)
{
  struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 };
  char s[11];
  struct userrec *u;

  u = get_user_by_handle(userlist, hand);
  touch_laston(u, "partyline", now);
  get_user_flagrec(u, &fr, NULL);
  Tcl_SetVar(interp, "_chonof1", (char *) hand, 0);
  egg_snprintf(s, sizeof s, "%d", sock);
  Tcl_SetVar(interp, "_chonof2", (char *) s, 0);
  check_tcl_bind(tl, hand, &fr, " $_chonof1 $_chonof2", MATCH_MASK |
                 BIND_USE_ATTR | BIND_STACKABLE | BIND_WANTRET);
}
예제 #22
0
파일: notes.c 프로젝트: ArNz8o8/Fr3shness
/* Get rid of old useless notes.
 */
static void expire_notes()
{
  FILE *f, *g;
  char s[513], *to, *from, *ts, *s1;
  int tot = 0, lapse;

  if (!notefile[0])
    return;
  f = fopen(notefile, "r");
  if (f == NULL)
    return;
  sprintf(s, "%s~new", notefile);
  g = fopen(s, "w");
  if (g == NULL) {
    fclose(f);
    return;
  }
  chmod(s, userfile_perm);      /* Use userfile permissions. */
  while (!feof(f)) {
    fgets(s, 512, f);
    if (!feof(f)) {
      if (s[strlen(s) - 1] == '\n')
        s[strlen(s) - 1] = 0;
      rmspace(s);
      if ((s[0]) && (s[0] != '#') && (s[0] != ';')) {   /* Not comment */
        s1 = s;
        to = newsplit(&s1);
        from = newsplit(&s1);
        ts = newsplit(&s1);
        lapse = (now - (time_t) atoi(ts)) / 86400;
        if (lapse > note_life)
          tot++;
        else if (!get_user_by_handle(userlist, to))
          tot++;
        else
          fprintf(g, "%s %s %s %s\n", to, from, ts, s1);
      } else
        fprintf(g, "%s\n", s);
    }
  }
  fclose(f);
  fclose(g);
  unlink(notefile);
  sprintf(s, "%s~new", notefile);
  movefile(s, notefile);
  if (tot > 0)
    putlog(LOG_MISC, "*", NOTES_EXPIRED, tot, tot == 1 ? "" : "s");
}
예제 #23
0
파일: botcmd.c 프로젝트: vap0r/wraith
/* join <bot> <nick> <chan> <flag><sock> <from>
 */
static void bot_join(int idx, char *par)
{
  char *bot = NULL, *nick = NULL, *x = NULL, *y = NULL;
  struct userrec *u = NULL;
  int i, sock, chan, i2, linking = 0;

  bot = newsplit(&par);
  if (bot[0] == '!') {
    linking = 1;
    bot++;
  }
  if (b_status(idx) & STAT_LINKING) {
    linking = 1;
  }
  nick = newsplit(&par);
  x = newsplit(&par);
  chan = base64_to_int(x);
  y = newsplit(&par);
  if ((chan < 0) || !y[0])
    return;			/* Woops! pre 1.2.1's send .chat off'ers
				 * too!! */
  if (!y[0]) {
    y[0] = '-';
    sock = 0;
  } else {
    sock = base64_to_int(y + 1);
  }
  i = nextbot(bot);
  if (i != idx) {		/* Ok, garbage from a 1.0g (who uses that
				 * now?) OR raistlin being evil :) */
    fake_alert(idx, "direction", bot, "join");
    return;
  }
  u = get_user_by_handle(userlist, nick);
  if (u) {
    simple_snprintf(TBUF, sizeof(TBUF), "@%s", bot);
    touch_laston(u, TBUF, now);
  }
  i = addparty(bot, nick, chan, y[0], sock, par, &i2);
  botnet_send_join_party(idx, linking, i2);
  if (i != chan) {
    if (i >= 0) {
      chanout_but(-1, i, "*** (%s) %s %s %s.\n", conf.bot->hub ? bot : "[botnet]", nick, "has left the", i ? "channel" : "party line");
    }
    if (!linking)
    chanout_but(-1, chan, "*** (%s) %s %s %s.\n", conf.bot->hub ? bot : "[botnet]", nick, "has joined the", chan ? "channel" : "party line");
  }
}
예제 #24
0
/* part <bot> <nick> <sock> [etc..]
 */
static void bot_part(int idx, char *par)
{
  char *bot, *nick, *etc;
  struct userrec *u;
  int sock, partyidx;
  int silent = 0;

  if (bot_flags(dcc[idx].user) & BOT_ISOLATE)
    return;
  bot = newsplit(&par);
  if (bot[0] == '!') {
    silent = 1;
    bot++;
  }
  nick = newsplit(&par);
  etc = newsplit(&par);
#ifndef NO_OLD_BOTNET
  if (dcc[idx].u.bot->numver < NEAT_BOTNET) {
    sock = atoi(etc);
    silent = 1;
  } else
#endif
    sock = base64_to_int(etc);
  if (sock == 0)
    sock = partysock(bot, nick);
  u = get_user_by_handle(userlist, nick);
  if (u) {
    sprintf(TBUF, "@%s", bot);
    touch_laston(u, TBUF, now);
  }
  if ((partyidx = getparty(bot, sock)) != -1) {
    if (party[partyidx].chan >= 0)
      check_tcl_chpt(bot, nick, sock, party[partyidx].chan);
    if ((dcc[idx].u.bot->numver >= NEAT_BOTNET) && !silent) {
      register int chan = party[partyidx].chan;

      if (par[0])
        chanout_but(-1, chan, "*** (%s) %s %s %s (%s).\n", bot, nick,
                    NET_LEFTTHE, chan ? "channel" : "party line", par);
      else
        chanout_but(-1, chan, "*** (%s) %s %s %s.\n", bot, nick,
                    NET_LEFTTHE, chan ? "channel" : "party line");
    }
    botnet_send_part_party(idx, partyidx, par, silent);
    remparty(bot, sock);
  }
}
예제 #25
0
파일: chanprog.c 프로젝트: x90/wraith
/* Reload the user file from disk
 */
void reload()
{
  FILE *f = fopen(userfile, "r");

  if (f == NULL) {
    putlog(LOG_MISC, "*", "Can't reload user file!");
    return;
  }
  fclose(f);
  noshare = 1;
  clear_userlist(userlist);
  noshare = 0;
  userlist = NULL;
  loading = 1;
  checkchans(0);
  if (!readuserfile(userfile, &userlist))
    fatal("User file is missing!", 0);

  /* ensure we did not lose our internal users */
  load_internal_users();
  /* make sure I am added and conf.bot->u is set */
  add_myself_to_userlist();

  if (conf.bot->localhub)
    add_child_bots();
  else if (!conf.bot->hub)
    add_localhub();

  /* Make sure no removed users/bots are still connected. */
  check_stale_dcc_users();

  for (tand_t* bot = tandbot; bot; bot = bot->next)
    bot->u = get_user_by_handle(userlist, bot->bot);

  /* I don't think these will ever be called anyway. */
  if (!conf.bot->hub) {
    Auth::FillUsers();
    check_hostmask();
  }

  checkchans(1);
  loading = 0;
  var_parse_my_botset();
  reaffirm_owners();
  hook_read_userfile();
}
예제 #26
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;
}
예제 #27
0
static void get_handle_chaninfo(char *handle, char *chname, char *s)
{
  struct userrec *u;
  struct chanuserrec *ch;

  u = get_user_by_handle(userlist, handle);
  if (u == NULL) {
    s[0] = 0;
    return;
  }
  ch = get_chanrec(u, chname);
  if (ch == NULL) {
    s[0] = 0;
    return;
  }
  if (ch->info == NULL) {
    s[0] = 0;
    return;
  }
  strcpy(s, ch->info);
  return;
}
예제 #28
0
파일: notes.c 프로젝트: ArNz8o8/Fr3shness
/* notes <pass> <func>
 */
static int msg_notes(char *nick, char *host, struct userrec *u, char *par)
{
  char *pwd, *fcn;

  if (!u)
    return 0;

  if (u->flags & (USER_BOT | USER_COMMON))
    return 1;

  if (!par[0]) {
    dprintf(DP_HELP, "NOTICE %s :%s: NOTES <pass> INDEX\n", nick, NOTES_USAGE);
    dprintf(DP_HELP, "NOTICE %s :NOTES <pass> TO <hand> <msg>\n", nick);
    dprintf(DP_HELP, "NOTICE %s :NOTES <pass> READ <# or ALL>\n", nick);
    dprintf(DP_HELP, "NOTICE %s :NOTES <pass> ERASE <# or ALL>\n", nick);
    dprintf(DP_HELP, "NOTICE %s :%s\n", nick, NOTES_MAYBE);
    dprintf(DP_HELP, "NOTICE %s :Ex: NOTES mypass ERASE 2-4;8;16-\n", nick);
    return 1;
  }

  if (!u_pass_match(u, "-")) { /* Do the have a password set? */
    pwd = newsplit(&par);
    if (!u_pass_match(u, pwd))
      return 0;
  }

  fcn = newsplit(&par);
  if (!egg_strcasecmp(fcn, "INDEX"))
    notes_read(u->handle, nick, "+", -1);
  else if (!egg_strcasecmp(fcn, "READ")) {
    if (!egg_strcasecmp(par, "ALL"))
      notes_read(u->handle, nick, "-", -1);
    else
      notes_read(u->handle, nick, par, -1);
  } else if (!egg_strcasecmp(fcn, "ERASE")) {
    if (!egg_strcasecmp(par, "ALL"))
      notes_del(u->handle, nick, "-", -1);
    else
      notes_del(u->handle, nick, par, -1);
  } else if (!egg_strcasecmp(fcn, "TO")) {
    char *to;
    int i;
    FILE *f;
    struct userrec *u2;

    to = newsplit(&par);
    if (!par[0]) {
      dprintf(DP_HELP, "NOTICE %s :%s: NOTES <pass> TO <hand> <message>\n",
              nick, NOTES_USAGE);
      return 0;
    }
    u2 = get_user_by_handle(userlist, to);
    if (!u2) {
      dprintf(DP_HELP, "NOTICE %s :%s\n", nick, NOTES_USERF_UNKNOWN);
      return 1;
    } else if (is_bot(u2)) {
      dprintf(DP_HELP, "NOTICE %s :%s\n", nick, NOTES_NOTTO_BOT);
      return 1;
    }
    for (i = 0; i < dcc_total; i++) {
      if ((!egg_strcasecmp(dcc[i].nick, to)) &&
          (dcc[i].type->flags & DCT_GETNOTES)) {
        int aok = 1;

        if (dcc[i].type->flags & DCT_CHAT)
          if (dcc[i].u.chat->away != NULL)
            aok = 0;
        if (!(dcc[i].type->flags & DCT_CHAT))
          aok = 0;              /* Assume non dcc-chat == something weird, so
                                 * store notes for later */
        if (aok) {
          dprintf(i, "\007%s [%s]: %s\n", u->handle, NOTES_OUTSIDE, par);
          dprintf(DP_HELP, "NOTICE %s :%s\n", nick, NOTES_DELIVERED);
          return 1;
        }
      }
    }
    if (notefile[0] == 0) {
      dprintf(DP_HELP, "NOTICE %s :%s\n", nick, NOTES_UNSUPPORTED);
      return 1;
    }
    f = fopen(notefile, "a");
    if (f == NULL)
      f = fopen(notefile, "w");
    if (f == NULL) {
      dprintf(DP_HELP, "NOTICE %s :%s", nick, NOTES_NOTEFILE_FAILED);
      putlog(LOG_MISC, "*", "* %s", NOTES_NOTEFILE_UNREACHABLE);
      return 1;
    }
    chmod(notefile, userfile_perm); /* Use userfile permissions. */
    fprintf(f, "%s %s %li %s\n", to, u->handle, (long) now, par);
    fclose(f);
    dprintf(DP_HELP, "NOTICE %s :%s\n", nick, NOTES_DELIVERED);
    return 1;
  } else
    dprintf(DP_HELP, "NOTICE %s :%s: NOTES <pass> INDEX, READ, ERASE, TO\n",
            nick, NOTES_USAGE);
  putlog(LOG_CMDS, "*", "(%s!%s) !%s! NOTES %s %s", nick, host, u->handle, fcn,
         par[0] ? "..." : "");
  return 1;
}
예제 #29
0
파일: main.c 프로젝트: Estella/eggdrop-1.8
int main(int arg_c, char **arg_v)
{
  int i, xx;
  char s[25];
  FILE *f;
  struct sigaction sv;
  struct chanset_t *chan;
#ifdef DEBUG
  struct rlimit cdlim;
#endif
#ifdef STOP_UAC
  int nvpair[2];
#endif

/* Make sure it can write core, if you make debug. Else it's pretty
 * useless (dw)
 *
 * Only allow unlimited size core files when compiled with DEBUG defined.
 * This is not a good idea for normal builds -- in these cases, use the
 * default system resource limits instead.
 */
#ifdef DEBUG
  cdlim.rlim_cur = RLIM_INFINITY;
  cdlim.rlim_max = RLIM_INFINITY;
  setrlimit(RLIMIT_CORE, &cdlim);
#endif

#ifdef DEBUG_CONTEXT
  /* Initialise context list */
  for (i = 0; i < 16; i++)
    Context;
#endif

/* Include patch.h header for patch("...") */
#include "patch.h"

  argc = arg_c;
  argv = arg_v;

  /* Version info! */
  egg_snprintf(ver, sizeof ver, "eggdrop v%s", egg_version);
  egg_snprintf(version, sizeof version,
               "Eggdrop v%s (C) 1997 Robey Pointer (C) 2010 Eggheads",
               egg_version);
  /* Now add on the patchlevel (for Tcl) */
  sprintf(&egg_version[strlen(egg_version)], " %u", egg_numver);
  strcat(egg_version, egg_xtra);

/* For OSF/1 */
#ifdef STOP_UAC
  /* Don't print "unaligned access fixup" warning to the user */
  nvpair[0] = SSIN_UACPROC;
  nvpair[1] = UAC_NOPRINT;
  setsysinfo(SSI_NVPAIRS, (char *) nvpair, 1, NULL, 0);
#endif

  /* Set up error traps: */
  sv.sa_handler = got_bus;
  sigemptyset(&sv.sa_mask);
#ifdef SA_RESETHAND
  sv.sa_flags = SA_RESETHAND;
#else
  sv.sa_flags = 0;
#endif
  sigaction(SIGBUS, &sv, NULL);
  sv.sa_handler = got_segv;
  sigaction(SIGSEGV, &sv, NULL);
#ifdef SA_RESETHAND
  sv.sa_flags = 0;
#endif
  sv.sa_handler = got_fpe;
  sigaction(SIGFPE, &sv, NULL);
  sv.sa_handler = got_term;
  sigaction(SIGTERM, &sv, NULL);
  sv.sa_handler = got_hup;
  sigaction(SIGHUP, &sv, NULL);
  sv.sa_handler = got_quit;
  sigaction(SIGQUIT, &sv, NULL);
  sv.sa_handler = SIG_IGN;
  sigaction(SIGPIPE, &sv, NULL);
  sv.sa_handler = got_ill;
  sigaction(SIGILL, &sv, NULL);
  sv.sa_handler = got_alarm;
  sigaction(SIGALRM, &sv, NULL);

  /* Initialize variables and stuff */
  now = time(NULL);
  chanset = NULL;
  egg_memcpy(&nowtm, localtime(&now), sizeof(struct tm));
  lastmin = nowtm.tm_min;
  srandom((unsigned int) (now % (getpid() + getppid())));
  init_mem();
  init_language(1);
  if (argc > 1)
    for (i = 1; i < argc; i++)
      do_arg(argv[i]);

  printf("\n%s\n", version);

#ifndef CYGWIN_HACKS
  /* Don't allow eggdrop to run as root
   * This check isn't useful under cygwin and has been
   * reported to cause trouble in some situations.
   */
  if (((int) getuid() == 0) || ((int) geteuid() == 0))
    fatal("ERROR: Eggdrop will not run as root!", 0);
#endif

#ifndef REPLACE_NOTIFIER
  init_threaddata(1);
#endif
  init_userent();
  init_misc();
  init_bots();
  init_modules();
  if (backgrd)
    bg_prepare_split();
  init_tcl(argc, argv);
  init_language(0);
#ifdef STATIC
  link_statics();
#endif
  strncpyz(s, ctime(&now), sizeof s);
  strcpy(&s[11], &s[20]);
  putlog(LOG_ALL, "*", "--- Loading %s (%s)", ver, s);
  chanprog();
  if (!encrypt_pass) {
    printf(MOD_NOCRYPT);
    bg_send_quit(BG_ABORT);
    exit(1);
  }
  i = 0;
  for (chan = chanset; chan; chan = chan->next)
    i++;
  putlog(LOG_MISC, "*", "=== %s: %d channels, %d users.",
         botnetnick, i, count_users(userlist));
#ifdef TLS
  ssl_init();
#endif
  cache_miss = 0;
  cache_hit = 0;
  if (!pid_file[0])
    egg_snprintf(pid_file, sizeof pid_file, "pid.%s", botnetnick);

  /* Check for pre-existing eggdrop! */
  f = fopen(pid_file, "r");
  if (f != NULL) {
    fgets(s, 10, f);
    xx = atoi(s);
    i = kill(xx, SIGCHLD);      /* Meaningless kill to determine if pid
                                 * is used */
    if (i == 0 || errno != ESRCH) {
      printf(EGG_RUNNING1, botnetnick);
      printf(EGG_RUNNING2, pid_file);
      bg_send_quit(BG_ABORT);
      exit(1);
    }
  }

  /* Move into background? */
  if (backgrd) {
    bg_do_split();
  } else {                        /* !backgrd */
    xx = getpid();
    if (xx != 0) {
      FILE *fp;

      /* Write pid to file */
      unlink(pid_file);
      fp = fopen(pid_file, "w");
      if (fp != NULL) {
        fprintf(fp, "%u\n", xx);
        if (fflush(fp)) {
          /* Let the bot live since this doesn't appear to be a botchk */
          printf(EGG_NOWRITE, pid_file);
          fclose(fp);
          unlink(pid_file);
        } else
          fclose(fp);
      } else
        printf(EGG_NOWRITE, pid_file);
    }
  }

  use_stderr = 0;               /* Stop writing to stderr now */
  if (backgrd) {
    /* Ok, try to disassociate from controlling terminal (finger cross) */
#ifdef HAVE_SETPGID
    setpgid(0, 0);
#endif
    /* Tcl wants the stdin, stdout and stderr file handles kept open. */
    freopen("/dev/null", "r", stdin);
    freopen("/dev/null", "w", stdout);
    freopen("/dev/null", "w", stderr);
#ifdef CYGWIN_HACKS
    FreeConsole();
#endif
  }

  /* Terminal emulating dcc chat */
  if (!backgrd && term_z) {
    int n = new_dcc(&DCC_CHAT, sizeof(struct chat_info));

    getvhost(&dcc[n].sockname, AF_INET);
    dcc[n].sock = STDOUT;
    dcc[n].timeval = now;
    dcc[n].u.chat->con_flags = conmask;
    dcc[n].u.chat->strip_flags = STRIP_ALL;
    dcc[n].status = STAT_ECHO;
    strcpy(dcc[n].nick, "HQ");
    strcpy(dcc[n].host, "llama@console");
    /* HACK: Workaround not to pass literal "HQ" as a non-const arg */
    dcc[n].user = get_user_by_handle(userlist, dcc[n].nick);
    /* Make sure there's an innocuous HQ user if needed */
    if (!dcc[n].user) {
      userlist = adduser(userlist, dcc[n].nick, "none", "-", USER_PARTY);
      dcc[n].user = get_user_by_handle(userlist, dcc[n].nick);
    }
    setsock(STDOUT, 0);          /* Entry in net table */
    dprintf(n, "\n### ENTERING DCC CHAT SIMULATION ###\n\n");
    dcc_chatter(n);
  }

  then = now;
  online_since = now;
  autolink_cycle(NULL);         /* Hurry and connect to tandem bots */
  add_help_reference("cmds1.help");
  add_help_reference("cmds2.help");
  add_help_reference("core.help");
  add_hook(HOOK_SECONDLY, (Function) core_secondly);
  add_hook(HOOK_MINUTELY, (Function) core_minutely);
  add_hook(HOOK_HOURLY, (Function) core_hourly);
  add_hook(HOOK_REHASH, (Function) event_rehash);
  add_hook(HOOK_PRE_REHASH, (Function) event_prerehash);
  add_hook(HOOK_USERFILE, (Function) event_save);
  add_hook(HOOK_BACKUP, (Function) backup_userfile);
  add_hook(HOOK_DAILY, (Function) event_logfile);
  add_hook(HOOK_DAILY, (Function) event_resettraffic);
  add_hook(HOOK_LOADED, (Function) event_loaded);

  call_hook(HOOK_LOADED);

  debug0("main: entering loop");
  while (1) {
    mainloop(1);
  }
}
예제 #30
0
파일: irc.c 프로젝트: Estella/eggdrop-1.8
/* Dependant on revenge_mode, punish the offender.
 */
static void punish_badguy(struct chanset_t *chan, char *whobad,
                          struct userrec *u, char *badnick, char *victim,
                          int mevictim, int type)
{
    char reason[1024], ct[81], *kick_msg;
    memberlist *m;
    struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 };

    m = ismember(chan, badnick);
    if (!m)
        return;
    get_user_flagrec(u, &fr, chan->dname);

    /* Get current time into a string */
    egg_strftime(ct, 7, "%d %b", localtime(&now));

    /* Put together log and kick messages */
    reason[0] = 0;
    switch (type) {
    case REVENGE_KICK:
        kick_msg = IRC_KICK_PROTECT;
        simple_sprintf(reason, "kicked %s off %s", victim, chan->dname);
        break;
    case REVENGE_DEOP:
        simple_sprintf(reason, "deopped %s on %s", victim, chan->dname);
        kick_msg = IRC_DEOP_PROTECT;
        break;
    default:
        kick_msg = "revenge!";
    }
    putlog(LOG_MISC, chan->dname, "Punishing %s (%s)", badnick, reason);

    /* Set the offender +d */
    if ((chan->revenge_mode > 0) && !(chan_deop(fr) || glob_deop(fr))) {
        char s[UHOSTLEN], s1[UHOSTLEN];
        memberlist *mx = NULL;

        /* Removing op */
        if (chan_op(fr) || (glob_op(fr) && !chan_deop(fr))) {
            fr.match = FR_CHAN;
            if (chan_op(fr))
                fr.chan &= ~USER_OP;
            else
                fr.chan |= USER_DEOP;
            set_user_flagrec(u, &fr, chan->dname);
            putlog(LOG_MISC, "*", "No longer opping %s[%s] (%s)", u->handle, whobad,
                   reason);
        }
        /* ... or just setting to deop */
        else if (u) {
            /* In the user list already, cool :) */
            fr.match = FR_CHAN;
            fr.chan |= USER_DEOP;
            set_user_flagrec(u, &fr, chan->dname);
            simple_sprintf(s, "(%s) %s", ct, reason);
            putlog(LOG_MISC, "*", "Now deopping %s[%s] (%s)", u->handle, whobad, s);
        }
        /* ... or creating new user and setting that to deop */
        else {
            strcpy(s1, whobad);
            maskaddr(s1, s, chan->ban_type);
            strcpy(s1, badnick);
            /* If that handle exists use "badX" (where X is an increasing number)
             * instead.
             */
            while (get_user_by_handle(userlist, s1)) {
                if (!strncmp(s1, "bad", 3)) {
                    int i;

                    i = atoi(s1 + 3);
                    simple_sprintf(s1 + 3, "%d", i + 1);
                } else
                    strcpy(s1, "bad1");   /* Start with '1' */
            }
            userlist = adduser(userlist, s1, s, "-", 0);
            fr.match = FR_CHAN;
            fr.chan = USER_DEOP;
            fr.udef_chan = 0;
            u = get_user_by_handle(userlist, s1);
            if ((mx = ismember(chan, badnick)))
                mx->user = u;
            set_user_flagrec(u, &fr, chan->dname);
            simple_sprintf(s, "(%s) %s (%s)", ct, reason, whobad);
            set_user(&USERENTRY_COMMENT, u, (void *) s);
            putlog(LOG_MISC, "*", "Now deopping %s (%s)", whobad, reason);
        }
    }

    /* Always try to deop the offender */
    if (!mevictim)
        add_mode(chan, '-', 'o', badnick);
    /* Ban. Should be done before kicking. */
    if (chan->revenge_mode > 2) {
        char s[UHOSTLEN], s1[UHOSTLEN];

        splitnick(&whobad);
        maskaddr(whobad, s1, chan->ban_type);
        simple_sprintf(s, "(%s) %s", ct, reason);
        u_addban(chan, s1, botnetnick, s, now + (60 * chan->ban_time), 0);
        if (!mevictim && HALFOP_CANDOMODE('b')) {
            add_mode(chan, '+', 'b', s1);
            flush_mode(chan, QUICK);
        }
    }
    /* Kick the offender */
    if (!mevictim && (chan->revenge_mode > 1) && (!channel_dontkickops(chan) ||
            (!chan_op(fr) && (!glob_op(fr) || chan_deop(fr)))) &&
            !chan_sentkick(m) && (me_op(chan) || (me_halfop(chan) &&
                                  !chan_hasop(m) && (strchr(NOHALFOPS_MODES, 'b') == NULL)))) {
        dprintf(DP_MODE, "KICK %s %s :%s\n", chan->name, badnick, kick_msg);
        m->flags |= SENTKICK;
    }
}