示例#1
0
/* Got 442: not on channel
 */
static int got442(char *from, char *msg)
{
  char *chname, *key;
  struct chanset_t *chan;

  if (!realservername || egg_strcasecmp(from, realservername))
    return 0;
  newsplit(&msg);
  chname = newsplit(&msg);
  chan = findchan(chname);
  if (chan && !channel_inactive(chan)) {
    module_entry *me = module_find("channels", 0, 0);

    putlog(LOG_MISC, chname, IRC_SERVNOTONCHAN, chname);
    if (me && me->funcs)
      (me->funcs[CHANNEL_CLEAR]) (chan, 1);
    chan->status &= ~CHAN_ACTIVE;

    key = chan->channel.key[0] ? chan->channel.key : chan->key_prot;
    if (key[0])
      dprintf(DP_SERVER, "JOIN %s %s\n", chan->name, key);
    else
      dprintf(DP_SERVER, "JOIN %s\n", chan->name);
  }
  return 0;
}
示例#2
0
文件: chanprog.c 项目: x90/wraith
bool bot_shouldjoin(struct userrec* u, struct flag_record* fr, struct chanset_t* chan, bool ignore_inactive)
{
  // If restarting, keep this channel.
  if (restarting && (reset_chans == 2) && (channel_active(chan) || channel_pending(chan))) return 1;
  /* If the bot is restarting (and hasn't finished getting the userfile for the first time) DO NOT JOIN channels - breaks +B/+backup */
  if (restarting || loading) return 0;

  // No user record, can't make any safe assumptions really
  if (!u) return 0;

#ifdef DEBUG
  /* Force debugging bots to only join 3 channels */
  if (!strncmp(u->handle, "wtest", 5)) {
    if (!strcmp(chan->dname, "#skynet") || 
        !strcmp(chan->dname, "#bryan") || 
        !strcmp(chan->dname, "#wraith-devel"))
      return 1;
    else
      return 0;
  }
#endif
  // Ignore +inactive during cmd_slowjoin to ensure that +backup bots join
  return (!glob_kick(*fr) && !chan_kick(*fr) &&
      ((ignore_inactive || !channel_inactive(chan)) &&
       (channel_backup(chan) || (!glob_backup(*fr) && !chan_backup(*fr)))));
}
示例#3
0
static void read_channels(int create)
{
  struct chanset_t *chan, *chan2;

  if (!chanfile[0])
    return;
  for (chan = chanset; chan; chan = chan->next)
    if (!channel_static(chan))
      chan->status |= CHAN_FLAGGED;
  chan_hack = 1;
  if (!readtclprog(chanfile) && create) {
    FILE *f;

    /* assume file isnt there & therfore make it */
    putlog(LOG_MISC, "*", "Creating channel file");
    f = fopen(chanfile, "w");
    if (!f)
      putlog(LOG_MISC, "*", "Couldn't create channel file: %s.  Dropping",
	     chanfile);
    else fclose(f);
  }
  chan_hack = 0;
  chan = chanset;
  while (chan != NULL) {
    if (chan->status & CHAN_FLAGGED) {
      putlog(LOG_MISC, "*", "No longer supporting channel %s", chan->name);
      if (!channel_inactive(chan))
	dprintf(DP_SERVER, "PART %s\n", chan->name);
      chan2 = chan->next;
      remove_channel(chan);
      chan = chan2;
    } else
      chan = chan->next;
  }
}
示例#4
0
/* 001: welcome to IRC (use it to fix the server name) */
static int got001(char *from, char *msg)
{
  int i;
  char *key;
  struct chanset_t *chan;
  struct server_list *x = serverlist;

  /* FIXME - x should never be NULL anywhere in this function, but
   * apparently it sometimes is. */
  if (x) {
    for (i = curserv; i > 0 && x; i--)
      x = x->next;
    if (!x) {
      putlog(LOG_MISC, "*", "Invalid server list!");
    } else {
      if (x->realname)
        nfree(x->realname);
      x->realname = nmalloc(strlen(from) + 1);
      strcpy(x->realname, from);
    }
    if (realservername)
      nfree(realservername);
    realservername = nmalloc(strlen(from) + 1);
    strcpy(realservername, from);
  } else
    putlog(LOG_MISC, "*", "No server list!");

  server_online = now;
  fixcolon(msg);
  strncpyz(botname, msg, NICKLEN);
  altnick_char = 0;
  dprintf(DP_SERVER, "WHOIS %s\n", botname); /* get user@host */
  if (initserver[0])
    do_tcl("init-server", initserver); /* Call Tcl init-server */
  check_tcl_event("init-server");

  if (!x)
    return 0;

  if (module_find("irc", 0, 0)) {  /* Only join if the IRC module is loaded. */
    for (chan = chanset; chan; chan = chan->next) {
      chan->status &= ~(CHAN_ACTIVE | CHAN_PEND);
      if (!channel_inactive(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);
      }
    }
  }

  return 0;
}
示例#5
0
文件: irc.c 项目: Estella/eggdrop-1.8
/* Leave the specified channel and notify registered Tcl procs. This
 * should not be called by itsself.
 */
static void do_channel_part(struct chanset_t *chan)
{
    if (!channel_inactive(chan) && chan->name[0]) {
        /* Using chan->name is important here, especially for !chans <cybah> */
        dprintf(DP_SERVER, "PART %s\n", chan->name);

        /* As we don't know of this channel anymore when we receive the server's
         * ack for the above PART, we have to notify about it _now_. */
        check_tcl_part(botname, botuserhost, NULL, chan->dname, NULL);
    }
}
示例#6
0
文件: irc.c 项目: Estella/eggdrop-1.8
/* Reset channel information.
 */
static void reset_chan_info(struct chanset_t *chan, int reset)
{
    char beI[4] = "\0";
    /* Leave the channel if we aren't supposed to be there */
    if (channel_inactive(chan)) {
        dprintf(DP_MODE, "PART %s\n", chan->name);
        return;
    }

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

    clear_channel(chan, reset);
    if ((reset & CHAN_RESETBANS) && !(chan->status & CHAN_ASKEDBANS)) {
        chan->status |= CHAN_ASKEDBANS;
        strcat(beI, "b");
    }
    if ((reset & CHAN_RESETEXEMPTS) &&
            !(chan->ircnet_status & CHAN_ASKED_EXEMPTS) && (use_exempts == 1)) {
        chan->ircnet_status |= CHAN_ASKED_EXEMPTS;
        strcat(beI, "e");
    }
    if ((reset & CHAN_RESETINVITED) &&
            !(chan->ircnet_status & CHAN_ASKED_INVITED) && (use_invites == 1)) {
        chan->ircnet_status |= CHAN_ASKED_INVITED;
        strcat(beI, "I");
    }
    if (beI[0])
        dprintf(DP_MODE, "MODE %s +%s\n", chan->name, beI);
    if (reset & CHAN_RESETMODES) {
        /* done here to keep expmem happy, as this is accounted in
           irc.mod, not channels.mod where clear_channel() resides */
        nfree(chan->channel.key);
        chan->channel.key = (char *) channel_malloc (1);
        chan->channel.key[0] = 0;
        chan->status &= ~CHAN_ASKEDMODES;
        dprintf(DP_MODE, "MODE %s\n", chan->name);
    }
    if (reset & CHAN_RESETWHO) {
        chan->status |= CHAN_PEND;
        chan->status &= ~CHAN_ACTIVE;
        refresh_who_chan(chan->name);
    }
    if (reset & CHAN_RESETTOPIC)
        dprintf(DP_MODE, "TOPIC %s\n", chan->name);
}
示例#7
0
文件: irc.c 项目: Estella/eggdrop-1.8
/* Report the channel status of every active channel to dcc chat every
 * 5 minutes.
 */
static void status_log()
{
    masklist *b;
    memberlist *m;
    struct chanset_t *chan;
    char s[20], s2[20];
    int chops, halfops, voice, nonops, bans, invites, exempts;

    if (!server_online)
        return;

    for (chan = chanset; chan != NULL; chan = chan->next) {
        if (channel_active(chan) && channel_logstatus(chan) &&
                !channel_inactive(chan)) {
            chops = 0;
            voice = 0;
            halfops = 0;
            for (m = chan->channel.member; m && m->nick[0]; m = m->next) {
                if (chan_hasop(m))
                    chops++;
                else if (chan_hashalfop(m))
                    halfops++;
                else if (chan_hasvoice(m))
                    voice++;
            }
            nonops = (chan->channel.members - (chops + voice + halfops));

            for (bans = 0, b = chan->channel.ban; b->mask[0]; b = b->next)
                bans++;
            for (exempts = 0, b = chan->channel.exempt; b->mask[0]; b = b->next)
                exempts++;
            for (invites = 0, b = chan->channel.invite; b->mask[0]; b = b->next)
                invites++;

            sprintf(s, "%d", exempts);
            sprintf(s2, "%d", invites);

            putlog(LOG_MISC, chan->dname,
                   "%s%s (%s) : [m/%d o/%d h/%d v/%d n/%d b/%d e/%s I/%s]",
                   me_op(chan) ? "@" : me_voice(chan) ? "+" :
                   me_halfop(chan) ? "%" : "", chan->dname, getchanmode(chan),
                   chan->channel.members, chops, halfops, voice, nonops, bans,
                   use_exempts ? s : "-", use_invites ? s2 : "-");
        }
    }
}
示例#8
0
文件: channels.c 项目: Mafaioz/wraith
static void got_jn(int idx, char *code, char *par)
{
  char *chname = newsplit(&par);

  if (!chname || !chname[0]) 
    return;

  struct chanset_t *chan = NULL;

  if (!(chan = findchan_by_dname(chname))) return;
  if (chan->channel.jointime && channel_inactive(chan)) {
    chan->status &= ~CHAN_INACTIVE;
    chan->channel.jointime = 0;
    if (!conf.bot->hub && shouldjoin(chan))
      join_chan(chan);
  }
}
示例#9
0
static void channels_rehash()
{
  struct chanset_t *chan;

  setstatic = 0;
  read_channels(1);
  /* remove any extra channels */
  chan = chanset;
  while (chan) {
    if (chan->status & CHAN_FLAGGED) {
      putlog(LOG_MISC, "*", "No longer supporting channel %s", chan->name);
      if (!channel_inactive(chan))
	dprintf(DP_SERVER, "PART %s\n", chan->name);
      remove_channel(chan);
      chan = chanset;
    } else
      chan = chan->next;
  }
}
示例#10
0
文件: irc.c 项目: Estella/eggdrop-1.8
static void irc_report(int idx, int details)
{
    struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 };
    char ch[1024], q[256], *p;
    int k, l;
    struct chanset_t *chan;

    strcpy(q, "Channels: ");
    k = 10;
    for (chan = chanset; chan; chan = chan->next) {
        if (idx != DP_STDOUT)
            get_user_flagrec(dcc[idx].user, &fr, chan->dname);
        if ((idx == DP_STDOUT) || glob_master(fr) || chan_master(fr)) {
            p = NULL;
            if (!channel_inactive(chan)) {
                if (chan->status & CHAN_JUPED)
                    p = MISC_JUPED;
                else if (!(chan->status & CHAN_ACTIVE))
                    p = MISC_TRYING;
                else if (chan->status & CHAN_PEND)
                    p = MISC_PENDING;
                else if ((chan->dname[0] != '+') && !me_op(chan))
                    p = MISC_WANTOPS;
            }
            l = simple_sprintf(ch, "%s%s%s%s, ", chan->dname, p ? " (" : "",
                               p ? p : "", p ? ")" : "");
            if ((k + l) > 70) {
                dprintf(idx, "    %s\n", q);
                strcpy(q, "          ");
                k = 10;
            }
            k += my_strcpy(q + k, ch);
        }
    }
    if (k > 10) {
        q[k - 2] = 0;
        dprintf(idx, "    %s\n", q);
    }
}
示例#11
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);
        }
    }
}
示例#12
0
文件: irc.c 项目: Estella/eggdrop-1.8
char *irc_start(Function *global_funcs)
{
    struct chanset_t *chan;

    global = global_funcs;

    module_register(MODULE_NAME, irc_table, 1, 5);
    if (!module_depend(MODULE_NAME, "eggdrop", 108, 0)) {
        module_undepend(MODULE_NAME);
        return "This module requires Eggdrop 1.8.0 or later.";
    }
    if (!(server_funcs = module_depend(MODULE_NAME, "server", 1, 0))) {
        module_undepend(MODULE_NAME);
        return "This module requires server module 1.0 or later.";
    }
    if (!(channels_funcs = module_depend(MODULE_NAME, "channels", 1, 1))) {
        module_undepend(MODULE_NAME);
        return "This module requires channels module 1.1 or later.";
    }
    for (chan = chanset; chan; chan = chan->next) {
        if (!channel_inactive(chan)) {
            if (chan->key_prot[0])
                dprintf(DP_SERVER, "JOIN %s %s\n",
                        chan->name[0] ? chan->name : chan->dname, chan->key_prot);
            else
                dprintf(DP_SERVER, "JOIN %s\n",
                        chan->name[0] ? chan->name : chan->dname);
        }
        chan->status &= ~(CHAN_ACTIVE | CHAN_PEND | CHAN_ASKEDBANS);
        chan->ircnet_status &= ~(CHAN_ASKED_INVITED | CHAN_ASKED_EXEMPTS);
    }
    add_hook(HOOK_MINUTELY, (Function) check_expired_chanstuff);
    add_hook(HOOK_5MINUTELY, (Function) status_log);
    add_hook(HOOK_ADD_MODE, (Function) real_add_mode);
    add_hook(HOOK_IDLE, (Function) flush_modes);
    Tcl_TraceVar(interp, "net-type",
                 TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
                 traced_nettype, NULL);
    Tcl_TraceVar(interp, "rfc-compliant",
                 TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
                 traced_rfccompliant, NULL);
    strcpy(opchars, "@");
    add_tcl_strings(mystrings);
    add_tcl_ints(myints);
    add_builtins(H_dcc, irc_dcc);
    add_builtins(H_msg, C_msg);
    add_builtins(H_raw, irc_raw);
    add_tcl_commands(tclchan_cmds);
    add_help_reference("irc.help");
    H_topc = add_bind_table("topc", HT_STACKABLE, channels_5char);
    H_splt = add_bind_table("splt", HT_STACKABLE, channels_4char);
    H_sign = add_bind_table("sign", HT_STACKABLE, channels_5char);
    H_rejn = add_bind_table("rejn", HT_STACKABLE, channels_4char);
    H_part = add_bind_table("part", HT_STACKABLE, channels_5char);
    H_nick = add_bind_table("nick", HT_STACKABLE, channels_5char);
    H_mode = add_bind_table("mode", HT_STACKABLE, channels_6char);
    H_kick = add_bind_table("kick", HT_STACKABLE, channels_6char);
    H_join = add_bind_table("join", HT_STACKABLE, channels_4char);
    H_pubm = add_bind_table("pubm", HT_STACKABLE, channels_5char);
    H_pub = add_bind_table("pub", 0, channels_5char);
    H_need = add_bind_table("need", HT_STACKABLE, channels_2char);
    do_nettype();
    return NULL;
}
示例#13
0
/*
 * Note:
 *  - We write chanmode "" too, so that the bot won't use default-chanmode
 *    instead of ""
 *  - We will write empty need-xxxx too, why not? (less code + lazyness)
 */
static void write_channels()
{
  FILE *f;
  char s[121], w[1024], w2[1024], name[163];
  char need1[242], need2[242], need3[242], need4[242], need5[242];
  struct chanset_t *chan;
  struct udef_struct *ul;

  if (!chanfile[0])
    return;
  sprintf(s, "%s~new", chanfile);
  f = fopen(s, "w");
  chmod(s, userfile_perm);
  if (f == NULL) {
    putlog(LOG_MISC, "*", "ERROR writing channel file.");
    return;
  }
  if (!quiet_save)
    putlog(LOG_MISC, "*", "Writing channel file...");
  fprintf(f, "#Dynamic Channel File for %s (%s) -- written %s\n",
          botnetnick, ver, ctime(&now));
  for (chan = chanset; chan; chan = chan->next) {
    convert_element(chan->dname, name);
    get_mode_protect(chan, w);
    convert_element(w, w2);
    convert_element(chan->need_op, need1);
    convert_element(chan->need_invite, need2);
    convert_element(chan->need_key, need3);
    convert_element(chan->need_unban, need4);
    convert_element(chan->need_limit, need5);
    fprintf(f,
            "channel add %s { chanmode %s idle-kick %d stopnethack-mode %d "
            "revenge-mode %d need-op %s need-invite %s need-key %s "
            "need-unban %s need-limit %s flood-chan %d:%d flood-ctcp %d:%d "
            "flood-join %d:%d flood-kick %d:%d flood-deop %d:%d "
            "flood-nick %d:%d aop-delay %d:%d ban-type %d ban-time %d "
            "exempt-time %d invite-time %d %cenforcebans %cdynamicbans "
            "%cuserbans %cautoop %cautohalfop %cbitch %cgreet %cprotectops "
            "%cprotecthalfops %cprotectfriends %cdontkickops %cstatuslog "
            "%crevenge %crevengebot %cautovoice %csecret %cshared %ccycle "
            "%cseen %cinactive %cdynamicexempts %cuserexempts %cdynamicinvites "
            "%cuserinvites %cnodesynch %cstatic }" "\n",
            name, w2, chan->idle_kick, chan->stopnethack_mode,
            chan->revenge_mode, need1, need2, need3, need4, need5,
            chan->flood_pub_thr, chan->flood_pub_time,
            chan->flood_ctcp_thr, chan->flood_ctcp_time,
            chan->flood_join_thr, chan->flood_join_time,
            chan->flood_kick_thr, chan->flood_kick_time,
            chan->flood_deop_thr, chan->flood_deop_time,
            chan->flood_nick_thr, chan->flood_nick_time,
            chan->aop_min, chan->aop_max, chan->ban_type, chan->ban_time,
            chan->exempt_time, chan->invite_time,
            PLSMNS(channel_enforcebans(chan)),
            PLSMNS(channel_dynamicbans(chan)),
            PLSMNS(!channel_nouserbans(chan)),
            PLSMNS(channel_autoop(chan)),
            PLSMNS(channel_autohalfop(chan)),
            PLSMNS(channel_bitch(chan)),
            PLSMNS(channel_greet(chan)),
            PLSMNS(channel_protectops(chan)),
            PLSMNS(channel_protecthalfops(chan)),
            PLSMNS(channel_protectfriends(chan)),
            PLSMNS(channel_dontkickops(chan)),
            PLSMNS(channel_logstatus(chan)),
            PLSMNS(channel_revenge(chan)),
            PLSMNS(channel_revengebot(chan)),
            PLSMNS(channel_autovoice(chan)),
            PLSMNS(channel_secret(chan)),
            PLSMNS(channel_shared(chan)),
            PLSMNS(channel_cycle(chan)),
            PLSMNS(channel_seen(chan)),
            PLSMNS(channel_inactive(chan)),
            PLSMNS(channel_dynamicexempts(chan)),
            PLSMNS(!channel_nouserexempts(chan)),
            PLSMNS(channel_dynamicinvites(chan)),
            PLSMNS(!channel_nouserinvites(chan)),
            PLSMNS(channel_nodesynch(chan)),
            PLSMNS(channel_static(chan)));
    for (ul = udef; ul; ul = ul->next) {
      if (ul->defined && ul->name) {
        if (ul->type == UDEF_FLAG)
          fprintf(f, "channel set %s %c%s%s\n", name, getudef(ul->values,
                  chan->dname) ? '+' : '-', "udef-flag-", ul->name);
        else if (ul->type == UDEF_INT)
          fprintf(f, "channel set %s %s%s %d\n", name, "udef-int-", ul->name,
                  (int) getudef(ul->values, chan->dname));
        else if (ul->type == UDEF_STR) {
          char *p = (char *) getudef(ul->values, chan->dname);

          if (!p)
            p = "{}";

          fprintf(f, "channel set %s udef-str-%s %s\n", name, ul->name, p);
        } else
          debug1("UDEF-ERROR: unknown type %d", ul->type);
      }
    }
    if (fflush(f)) {
      putlog(LOG_MISC, "*", "ERROR writing channel file.");
      fclose(f);
      return;
    }
  }
  fclose(f);
  unlink(chanfile);
  movefile(s, chanfile);
}
示例#14
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");
    }
  }
}
示例#15
0
文件: cmdschan.c 项目: kirune/wraith
static void cmd_chaninfo(int idx, char *par)
{
  char *chname = NULL, work[512] = "";
  struct chanset_t *chan = NULL;
  int cnt = 0;

  if (!par[0]) {
    chname = dcc[idx].u.chat->con_chan;
    if (chname[0] == '*') {
      dprintf(idx, "Your console channel is invalid.\n");
      return;
    }
  } else {
    chname = newsplit(&par);
    get_user_flagrec(dcc[idx].user, &user, chname);
    if (!glob_master(user) && !chan_master(user)) {
      dprintf(idx, "You don't have access to %s.\n", chname);
      return;
    }
  }
  if (!strcasecmp(chname, "default"))
    chan = chanset_default;
  else
    chan = findchan_by_dname(chname);
  if (!chan || (chan && privchan(user, chan, PRIV_OP))) {
    dprintf(idx, "No such channel.\n");
    return;
  } else {
    char nick[HANDLEN + 1] = "", date[81] = "";
    int deflag = 0;

    if (chan->added_ts) {
      strftime(date, sizeof date, "%c %Z", gmtime(&(chan->added_ts)));
    } else
      date[0] = 0;
    if (chan->added_by && chan->added_by[0])
      strlcpy(nick, chan->added_by, sizeof(nick));
    else
      nick[0] = 0;
    putlog(LOG_CMDS, "*", "#%s# chaninfo %s", dcc[idx].nick, chname);
    if (nick[0] && date[0])
      dprintf(idx, "Settings for channel %s (Added %s by %s%s%s):\n", chan->dname, date, BOLD(idx), nick, BOLD_END(idx));
    else
      dprintf(idx, "Settings for channel %s:\n", chan->dname);
/* FIXME: SHOW_CHAR() here */
    get_mode_protect(chan, work, sizeof(work));
    dprintf(idx, "Protect modes (chanmode): %s\n", work[0] ? work : "None");
    dprintf(idx, "Groups: %s\n", chan->groups && chan->groups->length() ? static_cast<bd::String>(chan->groups->join(" ")).c_str() : "None");
    dprintf(idx, "FiSH Key: %s\n", chan->fish_key[0] ? chan->fish_key : "not set");
//    dprintf(idx, "Protect topic (topic)   : %s\n", chan->topic[0] ? chan->topic : "");
/* Chanchar template
 *  dprintf(idx, "String temp: %s\n", chan->temp[0] ? chan->temp : "NULL");
 */
    dprintf(idx, "Channel flags:\n");
    work[0] = 0;
    SHOW_FLAG("autoop",		channel_autoop(chan));
    SHOW_FLAG("backup",		channel_backup(chan));
    SHOW_FLAG("bitch",		channel_bitch(chan));
    SHOW_FLAG("botbitch",       channel_botbitch(chan));
    SHOW_FLAG("closed",		channel_closed(chan));
    SHOW_FLAG("cycle",		channel_cycle(chan));
    SHOW_FLAG("enforcebans", 	channel_enforcebans(chan));
    SHOW_FLAG("fastop",		channel_fastop(chan));
    SHOW_FLAG("floodban", channel_floodban(chan));
    SHOW_FLAG("inactive",	channel_inactive(chan));
    SHOW_FLAG("nodesynch",	channel_nodesynch(chan));
    SHOW_FLAG("private",	channel_privchan(chan));
    SHOW_FLAG("protect",	channel_protect(chan));
    SHOW_FLAG("rbl",		channel_rbl(chan));
    if (HAVE_TAKE)
      SHOW_FLAG("take",		channel_take(chan));
    SHOW_FLAG("voice",		channel_voice(chan));
    SHOW_FLAG("voicebitch",		channel_voicebitch(chan));
    SHOW_FLAG("", 0);
    SHOW_FLAG("dynamicbans",	channel_dynamicbans(chan));
    SHOW_FLAG("userbans",	!channel_nouserbans(chan));
    SHOW_FLAG("dynamicexempts",	channel_dynamicexempts(chan));
    SHOW_FLAG("userexempts",	!channel_nouserexempts(chan));
    SHOW_FLAG("dynamicinvites",	channel_dynamicinvites(chan));
    SHOW_FLAG("userinvites",	!channel_nouserinvites(chan));
    SHOW_FLAG("", 0);
    work[0] = 0;

/* Chanflag template
 *  SHOW_FLAG("template", channel_template(chan));
 * also include %ctemp in dprintf.
 */

    work[0] = cnt = 0;
/* Chanint template
 * SHOW_INT("Desc: ", integer, "YES", "NO");
 */
    dprintf(idx, "Channel settings:\n");
    deflag = chan->bad_cookie;
    SHOW_INT("Auto-delay: ", chan->auto_delay, NULL, "None");
    SHOW_INT("Bad-cookie:" , chan->bad_cookie, DEFLAG_STR, "Ignore");
    SHOW_INT("Ban-time: ", chan->ban_time, NULL, "Forever");
    SHOW_INT("Ban-type: ", chan->ban_type, NULL, "3");
    SHOW_INT("Closed-ban: ", chan->closed_ban, NULL, "Don't!");
    SHOW_INT("Closed-invite:", chan->closed_invite, NULL, "Don't!");
    SHOW_INT("Closed-Private:", chan->closed_private, NULL, "Don't!");
    SHOW_INT("Closed-Exempt:", chan->closed_exempt_mode, F_STR(chan->closed_exempt_mode), "None");
    SHOW_INT("Exempt-time: ", chan->exempt_time, NULL, "Forever");
    SHOW_INT("Flood-exempt: ", chan->flood_exempt_mode, F_STR(chan->flood_exempt_mode), "None");
    SHOW_INT("Flood-lock-time: ", chan->flood_lock_time, NULL, "Don't");
    SHOW_INT("Caps-Limit(%): ", chan->capslimit, NULL, "None");
    SHOW_INT("Color-Limit: ", chan->colorlimit, NULL, "None");
    SHOW_INT("Invite-time: ", chan->invite_time, NULL, "Forever");
    SHOW_INT("Knock: ", chan->knock_flags, F_STR(chan->knock_flags), "None");
    SHOW_INT("Limit raise (limit): ", chan->limitraise, NULL, "Disabled");
    deflag = chan->manop;
    SHOW_INT("Manop: ", chan->manop, DEFLAG_STR, "Ignore");
    deflag = chan->mdop;
    SHOW_INT("Mdop: ", chan->mdop, DEFLAG_STR, "Ignore");
    deflag = chan->mop;
    SHOW_INT("Mop: ", chan->mop, DEFLAG_STR, "Ignore");
    deflag = chan->revenge;
    SHOW_INT("Revenge: ", chan->revenge, DEFLAG_STR, "Ignore");
    SHOW_INT("Protect-backup: ", chan->protect_backup, "Do!", "Don't!");
    SHOW_INT("Voice-non-ident: ", chan->voice_non_ident, "Do!", "Don't!");
    SHOW_INT("Voice-moderate:", chan->voice_moderate, "Do!", "Don't!");

    dprintf(idx, "Flood settings:   chan bytes ctcp join kick deop nick mjoin mpub mbytes mctcp\n");
    dprintf(idx, "  number:          %3d  %4d  %3d  %3d  %3d  %3d  %3d   %3d  %3d   %4d   %3d\n",
	    chan->flood_pub_thr, chan->flood_bytes_thr, chan->flood_ctcp_thr,
	    chan->flood_join_thr, chan->flood_kick_thr,
	    chan->flood_deop_thr, chan->flood_nick_thr,
            chan->flood_mjoin_thr, chan->flood_mpub_thr,
            chan->flood_mbytes_thr, chan->flood_mctcp_thr);
    dprintf(idx, "  time  :          %3u  %4u  %3u  %3u  %3u  %3u  %3u   %3u  %3u   %4u  %4u\n",
	    chan->flood_pub_time, chan->flood_bytes_time, chan->flood_ctcp_time,
	    chan->flood_join_time, chan->flood_kick_time,
	    chan->flood_deop_time, chan->flood_nick_time,
            chan->flood_mjoin_time, chan->flood_mpub_time,
            chan->flood_mbytes_time, chan->flood_mctcp_time);
  }
}
示例#16
0
static void channels_report(int idx, int details)
{
  struct chanset_t *chan;
  int i;
  char s[1024], s2[100];
  struct flag_record fr = { FR_CHAN | FR_GLOBAL, 0, 0, 0, 0, 0 };

  for (chan = chanset; chan; chan = chan->next) {
    if (idx != DP_STDOUT)
      get_user_flagrec(dcc[idx].user, &fr, chan->dname);
    if ((idx == DP_STDOUT) || glob_master(fr) || chan_master(fr)) {
      s[0] = 0;
      if (channel_greet(chan))
        strcat(s, "greet, ");
      if (channel_autoop(chan))
        strcat(s, "auto-op, ");
      if (channel_bitch(chan))
        strcat(s, "bitch, ");
      if (s[0])
        s[strlen(s) - 2] = 0;
      if (!s[0])
        strcpy(s, MISC_LURKING);
      get_mode_protect(chan, s2);
      if (!channel_inactive(chan)) {
        if (channel_active(chan)) {
          /* If it's a !chan, we want to display it's unique name too <cybah> */
          if (chan->dname[0] == '!') {
            dprintf(idx, "    %-20s: %3d member%s enforcing \"%s\" (%s), "
                    "unique name %s\n", chan->dname, chan->channel.members,
                    (chan->channel.members == 1) ? "," : "s,", s2, s,
                    chan->name);
          } else {
            dprintf(idx, "    %-20s: %3d member%s enforcing \"%s\" (%s)\n",
                    chan->dname, chan->channel.members,
                    chan->channel.members == 1 ? "," : "s,", s2, s);
          }
        } else {
          dprintf(idx, "    %-20s: (%s), enforcing \"%s\"  (%s)\n", chan->dname,
                  channel_pending(chan) ? "pending" : "not on channel", s2, s);
        }
      } else {
        dprintf(idx, "    %-20s: channel is set +inactive\n", chan->dname);
      }
      if (details) {
        s[0] = 0;
        i = 0;
        if (channel_enforcebans(chan))
          i += my_strcpy(s + i, "enforcebans ");
        if (channel_dynamicbans(chan))
          i += my_strcpy(s + i, "dynamicbans ");
        if (!channel_nouserbans(chan))
          i += my_strcpy(s + i, "userbans ");
        if (channel_autoop(chan))
          i += my_strcpy(s + i, "autoop ");
        if (channel_bitch(chan))
          i += my_strcpy(s + i, "bitch ");
        if (channel_greet(chan))
          i += my_strcpy(s + i, "greet ");
        if (channel_protectops(chan))
          i += my_strcpy(s + i, "protectops ");
        if (channel_protecthalfops(chan))
          i += my_strcpy(s + i, "protecthalfops ");
        if (channel_protectfriends(chan))
          i += my_strcpy(s + i, "protectfriends ");
        if (channel_dontkickops(chan))
          i += my_strcpy(s + i, "dontkickops ");
        if (channel_logstatus(chan))
          i += my_strcpy(s + i, "statuslog ");
        if (channel_revenge(chan))
          i += my_strcpy(s + i, "revenge ");
        if (channel_revenge(chan))
          i += my_strcpy(s + i, "revengebot ");
        if (channel_secret(chan))
          i += my_strcpy(s + i, "secret ");
        if (channel_shared(chan))
          i += my_strcpy(s + i, "shared ");
        if (!channel_static(chan))
          i += my_strcpy(s + i, "dynamic ");
        if (channel_autovoice(chan))
          i += my_strcpy(s + i, "autovoice ");
        if (channel_autohalfop(chan))
          i += my_strcpy(s + i, "autohalfop ");
        if (channel_cycle(chan))
          i += my_strcpy(s + i, "cycle ");
        if (channel_dynamicexempts(chan))
          i += my_strcpy(s + i, "dynamicexempts ");
        if (!channel_nouserexempts(chan))
          i += my_strcpy(s + i, "userexempts ");
        if (channel_dynamicinvites(chan))
          i += my_strcpy(s + i, "dynamicinvites ");
        if (!channel_nouserinvites(chan))
          i += my_strcpy(s + i, "userinvites ");
        if (channel_inactive(chan))
          i += my_strcpy(s + i, "inactive ");
        if (channel_nodesynch(chan))
          i += my_strcpy(s + i, "nodesynch ");
        dprintf(idx, "      Options: %s\n", s);
        if (chan->need_op[0])
          dprintf(idx, "      To get ops, I do: %s\n", chan->need_op);
        if (chan->need_invite[0])
          dprintf(idx, "      To get invited, I do: %s\n", chan->need_invite);
        if (chan->need_limit[0])
          dprintf(idx, "      To get the channel limit raised, I do: %s\n",
                  chan->need_limit);
        if (chan->need_unban[0])
          dprintf(idx, "      To get unbanned, I do: %s\n", chan->need_unban);
        if (chan->need_key[0])
          dprintf(idx, "      To get the channel key, I do: %s\n",
                  chan->need_key);
        if (chan->stopnethack_mode)
          dprintf(idx, "      stopnethack-mode: %d\n", chan->stopnethack_mode);
        if (chan->revenge_mode)
          dprintf(idx, "      revenge-mode: %d\n", chan->revenge_mode);
        dprintf(idx, "      Bans last %d minute%s.\n", chan->ban_time,
                 (chan->ban_time != 1) ? "s" : "");
        dprintf(idx, "      Exemptions last %d minute%s.\n", chan->exempt_time,
                 (chan->exempt_time != 1) ? "s" : "");
        dprintf(idx, "      Invitations last %d minute%s.\n", chan->invite_time,
                 (chan->invite_time != 1) ? "s" : "");
      }
    }
  }
}
示例#17
0
static void channels_report(int idx, int details)
{
  struct chanset_t *chan;
  int i;
  char s[1024], s2[100];
  struct flag_record fr =
  {FR_CHAN | FR_GLOBAL, 0, 0, 0, 0, 0};

  chan = chanset;
  while (chan != NULL) {
    if (idx != DP_STDOUT)
      get_user_flagrec(dcc[idx].user, &fr, chan->name);
    if ((idx == DP_STDOUT) || glob_master(fr) || chan_master(fr)) {
      s[0] = 0;
      if (channel_greet(chan))
	strcat(s, "greet, ");
      if (channel_autoop(chan))
	strcat(s, "auto-op, ");
      if (channel_bitch(chan))
	strcat(s, "bitch, ");
      if (s[0])
	s[strlen(s) - 2] = 0;
      if (!s[0])
	strcpy(s, MISC_LURKING);
      get_mode_protect(chan, s2);
      if (!channel_inactive(chan)) {
	if (channel_active(chan)) {
	  dprintf(idx, "    %-10s: %2d member%s enforcing \"%s\" (%s)\n", chan->name,
		  chan->channel.members, chan->channel.members == 1 ? "," : "s,", s2, s);
	} else {
	  dprintf(idx, "    %-10s: (%s), enforcing \"%s\"  (%s)\n", chan->name,
		  channel_pending(chan) ? "pending" : "inactive", s2, s);
	}
      } else {
	dprintf(idx, "    %-10s: no IRC support for this channel\n", chan->name);
      }
      if (details) {
	s[0] = 0;
	i = 0;
	if (channel_clearbans(chan))
	  i += my_strcpy(s + i, "clear-bans ");
	if (channel_enforcebans(chan))
	  i += my_strcpy(s + i, "enforce-bans ");
	if (channel_dynamicbans(chan))
	  i += my_strcpy(s + i, "dynamic-bans ");
	if (channel_nouserbans(chan))
	  i += my_strcpy(s + i, "forbid-user-bans ");
	if (channel_autoop(chan))
	  i += my_strcpy(s + i, "op-on-join ");
	if (channel_bitch(chan))
	  i += my_strcpy(s + i, "bitch ");
	if (channel_greet(chan))
	  i += my_strcpy(s + i, "greet ");
	if (channel_protectops(chan))
	  i += my_strcpy(s + i, "protect-ops ");
        if (channel_protectfriends(chan))
          i += my_strcpy(s + i, "protect-friends ");
	if (channel_dontkickops(chan))
	  i += my_strcpy(s + i, "dont-kick-ops ");
	if (channel_wasoptest(chan))
	  i += my_strcpy(s + i, "was-op-test ");
	if (channel_logstatus(chan))
	  i += my_strcpy(s + i, "log-status ");
	if (channel_revenge(chan))
	  i += my_strcpy(s + i, "revenge ");
	if (channel_stopnethack(chan))
	  i += my_strcpy(s + i, "stopnethack ");
	if (channel_secret(chan))
	  i += my_strcpy(s + i, "secret ");
	if (channel_shared(chan))
	  i += my_strcpy(s + i, "shared ");
	if (!channel_static(chan))
	  i += my_strcpy(s + i, "dynamic ");
	if (channel_autovoice(chan))
	  i += my_strcpy(s + i, "autovoice ");
	if (channel_cycle(chan))
	  i += my_strcpy(s + i, "cycle ");
	if (channel_seen(chan))
	  i += my_strcpy(s + i, "seen ");
	if (channel_dynamicexempts(chan))
	  i += my_strcpy(s + i, "dynamic-exempts ");
	if (channel_nouserexempts(chan))
	  i += my_strcpy(s + i, "forbid-user-exempts ");
	if (channel_dynamicinvites(chan))
	  i += my_strcpy(s + i, "dynamic-invites ");
	if (channel_nouserinvites(chan))
	  i += my_strcpy(s + i, "forbid-user-invites ");
	if (channel_inactive(chan))
	  i += my_strcpy(s + i, "inactive ");
	dprintf(idx, "      Options: %s\n", s);
	if (chan->need_op[0])
	  dprintf(idx, "      To get ops I do: %s\n", chan->need_op);
	if (chan->need_invite[0])
	  dprintf(idx, "      To get invited I do: %s\n", chan->need_invite);
	if (chan->need_limit[0])
	  dprintf(idx, "      To get the channel limit up'd I do: %s\n", chan->need_limit);
	if (chan->need_unban[0])
	  dprintf(idx, "      To get unbanned I do: %s\n", chan->need_unban);
	if (chan->need_key[0])
	  dprintf(idx, "      To get the channel key I do: %s\n", chan->need_key);
	if (chan->idle_kick)
	  dprintf(idx, "      Kicking idle users after %d min\n", chan->idle_kick);
      }
    }
    chan = chan->next;
  }
  if (details) {
    dprintf(idx, "    Bans last %d mins.\n", ban_time);
    dprintf(idx, "    Exemptions last %d mins.\n", exempt_time);
    dprintf(idx, "    Invitations last %d mins.\n", invite_time);
  }
}
示例#18
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);
        }
    }
}
示例#19
0
/* Parse options for a channel.
 */
static int tcl_channel_modify(Tcl_Interp * irp, struct chanset_t *chan,
			      int items, char **item)
{
  int i, x = 0, found,
      old_status = chan->status,
      old_mode_mns_prot = chan->mode_mns_prot,
      old_mode_pls_prot = chan->mode_pls_prot;
  struct udef_struct *ul = udef;
  char s[121];
  module_entry *me;

  for (i = 0; i < items; i++) {
    if (!strcmp(item[i], "chanmode")) {
      i++;
      if (i >= items) {
	if (irp)
	  Tcl_AppendResult(irp, "channel chanmode needs argument", NULL);
	return TCL_ERROR;
      }
      strlcpy(s, item[i], sizeof s);
      set_mode_protect(chan, s);
    } else if (!strcmp(item[i], "ban_time")) {
      i++;
      if (i >= items) {
        if (irp)
          Tcl_AppendResult(irp, "channel ban_time needs argument", NULL);
        return TCL_ERROR;
      }
      chan->ban_time = atoi(item[i]);
    } else if (!strcmp(item[i], "exempt_time")) {
      i++;
      if (i >= items) {
        if (irp)
          Tcl_AppendResult(irp, "channel exempt_time needs argument", NULL);
        return TCL_ERROR;
      }
      chan->exempt_time = atoi(item[i]);
    } else if (!strcmp(item[i], "invite_time")) {
      i++;
      if (i >= items) {
        if (irp)
          Tcl_AppendResult(irp, "channel invite_time needs argument", NULL);
        return TCL_ERROR;
      }
      chan->invite_time = atoi(item[i]);
    }
    else if (item[i][0] == '+' || item[i][0] == '-') {
      int flagval;

      if (lookup_flag_by_name(normal_flag_map, item[i]+1, &flagval)) {
        if (item[i][0] == '-') chan->status &= ~flagval;
        else chan->status |= flagval;
      }
      else if (lookup_flag_by_name(stupid_ircnet_flag_map, item[i]+1, &flagval)) {
        if (item[i][0] == '-') chan->ircnet_status &= ~flagval;
        else chan->ircnet_status |= flagval;
      }
      else {
        /* Hopefully it's a user-defined flag! */
        goto check_for_udef_flags;
      }
    } else if (!strncmp(item[i], "aop_delay", 9)) {
      char *p;
      i++;
      if (i >= items) {
	if (irp)
	  Tcl_AppendResult(irp, item[i - 1], " needs argument", NULL);
	return TCL_ERROR;
      }
      p = strchr(item[i], ':');
      if (p) {
	p++;
	chan->aop_min = atoi(item[i]);
	chan->aop_max = atoi(p);
      } else {
	chan->aop_min = atoi(item[i]);
	chan->aop_max = chan->aop_min;
      }
    } else {
      if (!strncmp(item[i] + 1, "udef_flag_", 10))
        initudef(UDEF_FLAG, item[i] + 11, 0);
      else if (!strncmp(item[i], "udef_int_", 9))
        initudef(UDEF_INT, item[i] + 9, 0);
	else if (!strncmp(item[i], "udef_str_", 9))
		initudef(UDEF_STR, item[i] + 9, 0);
check_for_udef_flags:
      found = 0;
      for (ul = udef; ul; ul = ul->next) {
        if (ul->type == UDEF_FLAG &&
	     /* Direct match when set during .chanset ... */
	    (!strcasecmp(item[i] + 1, ul->name) ||
	     /* ... or with prefix when set during chanfile load. */
	     (!strncmp(item[i] + 1, "udef_flag_", 10) &&
	      !strcasecmp(item[i] + 11, ul->name)))) {
          if (item[i][0] == '+')
            setudef(ul, chan->dname, 1);
          else
            setudef(ul, chan->dname, 0);
          found = 1;
	  break;
        } else if (ul->type == UDEF_INT &&
		    /* Direct match when set during .chanset ... */
		   (!strcasecmp(item[i], ul->name) ||
		    /* ... or with prefix when set during chanfile load. */
		    (!strncmp(item[i], "udef_int_", 9) &&
		     !strcasecmp(item[i] + 9, ul->name)))) {
          i++;
          if (i >= items) {
            if (irp)
              Tcl_AppendResult(irp, "this setting needs an argument", NULL);
            return TCL_ERROR;
          }
          setudef(ul, chan->dname, atoi(item[i]));
          found = 1;
	  break;
        }
	else if (ul->type == UDEF_STR && (!strcasecmp(item[i], ul->name) || (!strncmp(item[i], "udef_str_", 9) && !strcasecmp(item[i] + 9, ul->name)))) {
		char *val;
		i++;
		if (i >= items) {
			if (irp) Tcl_AppendResult(irp, "this setting needs an argument", NULL);
			return TCL_ERROR;
		}
		val = (char *)getudef(ul->values, chan->dname);
		if (val) free(val);
		/* Get extra room for new braces, etc */
		val = malloc(3 * strlen(item[i]) + 10);
		convert_element(item[i], val);
		val = realloc(val, strlen(val)+1);
		setudef(ul, chan->dname, (int)val);
		found = 1;
		break;
	}
      }
      if (!found) {
        if (irp && item[i][0]) /* ignore "" */
      	  Tcl_AppendResult(irp, "illegal channel option: ", item[i], NULL);
      	x++;
      }
    }
  }
  /* If protect_readonly == 0 and chan_hack == 0 then
   * bot is now processing the configfile, so dont do anything,
   * we've to wait the channelfile that maybe override these settings
   * (note: it may cause problems if there is no chanfile!)
   * <drummer/1999/10/21>
   */
  if (protect_readonly || chan_hack) {
    if (((old_status ^ chan->status) & CHAN_INACTIVE) &&
	module_find("irc", 0, 0)) {
      if (channel_inactive(chan) &&
	  (chan->status & (CHAN_ACTIVE | CHAN_PEND)))
	dprintf(DP_SERVER, "PART %s\n", chan->name);
      if (!channel_inactive(chan) &&
	  !(chan->status & (CHAN_ACTIVE | CHAN_PEND)))
	dprintf(DP_SERVER, "JOIN %s %s\n", (chan->name[0]) ?
					   chan->name : chan->dname,
					   chan->channel.key[0] ?
					   chan->channel.key : chan->key_prot);
    }
    if ((old_status ^ chan->status) &
	(CHAN_ENFORCEBANS | CHAN_OPONJOIN | CHAN_AUTOVOICE)) {
      if ((me = module_find("irc", 0, 0)))
	(me->funcs[IRC_RECHECK_CHANNEL])(chan, 1);
    } else if (old_mode_pls_prot != chan->mode_pls_prot ||
	       old_mode_mns_prot != chan->mode_mns_prot)
      if ((me = module_find("irc", 1, 2)))
	(me->funcs[IRC_RECHECK_CHANNEL_MODES])(chan);
  }
  if (x > 0)
    return TCL_ERROR;
  return TCL_OK;
}
示例#20
0
static void remote_tell_who(int idx, char *nick, int chan)
{
  int i = 10, k, l, ok = 0;
  char s[1024], *realnick;
  struct chanset_t *c;

  realnick = strchr(nick, ':');
  if (realnick)
    realnick++;
  else
    realnick = nick;
  putlog(LOG_BOTS, "*", "#%s# who", realnick);
  strcpy(s, "Channels: ");
  for (c = chanset; c; c = c->next)
    if (!channel_secret(c) && !channel_inactive(c)) {
      l = strlen(c->dname);
      if (i + l < 1021) {
        if (i > 10)
          sprintf(s, "%s, %s", s, c->dname);
        else {
          strcpy(s, c->dname);
          i += (l + 2);
        }
      }
    }
  if (i > 10) {
    botnet_send_priv(idx, botnetnick, nick, NULL, "%s (%s)", s, ver);
  } else
    botnet_send_priv(idx, botnetnick, nick, NULL, "%s (%s)", BOT_NOCHANNELS,
                     ver);
  if (admin[0])
    botnet_send_priv(idx, botnetnick, nick, NULL, "Admin: %s", admin);
  if (chan == 0)
    botnet_send_priv(idx, botnetnick, nick, NULL, "%s (* = owner, + = master,"
                     " %% = botmaster, @ = op, ^ = halfop)", BOT_PARTYMEMBS);
  else {
    simple_sprintf(s, "assoc %d", chan);
    if ((Tcl_Eval(interp, s) != TCL_OK) || !interp->result[0])
      botnet_send_priv(idx, botnetnick, nick, NULL, "%s %s%d: (* = owner, + ="
                       " master, %% = botmaster, @ = op, ^ = halfop)\n",
                       BOT_PEOPLEONCHAN, (chan < GLOBAL_CHANS) ? "" : "*",
                       chan % GLOBAL_CHANS);
    else
      botnet_send_priv(idx, botnetnick, nick, NULL, "%s '%s' (%s%d): (* = "
                       "owner, + = master, %% = botmaster, @ = op, ^ = halfop)\n",
                       BOT_PEOPLEONCHAN, interp->result, (chan < GLOBAL_CHANS) ?
                       "" : "*", chan % GLOBAL_CHANS);
  }
  for (i = 0; i < dcc_total; i++)
    if (dcc[i].type->flags & DCT_REMOTEWHO)
      if (dcc[i].u.chat->channel == chan) {
        k = sprintf(s, "  %c%-15s %s", (geticon(i) == '-' ? ' ' : geticon(i)),
                    dcc[i].nick, dcc[i].host);
        if (now - dcc[i].timeval > 300) {
          unsigned long days, hrs, mins;

          days = (now - dcc[i].timeval) / 86400;
          hrs = ((now - dcc[i].timeval) - (days * 86400)) / 3600;
          mins = ((now - dcc[i].timeval) - (hrs * 3600)) / 60;
          if (days > 0)
            sprintf(s + k, " (%s %lud%luh)", MISC_IDLE, days, hrs);
          else if (hrs > 0)
            sprintf(s + k, " (%s %luh%lum)", MISC_IDLE, hrs, mins);
          else
            sprintf(s + k, " (%s %lum)", MISC_IDLE, mins);
        }
        botnet_send_priv(idx, botnetnick, nick, NULL, "%s", s);
        if (dcc[i].u.chat->away != NULL)
          botnet_send_priv(idx, botnetnick, nick, NULL, "      %s: %s",
                           MISC_AWAY, dcc[i].u.chat->away);
      }
  for (i = 0; i < dcc_total; i++)
    if (dcc[i].type == &DCC_BOT) {
      if (!ok) {
        ok = 1;
        botnet_send_priv(idx, botnetnick, nick, NULL, "%s:", BOT_BOTSCONNECTED);
      }
      sprintf(s, "  %s%c%-15s %s",
              dcc[i].status & BSTAT_CALLED ? "<-" : "->",
              dcc[i].status & BSTAT_SHARE ? '+' : ' ',
              dcc[i].nick, dcc[i].u.bot->version);
      botnet_send_priv(idx, botnetnick, nick, NULL, "%s", s);
    }
  ok = 0;
  for (i = 0; i < dcc_total; i++)
    if (dcc[i].type->flags & DCT_REMOTEWHO)
      if (dcc[i].u.chat->channel != chan) {
        if (!ok) {
          ok = 1;
          botnet_send_priv(idx, botnetnick, nick, NULL, "%s:", BOT_OTHERPEOPLE);
        }
        l = sprintf(s, "  %c%-15s %s", (geticon(i) == '-' ? ' ' : geticon(i)),
                    dcc[i].nick, dcc[i].host);
        if (now - dcc[i].timeval > 300) {
          k = (now - dcc[i].timeval) / 60;
          if (k < 60)
            sprintf(s + l, " (%s %dm)", MISC_IDLE, k);
          else
            sprintf(s + l, " (%s %dh%dm)", MISC_IDLE, k / 60, k % 60);
        }
        botnet_send_priv(idx, botnetnick, nick, NULL, "%s", s);
        if (dcc[i].u.chat->away != NULL)
          botnet_send_priv(idx, botnetnick, nick, NULL,
                           "      %s: %s", MISC_AWAY, dcc[i].u.chat->away);
      }
}
示例#21
0
static void channels_report(int idx, int details)
{
  int i;
  char s[1024], s1[100], s2[100];
  struct chanset_t *chan;
  struct flag_record fr = { FR_CHAN | FR_GLOBAL, 0, 0, 0, 0, 0 };

  for (chan = chanset; chan; chan = chan->next) {

    /* Get user's flags if output isn't going to stdout */
    if (idx != DP_STDOUT)
      get_user_flagrec(dcc[idx].user, &fr, chan->dname);

    /* Don't show channel information to someone who isn't a master */
    if ((idx != DP_STDOUT) && !glob_master(fr) && !chan_master(fr))
      continue;

    s[0] = 0;

    sprintf(s, "    %-20s: ", chan->dname);

    if (channel_inactive(chan))
      strcat(s, "(inactive)");
    else if (channel_pending(chan))
      strcat(s, "(pending)");
    else if (!channel_active(chan))
      strcat(s, "(not on channel)");
    else {

      s1[0] = 0;
      sprintf(s1, "%3d member%s", chan->channel.members,
              (chan->channel.members == 1) ? "" : "s");
      strcat(s, s1);

      s2[0] = 0;
      get_mode_protect(chan, s2);

      if (s2[0]) {
        s1[0] = 0;
        sprintf(s1, ", enforcing \"%s\"", s2);
        strcat(s, s1);
      }

      s2[0] = 0;

      if (channel_greet(chan))
        strcat(s2, "greet, ");
      if (channel_autoop(chan))
        strcat(s2, "auto-op, ");
      if (channel_bitch(chan))
        strcat(s2, "bitch, ");

      if (s2[0]) {
        s2[strlen(s2) - 2] = 0;

        s1[0] = 0;
        sprintf(s1, " (%s)", s2);
        strcat(s, s1);
      }

      /* If it's a !chan, we want to display it's unique name too <cybah> */
      if (chan->dname[0] == '!') {
        s1[0] = 0;
        sprintf(s1, ", unique name %s", chan->name);
        strcat(s, s1);
      }
    }

    dprintf(idx, "%s\n", s);

    if (details) {
      s[0] = 0;
      i = 0;

      if (channel_enforcebans(chan))
        i += my_strcpy(s + i, "enforcebans ");
      if (channel_dynamicbans(chan))
        i += my_strcpy(s + i, "dynamicbans ");
      if (!channel_nouserbans(chan))
        i += my_strcpy(s + i, "userbans ");
      if (channel_autoop(chan))
        i += my_strcpy(s + i, "autoop ");
      if (channel_bitch(chan))
        i += my_strcpy(s + i, "bitch ");
      if (channel_greet(chan))
        i += my_strcpy(s + i, "greet ");
      if (channel_protectops(chan))
        i += my_strcpy(s + i, "protectops ");
      if (channel_protecthalfops(chan))
        i += my_strcpy(s + i, "protecthalfops ");
      if (channel_protectfriends(chan))
        i += my_strcpy(s + i, "protectfriends ");
      if (channel_dontkickops(chan))
        i += my_strcpy(s + i, "dontkickops ");
      if (channel_logstatus(chan))
        i += my_strcpy(s + i, "statuslog ");
      if (channel_revenge(chan))
        i += my_strcpy(s + i, "revenge ");
      if (channel_revenge(chan))
        i += my_strcpy(s + i, "revengebot ");
      if (channel_secret(chan))
        i += my_strcpy(s + i, "secret ");
      if (channel_shared(chan))
        i += my_strcpy(s + i, "shared ");
      if (!channel_static(chan))
        i += my_strcpy(s + i, "dynamic ");
      if (channel_autovoice(chan))
        i += my_strcpy(s + i, "autovoice ");
      if (channel_autohalfop(chan))
        i += my_strcpy(s + i, "autohalfop ");
      if (channel_cycle(chan))
        i += my_strcpy(s + i, "cycle ");
      if (channel_seen(chan))
        i += my_strcpy(s + i, "seen ");
      if (channel_dynamicexempts(chan))
        i += my_strcpy(s + i, "dynamicexempts ");
      if (!channel_nouserexempts(chan))
        i += my_strcpy(s + i, "userexempts ");
      if (channel_dynamicinvites(chan))
        i += my_strcpy(s + i, "dynamicinvites ");
      if (!channel_nouserinvites(chan))
        i += my_strcpy(s + i, "userinvites ");
      if (channel_inactive(chan))
        i += my_strcpy(s + i, "inactive ");
      if (channel_nodesynch(chan))
        i += my_strcpy(s + i, "nodesynch ");

      dprintf(idx, "      Options: %s\n", s);

      if (chan->need_op[0])
        dprintf(idx, "      To get ops, I do: %s\n", chan->need_op);

      if (chan->need_invite[0])
        dprintf(idx, "      To get invited, I do: %s\n", chan->need_invite);

      if (chan->need_limit[0])
        dprintf(idx, "      To get the channel limit raised, I do: %s\n",
                chan->need_limit);

      if (chan->need_unban[0])
        dprintf(idx, "      To get unbanned, I do: %s\n", chan->need_unban);

      if (chan->need_key[0])
        dprintf(idx, "      To get the channel key, I do: %s\n",
                chan->need_key);

      if (chan->idle_kick)
        dprintf(idx, "      Kicking idle users after %d minute%s\n",
                chan->idle_kick, (chan->idle_kick != 1) ? "s" : "");

      if (chan->stopnethack_mode)
        dprintf(idx, "      stopnethack-mode: %d\n", chan->stopnethack_mode);

      if (chan->revenge_mode)
        dprintf(idx, "      revenge-mode: %d\n", chan->revenge_mode);

      dprintf(idx, "      ban-type: %d\n", chan->ban_type);
      dprintf(idx, "      Bans last %d minute%s.\n", chan->ban_time,
               (chan->ban_time == 1) ? "" : "s");
      dprintf(idx, "      Exemptions last %d minute%s.\n", chan->exempt_time,
               (chan->exempt_time == 1) ? "" : "s");
      dprintf(idx, "      Invitations last %d minute%s.\n", chan->invite_time,
               (chan->invite_time == 1) ? "" : "s");
    }
  }
}
示例#22
0
static void write_channels()
{
  FILE *f;
  char s[121], w[1024], w2[1024], name[163];
  char need1[242], need2[242], need3[242], need4[242], need5[242];
  struct chanset_t *chan;

  Context;
  if (!chanfile[0])
    return;
  sprintf(s, "%s~new", chanfile);
  f = fopen(s, "w");
  chmod(s, 0600);
  if (f == NULL) {
    putlog(LOG_MISC, "*", "ERROR writing channel file.");
    return;
  }
  if (!quiet_save)
    putlog(LOG_MISC, "*", "Writing channel file ...");
  fprintf(f, "#Dynamic Channel File for %s (%s) -- written %s\n",
	  origbotname, ver, ctime(&now));
  for (chan = chanset; chan; chan = chan->next) {
    convert_element(chan->name, name);
    get_mode_protect(chan, w);
    convert_element(w, w2);
    convert_element(chan->need_op, need1);
    convert_element(chan->need_invite, need2);
    convert_element(chan->need_key, need3);
    convert_element(chan->need_unban, need4);
    convert_element(chan->need_limit, need5);
    fprintf(f, "channel %s %s%schanmode %s idle-kick %d \
need-op %s need-invite %s need-key %s need-unban %s need-limit %s \
flood-chan %d:%d flood-ctcp %d:%d flood-join %d:%d \
flood-kick %d:%d flood-deop %d:%d \
%cclearbans %cenforcebans %cdynamicbans %cuserbans %cautoop %cbitch \
%cgreet %cprotectops %cprotectfriends %cdontkickops %cwasoptest \
%cstatuslog %cstopnethack %crevenge %crevengebot %cautovoice %csecret \
%cshared %ccycle %cseen %cinactive %cdynamicexempts %cuserexempts \
%cdynamicinvites %cuserinvites%s\n",
	channel_static(chan) ? "set" : "add",
	name,
	channel_static(chan) ? " " : " { ",
	w2,
/* now bot write chanmode "" too,
 * so bot wont use default-chanmode instead of "" -- bugfix
 */
	chan->idle_kick, /* idle-kick 0 is same as dont-idle-kick (less code)*/
	need1, need2, need3, need4, need5,
/* yes we will write empty need-xxxx too, why not? (less code + lazyness) */
	chan->flood_pub_thr, chan->flood_pub_time,
        chan->flood_ctcp_thr, chan->flood_ctcp_time,
        chan->flood_join_thr, chan->flood_join_time,
        chan->flood_kick_thr, chan->flood_kick_time,
        chan->flood_deop_thr, chan->flood_deop_time,
	PLSMNS(channel_clearbans(chan)),
	PLSMNS(channel_enforcebans(chan)),
	PLSMNS(channel_dynamicbans(chan)),
	PLSMNS(!channel_nouserbans(chan)),
	PLSMNS(channel_autoop(chan)),
	PLSMNS(channel_bitch(chan)),
	PLSMNS(channel_greet(chan)),
	PLSMNS(channel_protectops(chan)),
        PLSMNS(channel_protectfriends(chan)),
	PLSMNS(channel_dontkickops(chan)),
	PLSMNS(channel_wasoptest(chan)),
	PLSMNS(channel_logstatus(chan)),
	PLSMNS(channel_stopnethack(chan)),
	PLSMNS(channel_revenge(chan)),
	PLSMNS(channel_revengebot(chan)),
	PLSMNS(channel_autovoice(chan)),
	PLSMNS(channel_secret(chan)),
	PLSMNS(channel_shared(chan)),
	PLSMNS(channel_cycle(chan)),
	PLSMNS(channel_seen(chan)),
	PLSMNS(channel_inactive(chan)),
        PLSMNS(channel_dynamicexempts(chan)),
        PLSMNS(!channel_nouserexempts(chan)),
 	PLSMNS(channel_dynamicinvites(chan)),
        PLSMNS(!channel_nouserinvites(chan)),
	channel_static(chan) ? "" : " }");
    if (fflush(f)) {
      putlog(LOG_MISC, "*", "ERROR writing channel file.");
      fclose(f);
      return;
    }
  }
  fclose(f);
  unlink(chanfile);
  movefile(s, chanfile);
}
示例#23
0
/* Create new channel and parse commands.
 */
static int tcl_channel_add(Tcl_Interp *irp, char *newname, char *options)
{
  struct chanset_t *chan;
  int items;
  int ret = TCL_OK;
  int join = 0;
  char **item;
  char buf[2048], buf2[256];

  if (!newname || !newname[0] || (strchr(CHANMETA, newname[0]) == NULL)) {
    if (irp)
      Tcl_AppendResult(irp, "invalid channel prefix", NULL);
    return TCL_ERROR;
  }

  if (strchr(newname, ',') != NULL) {
    if (irp)
      Tcl_AppendResult(irp, "invalid channel name", NULL);
     return TCL_ERROR;
   }

  convert_element(glob_chanmode, buf2);
  simple_sprintf(buf, "chanmode %s ", buf2);
  strlcat(buf, glob_chanset, sizeof buf);
  strlcat(buf, options, sizeof buf);

  if (Tcl_SplitList(NULL, buf, &items, &item) != TCL_OK)
    return TCL_ERROR;
  if ((chan = findchan_by_dname(newname))) {
    /* Already existing channel, maybe a reload of the channel file */
    chan->status &= ~CHAN_FLAGGED;	/* don't delete me! :) */
  } else {
    chan = calloc(1, sizeof(struct chanset_t));
    chan->limit_prot = 0;
    chan->limit = 0;

    chan->ban_time = global_ban_time;
    chan->exempt_time = global_exempt_time;
    chan->invite_time = global_invite_time;
    chan->aop_min = global_aop_min;
    chan->aop_max = global_aop_max;

    /* We _only_ put the dname (display name) in here so as not to confuse
     * any code later on. chan->name gets updated with the channel name as
     * the server knows it, when we join the channel. <cybah>
     */
    strlcpy(chan->dname, newname, sizeof chan->dname);

    /* Initialize chan->channel info */
    init_channel(chan, 0);
    list_append((struct list_type **) &chanset, (struct list_type *) chan);
    join = 1;
  }
  if (setstatic)
    chan->status |= CHAN_STATIC;
  /* If chan_hack is set, we're loading the userfile. Ignore errors while
   * reading userfile and just return TCL_OK. This is for compatability
   * if a user goes back to an eggdrop that no-longer supports certain
   * (channel) options.
   */
  if ((tcl_channel_modify(irp, chan, items, item) != TCL_OK) && !chan_hack) {
    ret = TCL_ERROR;
  }
  Tcl_Free((char *) item);
  if (join && !channel_inactive(chan) && module_find("irc", 0, 0))
    dprintf(DP_SERVER, "JOIN %s %s\n", chan->dname, chan->key_prot);
  return ret;
}
示例#24
0
/*
 * Note:
 *  - We write chanmode "" too, so that the bot won't use default-chanmode
 *    instead of ""
 *  - We will write empty need-xxxx too, why not? (less code + lazyness)
 */
static void write_channels()
{
  FILE *f;
  char s[121], w[1024], w2[1024], name[163];
  char need1[242], need2[242], need3[242], need4[242], need5[242];
  struct chanset_t *chan;
  struct udef_struct *ul;

  Context;
  if (!chanfile[0])
    return;
  sprintf(s, "%s~new", chanfile);
  f = fopen(s, "w");
  chmod(s, userfile_perm);
  if (f == NULL) {
    putlog(LOG_MISC, "*", "ERROR writing channel file.");
    return;
  }
  if (!quiet_save)
    putlog(LOG_MISC, "*", "Writing channel file ...");
  fprintf(f, "#Dynamic Channel File for %s (%s) -- written %s\n",
	  origbotname, ver, ctime(&now));
  for (chan = chanset; chan; chan = chan->next) {
    convert_element(chan->dname, name);
    get_mode_protect(chan, w);
    convert_element(w, w2);
    convert_element(chan->need_op, need1);
    convert_element(chan->need_invite, need2);
    convert_element(chan->need_key, need3);
    convert_element(chan->need_unban, need4);
    convert_element(chan->need_limit, need5);
    fprintf(f, "channel %s %s%schanmode %s idle-kick %d stopnethack-mode %d \
need-op %s need-invite %s need-key %s need-unban %s need-limit %s \
flood-chan %d:%d flood-ctcp %d:%d flood-join %d:%d \
flood-kick %d:%d flood-deop %d:%d flood-nick %d:%d \
%cclearbans %cenforcebans %cdynamicbans %cuserbans %cautoop %cbitch \
%cgreet %cprotectops %cprotectfriends %cdontkickops \
%cstatuslog %crevenge %crevengebot %cautovoice %csecret \
%cshared %ccycle %cseen %cinactive %cdynamicexempts %cuserexempts \
%cdynamicinvites %cuserinvites %cnodesynch ",
	channel_static(chan) ? "set" : "add",
	name,
	channel_static(chan) ? " " : " { ",
	w2,
	chan->idle_kick, /* idle-kick 0 is same as dont-idle-kick (less code)*/
	chan->stopnethack_mode,
	need1, need2, need3, need4, need5,
	chan->flood_pub_thr, chan->flood_pub_time,
        chan->flood_ctcp_thr, chan->flood_ctcp_time,
        chan->flood_join_thr, chan->flood_join_time,
        chan->flood_kick_thr, chan->flood_kick_time,
        chan->flood_deop_thr, chan->flood_deop_time,
	chan->flood_nick_thr, chan->flood_nick_time,
	PLSMNS(channel_clearbans(chan)),
	PLSMNS(channel_enforcebans(chan)),
	PLSMNS(channel_dynamicbans(chan)),
	PLSMNS(!channel_nouserbans(chan)),
	PLSMNS(channel_autoop(chan)),
	PLSMNS(channel_bitch(chan)),
	PLSMNS(channel_greet(chan)),
	PLSMNS(channel_protectops(chan)),
        PLSMNS(channel_protectfriends(chan)),
	PLSMNS(channel_dontkickops(chan)),
	PLSMNS(channel_logstatus(chan)),
	PLSMNS(channel_revenge(chan)),
	PLSMNS(channel_revengebot(chan)),
	PLSMNS(channel_autovoice(chan)),
	PLSMNS(channel_secret(chan)),
	PLSMNS(channel_shared(chan)),
	PLSMNS(channel_cycle(chan)),
	PLSMNS(channel_seen(chan)),
	PLSMNS(channel_inactive(chan)),
        PLSMNS(channel_dynamicexempts(chan)),
        PLSMNS(!channel_nouserexempts(chan)),
 	PLSMNS(channel_dynamicinvites(chan)),
        PLSMNS(!channel_nouserinvites(chan)),
	PLSMNS(channel_nodesynch(chan)));
    for (ul = udef; ul; ul = ul->next) {
      if (ul->defined && ul->name) {
	if (ul->type == UDEF_FLAG)
	  fprintf(f, "%c%s%s ", getudef(ul->values, chan->dname) ? '+' : '-',
		  "udef-flag-", ul->name);
	else if (ul->type == UDEF_INT)
	  fprintf(f, "%s%s %d ", "udef-int-", ul->name, getudef(ul->values,
		  chan->dname));
	else
	  debug1("UDEF-ERROR: unknown type %d", ul->type);
      }
    }
    fprintf(f, "%s\n", channel_static(chan) ? "" : "}");
    if (fflush(f)) {
      putlog(LOG_MISC, "*", "ERROR writing channel file.");
      fclose(f);
      return;
    }
  }
  fclose(f);
  unlink(chanfile);
  movefile(s, chanfile);
}